CN-1733 fix: Source管理页面开发
This commit is contained in:
@@ -53,7 +53,7 @@
|
|||||||
border: 1px solid var(--el-border-color-light);
|
border: 1px solid var(--el-border-color-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-tool-search {
|
.top-tool-search, .top-tool-search1 {
|
||||||
.top-tool-search__display {
|
.top-tool-search__display {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@@ -83,6 +83,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-tool-search1 {
|
||||||
|
width: 100%;
|
||||||
|
.el-input {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.top-tool-right {
|
.top-tool-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,3 +89,6 @@
|
|||||||
@import "./components/common/simple-loading";
|
@import "./components/common/simple-loading";
|
||||||
|
|
||||||
@import "views/location/location";
|
@import "views/location/location";
|
||||||
|
|
||||||
|
@import "views/setting/sourcesForm";
|
||||||
|
@import "views/setting/entitySettingForm";
|
||||||
|
|||||||
306
src/assets/css/components/views/setting/entitySettingForm.scss
Normal file
306
src/assets/css/components/views/setting/entitySettingForm.scss
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
$text-color-primary: var(--el-text-color-primary);
|
||||||
|
$bg-color-page: var(--el-bg-color-page);
|
||||||
|
$border-color-light: var(--el-border-color-light);
|
||||||
|
|
||||||
|
// es为entity setting简写
|
||||||
|
.es-form {
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select__wrapper {
|
||||||
|
min-height: 24px;
|
||||||
|
//padding: 2px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.es-form-header {
|
||||||
|
font-size: 24px;
|
||||||
|
color: $text-color-primary;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.es-form-content {
|
||||||
|
height: calc(100% - 92px);
|
||||||
|
overflow: scroll;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
.es-form-collapse {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 1200px;
|
||||||
|
border: 1px $border-color-light solid;
|
||||||
|
|
||||||
|
.rule-definition {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-collapse-item__header {
|
||||||
|
width: 1200px !important;
|
||||||
|
height: 56px !important;
|
||||||
|
background: var(--el-fill-color-blank) !important;
|
||||||
|
border-left: 1px solid $bg-color-page;
|
||||||
|
border-right: 1px solid $border-color-light;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: inherit;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 20px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-collapse-item__wrap {
|
||||||
|
//border: 1px solid $bg-color-page;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-collapse-header {
|
||||||
|
margin-left: 26px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.form-collapse-header-no, .form-collapse-header-no-active {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
transition: 0.5s all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-collapse-header-no {
|
||||||
|
background: $border-color-light;
|
||||||
|
color: $text-color-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-collapse-header-no-active {
|
||||||
|
background: var(--el-color-business);
|
||||||
|
color: var(--el-color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-collapse-header-title {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $text-color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-collapse-content {
|
||||||
|
padding: 0 20px 0 46px;
|
||||||
|
|
||||||
|
.form-setting__block {
|
||||||
|
width: 620px;
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
|
.form-setting__select {
|
||||||
|
width: 620px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content__title {
|
||||||
|
line-height: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content__block {
|
||||||
|
width: 620px;
|
||||||
|
padding: 15px 12px 5px 12px;
|
||||||
|
border: 1px $border-color-light solid;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.block-header {
|
||||||
|
width: 596px;
|
||||||
|
line-height: 12px;
|
||||||
|
display: flex;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
div:nth-child(1) {
|
||||||
|
width: 288px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-body {
|
||||||
|
width: 596px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-body__select {
|
||||||
|
width: 260px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-body-equal {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapping-item-add {
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 24px;
|
||||||
|
margin: 0 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapping-item-close {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: var(--el-color-error);
|
||||||
|
font-size: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.relation-field__select {
|
||||||
|
width: 112px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.relation-field__select-disabled {
|
||||||
|
width: 112px;
|
||||||
|
|
||||||
|
.el-select__selected-item {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select__suffix {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.relation-type__select {
|
||||||
|
width: 312px;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-setting-type {
|
||||||
|
width: 620px;
|
||||||
|
border: 1px solid $border-color-light;
|
||||||
|
padding: 15px 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.setting-type__text {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__footer {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.addFieldBtn {
|
||||||
|
height: 24px;
|
||||||
|
min-height: 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
width: 620px;
|
||||||
|
background: var(--el-color-business-light-9);
|
||||||
|
border: 1px $border-color-light solid;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(51, 51, 51, 0.02);
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.add-field-btn {
|
||||||
|
color: var(--el-text-color-regular) !important;
|
||||||
|
font-size: 9px !important;
|
||||||
|
margin: 0 8px 2px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
i {
|
||||||
|
color: var(--el-color-business) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-20 {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-collapse-item__content {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
.es-form-trigger {
|
||||||
|
|
||||||
|
.el-input__wrapper, .el-select__wrapper {
|
||||||
|
width: 112px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
padding: 0 15px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input--small, .el-input--small .el-input__inner {
|
||||||
|
border-radius: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch__block {
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
.block-title {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
color: $text-color-primary;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.es-form__footer {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
box-shadow: 0 -1px 4px 0 rgba(0, 0, 0, 0.10);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.el-form-item__label {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag__btn {
|
||||||
|
margin: 0 10px;
|
||||||
|
height: 30px;
|
||||||
|
min-width: 74px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-overlay-message-box, .el-message-box {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-overlay-message-box {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-message-box .el-overlay-message-box {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
189
src/assets/css/components/views/setting/sourcesForm.scss
Normal file
189
src/assets/css/components/views/setting/sourcesForm.scss
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
$color-text-primary: var(--el-text-color-primary);
|
||||||
|
|
||||||
|
.sources-form {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select__wrapper {
|
||||||
|
min-height: 24px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__wrapper {
|
||||||
|
padding: 1px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sources-form__header {
|
||||||
|
padding: 30px 0 30px 20px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: $color-text-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sources-form__body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: calc(100% - 147px);
|
||||||
|
padding-left: 40px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.el-form-item__label {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form__body__label {
|
||||||
|
font-family: NotoSansHans-Medium;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-fields__block {
|
||||||
|
padding: 10px;
|
||||||
|
width: 620px;
|
||||||
|
border: 1px solid var(--el-border-color-light);
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.block__header {
|
||||||
|
display: flex;
|
||||||
|
font-family: NotoSansHans-Medium;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.block__header-name {
|
||||||
|
width: 262px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__header-type {
|
||||||
|
width: 162px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.block__body-container {
|
||||||
|
//height: 24px;
|
||||||
|
//line-height: 24px;
|
||||||
|
display: flex;
|
||||||
|
//margin-bottom: 8px;
|
||||||
|
|
||||||
|
.block__body-name, .block__body-type, .block__body-default, .block__body-function, .block__body-field, .block__body-field-name {
|
||||||
|
width: 262px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__body-type {
|
||||||
|
width: 162px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__body-default {
|
||||||
|
width: 132px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__body-function {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__body-field {
|
||||||
|
width: 124px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__body-field-name {
|
||||||
|
width: 138px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-btn {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-size: 9px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
.el-form-item__content {
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.block__footer {
|
||||||
|
margin-top: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.addFieldBtn {
|
||||||
|
height: 24px;
|
||||||
|
min-height: 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $color-text-primary;
|
||||||
|
font-weight: 500;
|
||||||
|
width: 598px;
|
||||||
|
background: var(--el-color-business-light-9);
|
||||||
|
border: 1px var(--el-border-color-light) solid;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(51, 51, 51, 0.02);
|
||||||
|
border-radius: 2px;
|
||||||
|
font-family: NotoSansHans-Medium !important;
|
||||||
|
|
||||||
|
.add-field-btn {
|
||||||
|
color: var(--el-text-color-regular) !important;
|
||||||
|
font-size: 9px !important;
|
||||||
|
margin: 0 8px 2px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
i {
|
||||||
|
color: var(--el-color-business) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-family: NotoSansHans-Medium !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-description {
|
||||||
|
width: 620px;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sources-form__footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 60px;
|
||||||
|
margin-top: 3px;
|
||||||
|
box-shadow: 0 -1px 4px 0 rgba(0, 0, 0, 0.10);
|
||||||
|
|
||||||
|
.el-form-item__label {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag__btn {
|
||||||
|
margin: 0 10px;
|
||||||
|
height: 30px;
|
||||||
|
min-width: 74px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -199,6 +199,114 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sources-dialog {
|
||||||
|
.el-dialog__header {
|
||||||
|
background-color: var(--cn-bg-color-lighter);
|
||||||
|
box-shadow: 0 1px 0 0 rgba(53,54,54,0.08);
|
||||||
|
padding: 0;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
|
||||||
|
.sources-dialog__header {
|
||||||
|
font-family: NotoSansSChineseRegular;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
letter-spacing: 0;
|
||||||
|
font-weight: 400;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__headerbtn {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
|
||||||
|
.el-dialog__close {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.sources-dialog__body {
|
||||||
|
padding: 20px 30px 10px 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.dialog__body-upload {
|
||||||
|
width: 420px;
|
||||||
|
height: 124px;
|
||||||
|
background: var(--cn-bg-color-lighter);
|
||||||
|
border: 1px solid var(--el-border-color-light);
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.el-upload-dragger {
|
||||||
|
height: 124px;
|
||||||
|
border: 1px solid var(--el-border-color-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-upload__text {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog__body-tip {
|
||||||
|
width: 420px;
|
||||||
|
height: 142px;
|
||||||
|
background: var(--el-color-business-light-9);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.tip__text {
|
||||||
|
font-family: NotoSansSChineseRegular;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
letter-spacing: 0;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__footer {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.sources-dialog__footer {
|
||||||
|
height: 52px;
|
||||||
|
line-height: 52px;
|
||||||
|
border-top: 1px solid var(--el-border-color-light);
|
||||||
|
|
||||||
|
.cancel-btn {
|
||||||
|
width: 80px;
|
||||||
|
height: 28px;
|
||||||
|
margin-right: 20px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
background: var(--el-fill-color-light);
|
||||||
|
border: 1px solid var(--el-border-color-dark);
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-btn {
|
||||||
|
width: 80px;
|
||||||
|
height: 28px;
|
||||||
|
margin-right: 20px;
|
||||||
|
color: var(--el-color-white);
|
||||||
|
margin-left: 0 !important;
|
||||||
|
background-color: var(--el-color-business);
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.type-tag {
|
.type-tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|||||||
@@ -138,6 +138,7 @@
|
|||||||
class="cn-menu"
|
class="cn-menu"
|
||||||
:with-header="false"
|
:with-header="false"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
|
@close="closeDrawer"
|
||||||
>
|
>
|
||||||
<div class="cn-menu__left" v-if="otherMenu">
|
<div class="cn-menu__left" v-if="otherMenu">
|
||||||
<div class="left-menu" v-for="menu in otherMenu" :key="menu.id" @click="jumpOther(menu.route,'','',0)">
|
<div class="left-menu" v-for="menu in otherMenu" :key="menu.id" @click="jumpOther(menu.route,'','',0)">
|
||||||
@@ -146,7 +147,7 @@
|
|||||||
<i class="cn-icon cn-icon-right"></i>
|
<i class="cn-icon cn-icon-right"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cn-menu__middle" >
|
<div class="cn-menu__middle" v-if="!isShowSetting">
|
||||||
<div class="middle-menus middle-menus--network-analytics">
|
<div class="middle-menus middle-menus--network-analytics">
|
||||||
<div class="middle-menus__header">{{ $t('overall.networkAnalytics') }}</div>
|
<div class="middle-menus__header">{{ $t('overall.networkAnalytics') }}</div>
|
||||||
<div class="middle-menus__body" v-if="networkAnalyticsMenu && networkAnalyticsMenu.children">
|
<div class="middle-menus__body" v-if="networkAnalyticsMenu && networkAnalyticsMenu.children">
|
||||||
@@ -186,6 +187,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cn-menu__middle" v-if="isShowSetting">
|
||||||
|
<div class="middle-menus middle-menus--network-analytics">
|
||||||
|
<div class="middle-menus__header">{{ $t('overall.setting') }}</div>
|
||||||
|
<div class="middle-menus__body" v-if="settingMenu && settingMenu.children">
|
||||||
|
<div style="width: 260px;">
|
||||||
|
<template v-for="(menu, index) in settingMenu.children" :key="menu.name">
|
||||||
|
<div class="middle-menu" v-if="index < 5" @click="jump(menu.route,'','',2)">
|
||||||
|
{{ $t(menu.i18n || menu.name) }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<template v-for="(menu, index) in settingMenu.children" :key="menu.name">
|
||||||
|
<div class="middle-menu" v-if="index >= 5 && index < 10" @click="jump(menu.route,'','',2)">
|
||||||
|
{{ $t(menu.i18n || menu.name) }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
<!-- 改密码 -->
|
<!-- 改密码 -->
|
||||||
@@ -336,16 +358,21 @@ export default {
|
|||||||
wholeScreenRouterMapping,
|
wholeScreenRouterMapping,
|
||||||
logo: 'images/logo-header.svg',
|
logo: 'images/logo-header.svg',
|
||||||
ZH,
|
ZH,
|
||||||
EN
|
EN,
|
||||||
|
isShowSetting: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
networkAnalyticsMenu () {
|
networkAnalyticsMenu () {
|
||||||
|
console.log('-------', this.$store.getters.menuList)
|
||||||
return this.$store.getters.menuList.find(menu => menu.code === 'networkAnalytics')
|
return this.$store.getters.menuList.find(menu => menu.code === 'networkAnalytics')
|
||||||
},
|
},
|
||||||
locationIntelligenceMenu () {
|
locationIntelligenceMenu () {
|
||||||
return this.$store.getters.menuList.find(menu => menu.code === 'locationIntelligence')
|
return this.$store.getters.menuList.find(menu => menu.code === 'locationIntelligence')
|
||||||
},
|
},
|
||||||
|
settingMenu () {
|
||||||
|
return this.$store.getters.menuList.find(menu => menu.code === 'setting')
|
||||||
|
},
|
||||||
otherMenu () {
|
otherMenu () {
|
||||||
return this.$store.getters.menuList.filter(menu => ['locationIntelligence', 'networkAnalytics', 'I18N', 'entityDetail', 'entityGraph', 'detectionPolicy'].indexOf(menu.code) === -1)
|
return this.$store.getters.menuList.filter(menu => ['locationIntelligence', 'networkAnalytics', 'I18N', 'entityDetail', 'entityGraph', 'detectionPolicy'].indexOf(menu.code) === -1)
|
||||||
|
|
||||||
@@ -755,6 +782,11 @@ export default {
|
|||||||
},
|
},
|
||||||
// 仅处理除panel外的相关路径的导航
|
// 仅处理除panel外的相关路径的导航
|
||||||
async jumpOther (route, index) {
|
async jumpOther (route, index) {
|
||||||
|
console.log('route', route, index)
|
||||||
|
if (route === '/setting') {
|
||||||
|
this.isShowSetting = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
route = route.replace('redirect:', '')
|
route = route.replace('redirect:', '')
|
||||||
this.showMenu = false
|
this.showMenu = false
|
||||||
if (route === this.route && index > 0) { // 当前只有一级菜单时,点击不进行刷新,重新跳转
|
if (route === this.route && index > 0) { // 当前只有一级菜单时,点击不进行刷新,重新跳转
|
||||||
@@ -893,6 +925,12 @@ export default {
|
|||||||
if (obj.scrollTop + obj.clientHeight === obj.scrollHeight) {
|
if (obj.scrollTop + obj.clientHeight === obj.scrollHeight) {
|
||||||
this.initDropdownList()
|
this.initDropdownList()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
closeDrawer () {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
this.isShowSetting = false
|
||||||
|
clearTimeout(timer)
|
||||||
|
}, 400)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<!-- 顶部工具栏 -->
|
<!-- 顶部工具栏 -->
|
||||||
<div class="top-tools">
|
<div class="top-tools">
|
||||||
<div class="top-tool-left">
|
<div class="top-tool-left" :style="{width: showInputWidth ? showInputWidth : 'auto'}">
|
||||||
<slot name="top-tool-left"></slot>
|
<slot name="top-tool-left"></slot>
|
||||||
<div v-if="showLayout.indexOf('search') > -1" class="top-tool-search margin-r-20">
|
<div v-if="showLayout.indexOf('search') > -1" :class="showInputWidth ? 'top-tool-search1' : 'top-tool-search margin-r-20'">
|
||||||
<div class="top-tool-search__display">
|
<div class="top-tool-search__display">
|
||||||
<el-input v-model="keyWord" @keyup.enter="onSearch"></el-input>
|
<el-input v-model="keyWord" @keyup.enter="onSearch"></el-input>
|
||||||
<button class="business-button business-button--light top-tool-btn--search" @click="onSearch">
|
<button class="business-button business-button--light top-tool-btn--search" @click="onSearch">
|
||||||
@@ -72,6 +72,10 @@ export default {
|
|||||||
layout: {
|
layout: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default () { return [] }
|
default () { return [] }
|
||||||
|
},
|
||||||
|
inputWidth: {
|
||||||
|
type: String,
|
||||||
|
default () { return '' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -82,6 +86,7 @@ export default {
|
|||||||
showCustomTableTitle: false // 自定义列弹框是否显示
|
showCustomTableTitle: false // 自定义列弹框是否显示
|
||||||
},
|
},
|
||||||
showLayout: [],
|
showLayout: [],
|
||||||
|
showInputWidth: '',
|
||||||
loading: true
|
loading: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -103,6 +108,13 @@ export default {
|
|||||||
handler (n) {
|
handler (n) {
|
||||||
this.showLayout = [...n]
|
this.showLayout = [...n]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
inputWidth: {
|
||||||
|
immediate: true,
|
||||||
|
deep: true,
|
||||||
|
handler (n) {
|
||||||
|
this.showInputWidth = n
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
124
src/components/table/setting/ProfilesTable.vue
Normal file
124
src/components/table/setting/ProfilesTable.vue
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<template>
|
||||||
|
<el-table
|
||||||
|
id="userTable"
|
||||||
|
ref="dataTable"
|
||||||
|
:data="tableData"
|
||||||
|
tooltip-effect="light"
|
||||||
|
empty-text=" "
|
||||||
|
@header-dragend="dragend"
|
||||||
|
@sort-change="tableDataSort"
|
||||||
|
@selection-change="selectionChange"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
:resizable="false"
|
||||||
|
align="center"
|
||||||
|
type="selection"
|
||||||
|
:selectable="checkSelectable"
|
||||||
|
width="55">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-for="(item, index) in customTableTitles"
|
||||||
|
:key="item.prop+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">
|
||||||
|
<template v-if="item.prop === 'createdTime' || item.prop === 'updateTime'">
|
||||||
|
<template v-if="scope.row[item.prop]">
|
||||||
|
{{ dateFormatByAppearance(scope.row[item.prop]) || '-' }}
|
||||||
|
</template>
|
||||||
|
<template v-else><span>-</span></template>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ scope.row[item.prop] || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<template v-slot:empty>
|
||||||
|
<div class="table-no-data" v-if="isNoData">
|
||||||
|
<div class="table-no-data__title">{{ $t('npm.noData') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import table from '@/mixins/table'
|
||||||
|
import { dateFormatByAppearance } from '@/utils/date-util'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SourcesTable',
|
||||||
|
props: {
|
||||||
|
isNoData: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [table],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
tableTitle: [ // 原始table列
|
||||||
|
{
|
||||||
|
label: 'ID',
|
||||||
|
prop: 'id',
|
||||||
|
show: true,
|
||||||
|
minWidth: 50,
|
||||||
|
sortable: 'custom'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('setting.source'),
|
||||||
|
prop: 'source',
|
||||||
|
show: true,
|
||||||
|
sortable: 'custom',
|
||||||
|
minWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('setting.entityTypes'),
|
||||||
|
prop: 'entityTypes',
|
||||||
|
show: true,
|
||||||
|
minWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('setting.relationTypes'),
|
||||||
|
prop: 'relationTypes',
|
||||||
|
show: true,
|
||||||
|
minWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('config.user.createTime'),
|
||||||
|
prop: 'createTime',
|
||||||
|
show: true,
|
||||||
|
minWidth: 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('overall.updateTime'),
|
||||||
|
prop: 'updateTime',
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
uploadParams () {
|
||||||
|
return {
|
||||||
|
indicatorType: 'IP'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
dateFormatByAppearance,
|
||||||
|
// 禁止勾选buildIn为1的项,即禁止修改、删除admin的账号
|
||||||
|
checkSelectable (row) {
|
||||||
|
return row.buildIn !== 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
308
src/components/table/setting/SourcesTable.vue
Normal file
308
src/components/table/setting/SourcesTable.vue
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
<template>
|
||||||
|
<el-table
|
||||||
|
id="userTable"
|
||||||
|
ref="dataTable"
|
||||||
|
:data="tableData"
|
||||||
|
tooltip-effect="light"
|
||||||
|
empty-text=" "
|
||||||
|
@header-dragend="dragend"
|
||||||
|
@sort-change="tableDataSort"
|
||||||
|
@selection-change="selectionChange"
|
||||||
|
>
|
||||||
|
<el-table-column
|
||||||
|
:resizable="false"
|
||||||
|
align="center"
|
||||||
|
type="selection"
|
||||||
|
:selectable="checkSelectable"
|
||||||
|
width="55">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
v-for="(item, index) in customTableTitles"
|
||||||
|
:key="item.prop+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">
|
||||||
|
<template v-if="item.prop === 'createdTime'">
|
||||||
|
<template v-if="scope.row[item.prop]">
|
||||||
|
{{ dateFormatByAppearance(scope.row[item.prop]) || '-' }}
|
||||||
|
</template>
|
||||||
|
<template v-else><span>-</span></template>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="item.prop === 'option'">
|
||||||
|
<i class="cn-icon cn-icon-upload" style="cursor: pointer;" @click="dialogVisible=true"></i>
|
||||||
|
</template>
|
||||||
|
<span v-else>{{ scope.row[item.prop] || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<template v-slot:empty>
|
||||||
|
<div class="table-no-data" v-if="isNoData">
|
||||||
|
<div class="table-no-data__title">{{ $t('npm.noData') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<el-dialog class="sources-dialog" v-model="dialogVisible" width="480">
|
||||||
|
<template #header>
|
||||||
|
<div class="sources-dialog__header">{{ $t('overall.upload') }}</div>
|
||||||
|
</template>
|
||||||
|
<div class="sources-dialog__body">
|
||||||
|
<div class="dialog__body-upload">
|
||||||
|
<!-- <loading :loading="uploadLoading"></loading>-->
|
||||||
|
<el-upload :action="uploadUrl"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:data="uploadParams"
|
||||||
|
:multiple="false"
|
||||||
|
:file-list="fileList"
|
||||||
|
:on-change="fileChange"
|
||||||
|
:on-success="uploadSuccess"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:on-progress="onUpload"
|
||||||
|
:on-error="uploadError"
|
||||||
|
:class="uploadErrorTip ? 'el-upload--error' : ''"
|
||||||
|
drag
|
||||||
|
:accept="fileTypeLimit"
|
||||||
|
ref="upload"
|
||||||
|
>
|
||||||
|
<i class="cn-icon cn-icon-upload2 upload-icon"></i>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
<div ref="uploadButton">{{ $t('sources.dragFile') }}</div>
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
<div class="dialog__body-tip">
|
||||||
|
<div class="tip__text"
|
||||||
|
v-for="(item, index) in tipsInfo[language]"
|
||||||
|
:key="item.value"
|
||||||
|
:style="{color: index===0 || index===3 ? 'var(--el-color-business)' : 'var(--el-text-color-regular)'}">
|
||||||
|
{{ item.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="sources-dialog__footer">
|
||||||
|
<button class="cancel-btn" @click="dialogVisible=false">{{ $t('overall.cancel') }}</button>
|
||||||
|
<button class="upload-btn">{{ $t('overall.upload') }}</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import table from '@/mixins/table'
|
||||||
|
import { dateFormatByAppearance } from '@/utils/date-util'
|
||||||
|
import { itemListHeight, storageKey, unitTypes, EN } from '@/utils/constants'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import unitConvert from '@/utils/unit-convert'
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SourcesTable',
|
||||||
|
props: {
|
||||||
|
isNoData: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [table],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
tableTitle: [ // 原始table列
|
||||||
|
{
|
||||||
|
label: 'ID',
|
||||||
|
prop: 'id',
|
||||||
|
show: true,
|
||||||
|
minWidth: 50,
|
||||||
|
sortable: 'custom'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('config.user.name'),
|
||||||
|
prop: 'name',
|
||||||
|
show: true,
|
||||||
|
sortable: 'custom',
|
||||||
|
minWidth: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('overall.remark'),
|
||||||
|
prop: 'description',
|
||||||
|
show: true,
|
||||||
|
minWidth: 350
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('config.user.createTime'),
|
||||||
|
prop: 'createdTime',
|
||||||
|
show: true,
|
||||||
|
minWidth: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('overall.option'),
|
||||||
|
prop: 'option',
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dialogVisible: false,
|
||||||
|
uploadUrl: api.setting.source.sourceUpload,
|
||||||
|
uploadHeaders: {
|
||||||
|
'Cn-Authorization': localStorage.getItem(storageKey.token)
|
||||||
|
},
|
||||||
|
fileList: [],
|
||||||
|
fileTypeLimit: '.csv',
|
||||||
|
language: localStorage.getItem(storageKey.language) || EN,
|
||||||
|
tipsInfo: {
|
||||||
|
en: [
|
||||||
|
{ value: 0, label: 'You can now integrate data to our platform using two methods:' },
|
||||||
|
{ value: 1, label: '1. File Upload: Access the upload feature on our website to submit your files directly.' },
|
||||||
|
{ value: 2, label: '2. Kafka Direct Transmission: Send your data to a specific Kafka topic on our servers, ensuring each message includes a header with the source_id.' },
|
||||||
|
{ value: 3, label: 'For Kafka server information, please contact your administrator.' }
|
||||||
|
],
|
||||||
|
zh: [
|
||||||
|
{ value: 0, label: '您现在可以使用两种方法将数据集成到我们的平台:' },
|
||||||
|
{ value: 1, label: '1. 文件上传:访问我们网站的上传功能直接提交您的文件。' },
|
||||||
|
{ value: 2, label: '2. Kafka 直接传输:将您的数据发送到我们服务器上的特定 Kafka 主题,确保每条消息都包含带有 source_id 的标头。' },
|
||||||
|
{ value: 3, label: '有关 Kafka 服务器的信息,请联系您的管理员。' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
uploadParams () {
|
||||||
|
return {
|
||||||
|
indicatorType: 'IP'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
dateFormatByAppearance,
|
||||||
|
// 禁止勾选buildIn为1的项,即禁止修改、删除admin的账号
|
||||||
|
checkSelectable (row) {
|
||||||
|
return row.buildIn !== 1
|
||||||
|
},
|
||||||
|
fileChange (files, fileList) {
|
||||||
|
if (this.fileList.length > 0 && this.fileList[0].status === 'success') {
|
||||||
|
this.fileListBack = this.fileList[0]
|
||||||
|
}
|
||||||
|
this.fileList = fileList.slice(-1)
|
||||||
|
},
|
||||||
|
uploadSuccess (response) {
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.uploaded = true
|
||||||
|
// 上传成功后去掉upload和preview的错误提示
|
||||||
|
this.uploadErrorTip = ''
|
||||||
|
this.previewErrorTip = ''
|
||||||
|
this.importedType = this.editObject.indicatorType
|
||||||
|
const originalImportedData = _.cloneDeep(response.data.list)
|
||||||
|
this.importedDataNoData = originalImportedData.length === 0
|
||||||
|
if (originalImportedData.length > 0) {
|
||||||
|
originalImportedData.forEach(data => {
|
||||||
|
if (data.isValid === 1) {
|
||||||
|
data.msg = this.$t('overall.success')
|
||||||
|
} else if (data.isValid === 0) {
|
||||||
|
if (data.errorAttribute === 'entityType') {
|
||||||
|
data.msg = this.$t('validate.wrongType')
|
||||||
|
} else if (data.errorAttribute === 'entityValue') {
|
||||||
|
data.msg = this.$t('validate.wrongFormat')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.originalImportInfo = {
|
||||||
|
total: originalImportedData.length,
|
||||||
|
succeeded: originalImportedData.filter(d => d.isValid === 1).length,
|
||||||
|
failed: originalImportedData.filter(d => d.isValid !== 1).length
|
||||||
|
}
|
||||||
|
this.isLoad = false
|
||||||
|
originalImportedData.sort((a, b) => b.isValid - a.isValid)
|
||||||
|
this.importedData = this.handleSpeticalTypeData(originalImportedData)
|
||||||
|
this.addItemList = _.cloneDeep(this.importedData).filter(item => { return item.isValid === 1 })
|
||||||
|
this.updateItemList = []
|
||||||
|
this.deleteItemIds = this.oldItemIds
|
||||||
|
|
||||||
|
this.handleShowImportedData()
|
||||||
|
this.addEditFlag = false
|
||||||
|
this.editTagErrorTip = ''
|
||||||
|
this.editIndex = -1
|
||||||
|
this.isPreviewChange = true
|
||||||
|
this.stepHeights[2] = itemListHeight.hasData
|
||||||
|
this.stepHeightConstant.third = itemListHeight.hasData
|
||||||
|
} else {
|
||||||
|
this.uploadLoading = false
|
||||||
|
this.$message.error(this.$t('tip.uploadFailed', { msg: response.message }))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeUpload (file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// 判断后缀,仅支持.csv
|
||||||
|
if (!_.endsWith(file.name, '.csv')) {
|
||||||
|
this.$message.error(this.$t('validate.fileTypeLimit', { types: this.fileTypeLimit }))
|
||||||
|
this.fileList = []
|
||||||
|
reject(new Error(this.$t('validate.fileTypeLimit', { types: this.fileTypeLimit })))
|
||||||
|
} else if (file.size > this.uploadFileSizeLimit) { // 判断文件大小
|
||||||
|
this.$message.error(this.$t('validate.fileSizeLimit', { size: unitConvert(this.uploadFileSizeLimit, unitTypes.byte).join('') }))
|
||||||
|
this.fileList = []
|
||||||
|
reject(new Error(this.$t('validate.fileSizeLimit', { size: unitConvert(this.uploadFileSizeLimit, unitTypes.byte).join('') })))
|
||||||
|
} else {
|
||||||
|
if (!this.isClick) {
|
||||||
|
if (this.importedData.length > 0) {
|
||||||
|
ElMessageBox.confirm(this.$t('tip.uploadFile'), {
|
||||||
|
confirmButtonText: this.$t('tip.confirm'),
|
||||||
|
cancelButtonText: this.$t('overall.cancel'),
|
||||||
|
message: this.$t('tip.uploadFileTips'),
|
||||||
|
title: this.$t('tip.uploadFile'),
|
||||||
|
// type: 'warning',
|
||||||
|
iconClass: 'width:0px;height:0px;',
|
||||||
|
customClass: 'del-model'
|
||||||
|
}).then(() => {
|
||||||
|
resolve()
|
||||||
|
}).catch(e => {
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onUpload () {
|
||||||
|
this.uploadLoading = true
|
||||||
|
this.typeSelectDisable = true
|
||||||
|
this.isClick = false
|
||||||
|
},
|
||||||
|
uploadError (error) {
|
||||||
|
let errorMsg
|
||||||
|
if (error.message) {
|
||||||
|
errorMsg = JSON.parse(error.message).message
|
||||||
|
} else {
|
||||||
|
errorMsg = 'error'
|
||||||
|
}
|
||||||
|
this.uploadLoading = false
|
||||||
|
this.$message.error(this.$t('tip.uploadFailed', { msg: errorMsg }))
|
||||||
|
},
|
||||||
|
downloadTemplate () {
|
||||||
|
window.open('/assets/tagTemplate.csv', '_blank')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
// 没上传过文件的提示
|
||||||
|
const uploadErrorTip = ref('')
|
||||||
|
|
||||||
|
return {
|
||||||
|
uploadErrorTip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -197,6 +197,16 @@ export function handleComponent (code) {
|
|||||||
case 'locationMap':
|
case 'locationMap':
|
||||||
case 'traceTracking':
|
case 'traceTracking':
|
||||||
return () => import('@/views/location/Index')
|
return () => import('@/views/location/Index')
|
||||||
|
case 'source':
|
||||||
|
return () => import('@/views/setting/sources/Sources')
|
||||||
|
case 'createSource':
|
||||||
|
case 'editSource':
|
||||||
|
return () => import('@/views/setting/sources/SourcesForm')
|
||||||
|
case 'entitySetting':
|
||||||
|
return () => import('@/views/setting/entitySetting/EntitySetting')
|
||||||
|
case 'createEntitySetting':
|
||||||
|
case 'editEntitySetting':
|
||||||
|
return () => import('@/views/setting/entitySetting/EntitySettingForm')
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,6 +386,15 @@ export const api = {
|
|||||||
tracking: apiVersion + '/locationIntelligence/trace/tracking',
|
tracking: apiVersion + '/locationIntelligence/trace/tracking',
|
||||||
follow: apiVersion + '/locationIntelligence/follow',
|
follow: apiVersion + '/locationIntelligence/follow',
|
||||||
geoLocation: apiVersion + 'locationIntelligence/geolocation'
|
geoLocation: apiVersion + 'locationIntelligence/geolocation'
|
||||||
|
},
|
||||||
|
setting: {
|
||||||
|
source: {
|
||||||
|
source: apiVersion + '/entity/sources', // get列表查询,delete删除,post新增,put修改
|
||||||
|
sourceUpload: apiVersion + 'entity/sources/upload' // 文件上传,post
|
||||||
|
},
|
||||||
|
profiles: {
|
||||||
|
profiles: apiVersion + '/entity/profiles' // get列表查询,delete删除,post新增,put修改
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
255
src/views/setting/entitySetting/EntitySetting.vue
Normal file
255
src/views/setting/entitySetting/EntitySetting.vue
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cn-tag">
|
||||||
|
<div class="cn-tag-right">
|
||||||
|
<cn-data-list
|
||||||
|
ref="dataList"
|
||||||
|
:tableId="tableId"
|
||||||
|
v-model:custom-table-title="tools.customTableTitle"
|
||||||
|
:api="url"
|
||||||
|
:from="fromRoute.tag"
|
||||||
|
:layout="['search']"
|
||||||
|
:input-width="'100%'"
|
||||||
|
@search="search"
|
||||||
|
>
|
||||||
|
<template #top-tool-left>
|
||||||
|
<button id="account-add" class="business-button tag__btn margin-r-10" @click="add">
|
||||||
|
<i class="cn-icon-xinjian cn-icon"></i>
|
||||||
|
<span>{{ $t('overall.create') }}</span>
|
||||||
|
</button>
|
||||||
|
<button id="tag-edit" class="business-button business-button--light tag__btn margin-r-10"
|
||||||
|
:disabled="disableEdit"
|
||||||
|
@click="editTag">
|
||||||
|
<i class="cn-icon-edit cn-icon"></i>
|
||||||
|
<span>{{ $t('overall.edit') }}</span>
|
||||||
|
</button>
|
||||||
|
<button id="tag-delete" class="business-button business-button--light tag__btn margin-r-10"
|
||||||
|
:disabled="disableDelete"
|
||||||
|
@click="delBatch">
|
||||||
|
<i class="cn-icon-delete cn-icon"></i>
|
||||||
|
<span>{{ $t('overall.delete') }}</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<loading :loading="loading"></loading>
|
||||||
|
<profiles-table
|
||||||
|
ref="dataTable"
|
||||||
|
:api="url"
|
||||||
|
:isNoData="isNoData"
|
||||||
|
:custom-table-title="tools.customTableTitle"
|
||||||
|
:height="mainTableHeight"
|
||||||
|
:table-data="tableData"
|
||||||
|
@delete="del"
|
||||||
|
@edit="edit"
|
||||||
|
@download="download"
|
||||||
|
@preview="preview"
|
||||||
|
@reload="getTableData"
|
||||||
|
@selectionChange="selectionChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #pagination>
|
||||||
|
<pagination ref="pagination" :page-obj="pageObj" :tableData="tableData" :table-id="tableId" @pageNo='pageNo'
|
||||||
|
@pageSize='pageSize'></pagination>
|
||||||
|
</template>
|
||||||
|
</cn-data-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
import { tagCategoryOptions, tagIntentOptions, tagSourceOptions } from '@/utils/constants'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import dataListMixin from '@/mixins/data-list'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
import cnDataList from '@/components/table/CnDataList'
|
||||||
|
import ProfilesTable from '@/components/table/setting/ProfilesTable'
|
||||||
|
import { profilesList } from '@/utils/static-data'
|
||||||
|
import axios from '_axios@0.21.4@axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EntitySetting',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
builtinColor: false,
|
||||||
|
// url: 'api.sourcesList',
|
||||||
|
url: api.setting.profiles.profiles,
|
||||||
|
tagIntentOptions,
|
||||||
|
tagCategoryOptions,
|
||||||
|
tagSourceOptions,
|
||||||
|
tableId: 'ProfilesTable',
|
||||||
|
builtinLeftLoading: false,
|
||||||
|
isInit: true,
|
||||||
|
intent: '',
|
||||||
|
category: '',
|
||||||
|
source: '',
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
const { query } = useRoute()
|
||||||
|
const urlPageNo = ref(parseInt(query.pageNo) || 1)
|
||||||
|
|
||||||
|
return {
|
||||||
|
urlPageNo
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [dataListMixin],
|
||||||
|
components: {
|
||||||
|
Loading,
|
||||||
|
cnDataList,
|
||||||
|
ProfilesTable
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getTableData()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
search (params) {
|
||||||
|
this.name = params.q
|
||||||
|
params = { name: this.name }
|
||||||
|
this.pageObj.pageNo = 1
|
||||||
|
this.getTableData(params)
|
||||||
|
this.$refs.dataTable.expandedIds = []
|
||||||
|
},
|
||||||
|
add () {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting/create',
|
||||||
|
query: {
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTableData (params) {
|
||||||
|
this.searchLabel = null
|
||||||
|
if (params) {
|
||||||
|
this.searchLabel = { ...this.searchLabel, ...params }
|
||||||
|
}
|
||||||
|
this.searchLabel = { ...this.searchLabel, ...this.pageObj }
|
||||||
|
this.isNoData = false
|
||||||
|
this.toggleLoading(true)
|
||||||
|
// delete this.searchLabel.total
|
||||||
|
let listUrl = this.url
|
||||||
|
if (this.listUrl) {
|
||||||
|
listUrl = this.listUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isInit) {
|
||||||
|
// this.tableData = profilesList
|
||||||
|
// this.pageObj.total = profilesList.length
|
||||||
|
// this.isNoData = !this.tableData || this.tableData.length === 0
|
||||||
|
// this.toggleLoading(false)
|
||||||
|
console.log('params', this.searchLabel)
|
||||||
|
axios.get(listUrl, { params: this.searchLabel }).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.tableData = response.data.data.list.map(item => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
config: item.config ? JSON.parse(item.config) : {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.pageObj.total = response.data.data.total
|
||||||
|
this.isNoData = !this.tableData || this.tableData.length === 0
|
||||||
|
})
|
||||||
|
// TODO 回到顶部
|
||||||
|
} else {
|
||||||
|
this.isNoData = true
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.toggleLoading(false)
|
||||||
|
this.$refs.dataTable.expandedIds = []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.isInit = false
|
||||||
|
},
|
||||||
|
delBatch () {
|
||||||
|
const ids = []
|
||||||
|
if (this.batchDeleteObjs && this.batchDeleteObjs.length > 0) {
|
||||||
|
this.batchDeleteObjs.forEach(item => {
|
||||||
|
ids.push(item.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (ids.length === 0) {
|
||||||
|
this.$alert(this.$t('tip.pleaseSelect'), {
|
||||||
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
|
type: 'warning'
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$confirm(this.$t('tip.confirmDelete'), {
|
||||||
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
|
cancelButtonText: this.$t('tip.no'),
|
||||||
|
customClass: 'del-model-message-box',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.toggleLoading(true)
|
||||||
|
axios.delete(api.setting.profiles.profiles + '?id=' + ids).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.delFlag = true
|
||||||
|
this.$message({
|
||||||
|
duration: 2000,
|
||||||
|
type: 'success',
|
||||||
|
message: this.$t('tip.deleteSuccess')
|
||||||
|
})
|
||||||
|
let params = null
|
||||||
|
if (this.intent) {
|
||||||
|
params = { intent: this.intent }
|
||||||
|
}
|
||||||
|
if (this.category) {
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
category: this.category
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.name) {
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
name: this.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.getTableData(params)
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.data.message)
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
this.$message.error(e.response.data.message)
|
||||||
|
}).finally(() => {
|
||||||
|
this.toggleLoading(false)
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
if (this.isSelectedStatus !== undefined) {
|
||||||
|
this.isSelectedStatus = false
|
||||||
|
this.disableDelete = true
|
||||||
|
this.batchDeleteObjs = []
|
||||||
|
this.$refs.dataTable.expandedIds = []
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editTag () {
|
||||||
|
if (this.batchDeleteObjs.length === 0) {
|
||||||
|
this.$alert(this.$t('tip.pleaseSelectForEdit'), {
|
||||||
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
|
type: 'warning'
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.jumpToEditPage(this.batchDeleteObjs[0].id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jumpToEditPage (id) {
|
||||||
|
const pageNo = this.$router.currentRoute.value.query.pageNo
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting/edit',
|
||||||
|
query: {
|
||||||
|
t: +new Date(),
|
||||||
|
pageNoForTable: pageNo || 1,
|
||||||
|
id: id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
612
src/views/setting/entitySetting/EntitySettingForm.vue
Normal file
612
src/views/setting/entitySetting/EntitySettingForm.vue
Normal file
@@ -0,0 +1,612 @@
|
|||||||
|
<template>
|
||||||
|
<div class="es-form">
|
||||||
|
<loading :loading="myLoading"></loading>
|
||||||
|
|
||||||
|
<div class="es-form-header">
|
||||||
|
<!-- {{ ruleId ? $t('detection.editEventPolicies') : $t('overall.entitySetting') }}-->
|
||||||
|
{{ $t('overall.entitySetting') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="es-form-content">
|
||||||
|
<!--第一步:General Settings-->
|
||||||
|
<div class="es-form-collapse">
|
||||||
|
<el-collapse v-model="activeNames">
|
||||||
|
<el-collapse-item name="1">
|
||||||
|
<template #title>
|
||||||
|
<div class="form-collapse-header">
|
||||||
|
<div :class="activeNames[0]==='1' ? 'form-collapse-header-no-active' : 'form-collapse-header-no'">1</div>
|
||||||
|
<div class="form-collapse-header-title">{{ $t('detection.create.generalSettings') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="form-collapse-content">
|
||||||
|
<el-form ref="sourceForm" :model="editObj" label-position="top" :rules="sourceRules">
|
||||||
|
<el-form-item :label="$t('setting.source')" prop="source_id" class="form-setting__block margin-b-20">
|
||||||
|
<el-select v-model="editObj.source_id" class="form-setting__select" placeholder=" ">
|
||||||
|
<el-option
|
||||||
|
v-for="item in sourceOption"
|
||||||
|
:key="item.source_id"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.source_id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="form-content__title">{{ $t('setting.schemaMapping') }}</div>
|
||||||
|
|
||||||
|
<el-form :model="editObj.schemaMappingData" ref="mappingForm">
|
||||||
|
<div class="form-content__block" v-for="(item, index) in editObj.schemaMappingData.data" :key="index">
|
||||||
|
<div class="block-header">
|
||||||
|
<div>{{ item.name }}</div>
|
||||||
|
<div>{{ $t('setting.source') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="block-body" v-for="(ite, ind) in item.list" :key="index+'-'+ind">
|
||||||
|
<el-form-item :prop="`data.${index}.list.${ind}.field`" :rules="mappingRules.type">
|
||||||
|
<el-select v-model="ite.field" class="block-body__select" placeholder="">
|
||||||
|
<el-option
|
||||||
|
v-for="obj in mappingFieldOption"
|
||||||
|
:key="obj.value"
|
||||||
|
:label="obj.label"
|
||||||
|
:value="obj.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="block-body-equal">=</div>
|
||||||
|
<el-form-item :prop="`data.${index}.list.${ind}.source`" :rules="mappingRules.source">
|
||||||
|
<el-select v-model="ite.source" class="block-body__select" placeholder="">
|
||||||
|
<el-option
|
||||||
|
v-for="obj in mappingSourceOption"
|
||||||
|
:key="obj.value"
|
||||||
|
:label="obj.label"
|
||||||
|
:value="obj.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<i class="cn-icon cn-icon-add mapping-item-add" @click="addMappingListItem(index, ind)"></i>
|
||||||
|
<i class="cn-icon cn-icon-close mapping-item-close" v-if="isCloseMappingItem" @click="deleteMappingItem(index, ind)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="form-setting-type" v-if="showMappingType">
|
||||||
|
<div class="setting-type__text">{{ $t('setting.selectMappingType') }}</div>
|
||||||
|
<el-select v-model="mappingItemType" placeholder="" @change="changeMappingType">
|
||||||
|
<el-option
|
||||||
|
v-for="obj in typeList"
|
||||||
|
:key="obj.value"
|
||||||
|
:label="obj.label"
|
||||||
|
:value="obj.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block__footer">
|
||||||
|
<!--新增按钮-->
|
||||||
|
<el-button class="addFieldBtn" @click="addSchemaMappingItem">
|
||||||
|
<i class="cn-icon cn-icon-add add-field-btn"></i>
|
||||||
|
{{ $t('overall.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-setting__btn">
|
||||||
|
<button @click="onContinue" class="business-button">{{ $t('detection.create.continue') }}</button>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--第二步:Relation-->
|
||||||
|
<div class="es-form-collapse">
|
||||||
|
<el-collapse v-model="activeNames">
|
||||||
|
<el-collapse-item name="2">
|
||||||
|
<template #title>
|
||||||
|
<div class="form-collapse-header">
|
||||||
|
<div :class="activeNames[0]==='2' ? 'form-collapse-header-no-active' : 'form-collapse-header-no'">2
|
||||||
|
</div>
|
||||||
|
<div class="form-collapse-header-title">{{ $t('setting.relation') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="form-collapse-content">
|
||||||
|
<el-form :model="editObj.relationData" ref="relationForm">
|
||||||
|
<div class="form-content__block">
|
||||||
|
<div class="block-body" v-for="(item, index) in editObj.relationData.data" :key="index">
|
||||||
|
<el-form-item :prop="`data.${index}.from_entity_index`" :rules="relationRules">
|
||||||
|
<el-select
|
||||||
|
v-model="item.from_entity_index"
|
||||||
|
:disabled="item.fromDisabled"
|
||||||
|
:class="item.fromDisabled ? 'relation-field__select-disabled' : 'relation-field__select'"
|
||||||
|
placeholder=""
|
||||||
|
@visible-change="visibleFromEntity(index)"
|
||||||
|
@change="changeFromEntity(index)">
|
||||||
|
<el-option
|
||||||
|
v-for="obj in editObj.schemaMappingData.data"
|
||||||
|
:key="obj.index"
|
||||||
|
:label="obj.name"
|
||||||
|
:value="obj.index"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="block-body-equal">=</div>
|
||||||
|
<el-form-item :prop="`data.${index}.to_entity_index`" :rules="relationRules">
|
||||||
|
<el-select
|
||||||
|
v-model="item.to_entity_index"
|
||||||
|
:disabled="item.toDisabled"
|
||||||
|
:class="item.toDisabled ? 'relation-field__select-disabled' : 'relation-field__select'"
|
||||||
|
placeholder=""
|
||||||
|
@change="changeToEntity(index)">
|
||||||
|
<el-option
|
||||||
|
v-for="obj in editObj.schemaMappingData.data"
|
||||||
|
:key="obj.index"
|
||||||
|
:label="obj.name"
|
||||||
|
:value="obj.index"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`data.${index}.type`" :rules="relationRules">
|
||||||
|
<el-select v-model="item.type" class="relation-type__select" :placeholder="$t('setting.relationType')">
|
||||||
|
<el-option
|
||||||
|
v-for="obj in relationTypeOption"
|
||||||
|
:key="obj.value"
|
||||||
|
:label="obj.label"
|
||||||
|
:value="obj.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<i class="cn-icon cn-icon-close mapping-item-close" @click="deleteRelationItem(index)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="block__footer">
|
||||||
|
<!--新增按钮-->
|
||||||
|
<el-button class="addFieldBtn" @click="addRelationItem">
|
||||||
|
<i class="cn-icon cn-icon-add add-field-btn"></i>
|
||||||
|
{{ $t('overall.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="switch__block margin-20">
|
||||||
|
<div class="block-title">{{ $t('overall.status') }}</div>
|
||||||
|
<el-switch
|
||||||
|
v-model="editObj.enable"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
:active-text="$t(switchStatus(editObj.enable))"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="es-form__footer">
|
||||||
|
<button class="business-button business-button--light tag__btn" @click="cancel">
|
||||||
|
<span>{{ $t('overall.cancel') }}</span>
|
||||||
|
</button>
|
||||||
|
<button style="position: relative;" class="business-button tag__btn" @click="saveEntity">
|
||||||
|
<!-- <loading :loading="blockOperation.save"></loading>-->
|
||||||
|
<span>{{ $t('overall.save') }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import { toUpperCaseByString, switchStatus } from '@/utils/tools'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EntitySettingForm',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
activeNames: ['1'],
|
||||||
|
intervalList: [],
|
||||||
|
sourceRules: {
|
||||||
|
source_id: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }]
|
||||||
|
},
|
||||||
|
mappingRules: {
|
||||||
|
type: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }],
|
||||||
|
source: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }]
|
||||||
|
},
|
||||||
|
relationRules: { required: true, message: this.$t('validate.required'), trigger: 'change' },
|
||||||
|
sourceOption: [],
|
||||||
|
mappingFieldOption: [
|
||||||
|
{ value: 'IP_address', label: 'IP_address' },
|
||||||
|
{ value: 'Port', label: 'Port' },
|
||||||
|
{ value: 'ASN', label: 'ASN' }
|
||||||
|
],
|
||||||
|
mappingSourceOption: [
|
||||||
|
{ value: 'dns_server_role', label: 'dns_server_role' },
|
||||||
|
{ value: 'ip_addr', label: 'ip_addr' },
|
||||||
|
{ value: 'category_name', label: 'category_name' }
|
||||||
|
],
|
||||||
|
typeOption: [
|
||||||
|
{ label: 'IP', value: 'IP' },
|
||||||
|
{ label: 'Domain', value: 'Domain' },
|
||||||
|
{ label: 'APP', value: 'APP' }
|
||||||
|
],
|
||||||
|
isCloseMappingItem: false, // 删除mapping标识
|
||||||
|
showMappingType: false,
|
||||||
|
mappingItemType: '', // 添加mapping映射类型
|
||||||
|
typeList: [
|
||||||
|
{ value: 'ip', label: 'ip' },
|
||||||
|
{ value: 'domain', label: 'domain' },
|
||||||
|
{ value: 'app', label: 'app' },
|
||||||
|
{ value: 'subscriber_id', label: 'subscriber' },
|
||||||
|
{ value: 'cell_id', label: 'cell' }
|
||||||
|
],
|
||||||
|
relationTypeOption: [
|
||||||
|
{ value: 'RESOLVE_DOMAIN_IP', label: 'RESOLVE_DOMAIN_IP' },
|
||||||
|
{ value: 'CARRY_APP_IP', label: 'CARRY_APP_IP' },
|
||||||
|
{ value: 'CARRY_APP_DOMAIN', label: 'CARRY_APP_DOMAIN' },
|
||||||
|
{ value: 'VISIT_SUBSCRIBER_APP', label: 'VISIT_SUBSCRIBER_APP' },
|
||||||
|
{ value: 'CALL_SUBSCRIBER_SUBSCRIBER', label: 'CALL_SUBSCRIBER_SUBSCRIBER' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Loading
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.initSourceData()
|
||||||
|
if (this.ruleId) {
|
||||||
|
this.getDetailInfo()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
const { query } = useRoute()
|
||||||
|
const ruleId = ref(query.id || '')
|
||||||
|
const pageNoForTable = ref(query.pageNoForTable || 1)
|
||||||
|
const myLoading = ref(!!ruleId.value)
|
||||||
|
// 第二步的form表单信息
|
||||||
|
const ruleObj = ref({})
|
||||||
|
|
||||||
|
const editObj = ref({
|
||||||
|
id: '',
|
||||||
|
source_id: '',
|
||||||
|
entities: [],
|
||||||
|
schemaMappingData: {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
type: 'ip',
|
||||||
|
name: 'IP',
|
||||||
|
list: [
|
||||||
|
{ field: '', source: '' }
|
||||||
|
],
|
||||||
|
mapping: {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
relations: [],
|
||||||
|
relationData: {
|
||||||
|
data: [{ from_entity_index: '', to_entity_index: '', type: '', fromDisabled: false, toDisabled: false }]
|
||||||
|
},
|
||||||
|
enable: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
ruleId,
|
||||||
|
myLoading,
|
||||||
|
pageNoForTable,
|
||||||
|
editObj,
|
||||||
|
ruleObj
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
switchStatus,
|
||||||
|
initSourceData () {
|
||||||
|
this.sourceOption = [
|
||||||
|
{ source_id: '1', value: 'ip_metric1', label: 'IP metric1' },
|
||||||
|
{ source_id: '2', value: 'ip_metric2', label: 'IP metric2' },
|
||||||
|
{ source_id: '3', value: 'ip_metric3', label: 'IP metric3' },
|
||||||
|
{ source_id: '4', value: 'ip_metric4', label: 'IP metric4' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
/** 编辑时获取详情 */
|
||||||
|
getDetailInfo () {
|
||||||
|
axios.get(`${api.setting.profiles.profiles}/${this.ruleId}`).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
if (!response.data.data) {
|
||||||
|
throw new Error('No data found, id: ' + this.ruleId)
|
||||||
|
}
|
||||||
|
this.myLoading = false
|
||||||
|
this.editObj = {
|
||||||
|
...response.data.data,
|
||||||
|
ruleId: this.ruleId
|
||||||
|
}
|
||||||
|
this.ruleObj = this.$_.cloneDeep(this.editObj.ruleConfigObj)
|
||||||
|
this.activeNames = ['1', '2']
|
||||||
|
} else {
|
||||||
|
console.error(response.data)
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting',
|
||||||
|
query: {
|
||||||
|
pageNo: this.pageNoForTable ? Number(this.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onContinue () {
|
||||||
|
this.$refs.mappingForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
// this.editObj.schemaMappingData.data[index].list.push({ field: '', source: '' })
|
||||||
|
// this.isCloseMappingItem = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addSchemaMappingItem () {
|
||||||
|
this.showMappingType = true
|
||||||
|
},
|
||||||
|
changeMappingType () {
|
||||||
|
const mappingList = this.editObj.schemaMappingData.data.filter(d => d.type === this.mappingItemType)
|
||||||
|
let name = ''
|
||||||
|
// 添加item后,按顺序给name添加名字
|
||||||
|
if (mappingList.length === 0) {
|
||||||
|
name = this.handleMappingName(this.mappingItemType)
|
||||||
|
} else if (mappingList.length === 1) {
|
||||||
|
mappingList[0].name = mappingList[0].name + 1
|
||||||
|
name = this.handleMappingName(this.mappingItemType, mappingList.length)
|
||||||
|
} else {
|
||||||
|
name = this.handleMappingName(this.mappingItemType, mappingList.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editObj.schemaMappingData.data.push({
|
||||||
|
index: this.editObj.schemaMappingData.data.length + 1,
|
||||||
|
type: this.mappingItemType,
|
||||||
|
name: name,
|
||||||
|
list: [{ field: '', source: '' }],
|
||||||
|
mapping: {}
|
||||||
|
})
|
||||||
|
this.isCloseMappingItem = true
|
||||||
|
this.showMappingType = false
|
||||||
|
this.mappingItemType = ''
|
||||||
|
},
|
||||||
|
/** 添加relation **/
|
||||||
|
addRelationItem () {
|
||||||
|
this.$refs.relationForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.editObj.relationData.data.push({ from_entity_index: '', to_entity_index: '', type: '', fromDisabled: false, toDisabled: false })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 添加schema mapping某一类型下的字段 **/
|
||||||
|
async addMappingListItem (index, ind) {
|
||||||
|
const valid1 = await this.$refs.mappingForm.validateField(`data.${index}.list.${ind}.field`, (valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
const valid2 = await this.$refs.mappingForm.validateField(`data.${index}.list.${ind}.source`, (valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
if (valid1 && valid2) {
|
||||||
|
this.editObj.schemaMappingData.data[index].list.push({ field: '', source: '' })
|
||||||
|
this.isCloseMappingItem = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 删除mapping下的子项 **/
|
||||||
|
deleteMappingItem (index, ind) {
|
||||||
|
const type = this.editObj.schemaMappingData.data[index].type
|
||||||
|
if (this.editObj.schemaMappingData.data[index].list.length > 1) {
|
||||||
|
this.editObj.schemaMappingData.data[index].list.splice(ind, 1)
|
||||||
|
} else {
|
||||||
|
this.editObj.schemaMappingData.data.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editObj.schemaMappingData.data.forEach((item, index) => {
|
||||||
|
item.index = index + 1
|
||||||
|
})
|
||||||
|
|
||||||
|
// 删除同类型的,name需要重新排序
|
||||||
|
const list = this.editObj.schemaMappingData.data.filter(d => d.type === type)
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
if (list.length === 1) {
|
||||||
|
list[0].name = this.handleMappingName(list[0].type)
|
||||||
|
} else {
|
||||||
|
list.forEach((item, i) => {
|
||||||
|
item.name = this.handleMappingName(item.type, i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.editObj.schemaMappingData.data.length > 1) {
|
||||||
|
this.isCloseMappingItem = true
|
||||||
|
} else {
|
||||||
|
this.isCloseMappingItem = this.editObj.schemaMappingData.data[0].list.length > 1
|
||||||
|
}
|
||||||
|
console.log('shuzu', this.editObj.schemaMappingData.data)
|
||||||
|
},
|
||||||
|
/** 删除relation的子项 **/
|
||||||
|
deleteRelationItem (index) {
|
||||||
|
this.editObj.relationData.data.splice(index, 1)
|
||||||
|
},
|
||||||
|
/** 修改mapping的模块名 **/
|
||||||
|
handleMappingName (type, index) {
|
||||||
|
let name = ''
|
||||||
|
if (type === 'ip' || type === 'app') {
|
||||||
|
name = index >= 0 ? type.toUpperCase() + (index + 1) : type.toUpperCase()
|
||||||
|
} else {
|
||||||
|
name = index >= 0 ? toUpperCaseByString(type) + (index + 1) : toUpperCaseByString(type)
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
},
|
||||||
|
visibleFromEntity (index) {
|
||||||
|
console.log('visible---from', this.editObj.relationData.data, index)
|
||||||
|
},
|
||||||
|
changeFromEntity (index) {
|
||||||
|
console.log('from---data', this.editObj.relationData.data)
|
||||||
|
this.editObj.relationData.data[index].fromDisabled = true
|
||||||
|
},
|
||||||
|
changeToEntity (index) {
|
||||||
|
console.log('to---data', this.editObj.relationData.data)
|
||||||
|
this.editObj.relationData.data[index].toDisabled = true
|
||||||
|
},
|
||||||
|
handleToEntityData (index) {
|
||||||
|
console.log('index', index)
|
||||||
|
if (index && index >= 0) {
|
||||||
|
const obj = this.editObj.relationData.data[index]
|
||||||
|
console.log('obj', obj)
|
||||||
|
}
|
||||||
|
return this.editObj.schemaMappingData.data
|
||||||
|
},
|
||||||
|
/** 获取Rule Definition折叠板form数据 */
|
||||||
|
getRuleObj (data) {
|
||||||
|
if (data.dataSource && data.knowledgeId && data.level) {
|
||||||
|
data.editFlag = false
|
||||||
|
data.saveFlag = true
|
||||||
|
this.handleActiveNames('2', this.activeNames, data.ruleNoContinue)
|
||||||
|
}
|
||||||
|
this.ruleObj = JSON.parse(JSON.stringify(data))
|
||||||
|
},
|
||||||
|
/** 自动展开收起折叠板 */
|
||||||
|
handleActiveNames (name, arr, flag) {
|
||||||
|
if (!flag) {
|
||||||
|
const list = arr
|
||||||
|
list.splice(list.indexOf(name), 1)
|
||||||
|
if (name === '1' && list.indexOf('2') < 0) {
|
||||||
|
list.push('2')
|
||||||
|
}
|
||||||
|
if (name === '2' && list.indexOf('3') < 0) {
|
||||||
|
list.push('3')
|
||||||
|
}
|
||||||
|
this.activeNames = []
|
||||||
|
list.forEach(t => {
|
||||||
|
this.activeNames.push(t)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 创建entity */
|
||||||
|
async saveEntity () {
|
||||||
|
const valid1 = await this.$refs.sourceForm.validate((valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
const valid2 = await this.$refs.mappingForm.validate((valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
const valid3 = await this.$refs.relationForm.validate((valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
console.log('obj', this.editObj)
|
||||||
|
const formObj = this.$_.cloneDeep(this.editObj)
|
||||||
|
formObj.schemaMappingData.data.forEach((item) => {
|
||||||
|
const obj = {}
|
||||||
|
item.list.forEach(ite => {
|
||||||
|
obj[ite.field] = ite.source
|
||||||
|
})
|
||||||
|
item.mapping = this.$_.cloneDeep(obj)
|
||||||
|
})
|
||||||
|
console.log('formObj', formObj)
|
||||||
|
if (valid1 && valid2 && valid3) {
|
||||||
|
this.myLoading = true
|
||||||
|
if (!this.ruleId) {
|
||||||
|
const formObj = this.$_.cloneDeep(this.editObj)
|
||||||
|
formObj.schemaMappingData.data.forEach((item) => {
|
||||||
|
const obj = {}
|
||||||
|
item.list.forEach(ite => {
|
||||||
|
obj[ite.field] = ite.source
|
||||||
|
})
|
||||||
|
item.mapping = this.$_.cloneDeep(obj)
|
||||||
|
})
|
||||||
|
// post调用是新增,put是编辑
|
||||||
|
axios.post(api.setting.profiles.profiles, formObj).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
|
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting',
|
||||||
|
query: {
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error(response.data.message)
|
||||||
|
this.$message.error(this.errorMsgHandler(response))
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
}).finally(() => {
|
||||||
|
this.myLoading = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
axios.put(api.setting.profiles.profiles, 'formObj').then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
|
|
||||||
|
const { query } = this.$route
|
||||||
|
const queryInfo = {
|
||||||
|
pageNo: self.pageNoForTable ? Number(self.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
if (query.name && query.id) {
|
||||||
|
queryInfo.ruleId = query.id
|
||||||
|
queryInfo.name = this.settingObj.name
|
||||||
|
}
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting',
|
||||||
|
query: queryInfo
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error(response.data.message)
|
||||||
|
this.$message.error(this.errorMsgHandler(response))
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
}).finally(() => {
|
||||||
|
this.myLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel () {
|
||||||
|
const { query } = this.$route
|
||||||
|
const queryInfo = {
|
||||||
|
pageNo: this.pageNoForTable ? Number(this.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
if (query.name && query.id) {
|
||||||
|
queryInfo.ruleId = query.id
|
||||||
|
queryInfo.name = this.settingObj.name
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.settingObj.editFlag || this.ruleObj.editFlag) {
|
||||||
|
this.confirmMessage(queryInfo)
|
||||||
|
} else {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting',
|
||||||
|
query: queryInfo
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
confirmMessage (queryInfo) {
|
||||||
|
ElMessageBox.confirm(this.$t('tip.leavePage'), {
|
||||||
|
confirmButtonText: this.$t('tip.confirm'),
|
||||||
|
cancelButtonText: this.$t('overall.cancel'),
|
||||||
|
message: this.$t('tip.leavePageTips'),
|
||||||
|
title: this.$t('tip.leavePage'),
|
||||||
|
// type: 'warning',
|
||||||
|
iconClass: 'width:0px;height:0px;',
|
||||||
|
customClass: 'del-model'
|
||||||
|
}).then(() => {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/entitySetting',
|
||||||
|
query: queryInfo
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
252
src/views/setting/sources/Sources.vue
Normal file
252
src/views/setting/sources/Sources.vue
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
<template>
|
||||||
|
<div class="cn-tag">
|
||||||
|
<div class="cn-tag-right">
|
||||||
|
<cn-data-list
|
||||||
|
ref="dataList"
|
||||||
|
:tableId="tableId"
|
||||||
|
v-model:custom-table-title="tools.customTableTitle"
|
||||||
|
:api="url"
|
||||||
|
:from="fromRoute.tag"
|
||||||
|
:layout="['search']"
|
||||||
|
:input-width="'100%'"
|
||||||
|
@search="search"
|
||||||
|
>
|
||||||
|
<template #top-tool-left>
|
||||||
|
<button id="account-add" class="business-button tag__btn margin-r-10" @click="add">
|
||||||
|
<i class="cn-icon-xinjian cn-icon"></i>
|
||||||
|
<span>{{ $t('overall.create') }}</span>
|
||||||
|
</button>
|
||||||
|
<button id="tag-edit" class="business-button business-button--light tag__btn margin-r-10"
|
||||||
|
:disabled="disableEdit"
|
||||||
|
@click="editTag">
|
||||||
|
<i class="cn-icon-edit cn-icon"></i>
|
||||||
|
<span>{{ $t('overall.edit') }}</span>
|
||||||
|
</button>
|
||||||
|
<button id="tag-delete" class="business-button business-button--light tag__btn margin-r-10"
|
||||||
|
:disabled="disableDelete"
|
||||||
|
@click="delBatch">
|
||||||
|
<i class="cn-icon-delete cn-icon"></i>
|
||||||
|
<span>{{ $t('overall.delete') }}</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<loading :loading="loading"></loading>
|
||||||
|
<sources-table
|
||||||
|
ref="dataTable"
|
||||||
|
:api="url"
|
||||||
|
:isNoData="isNoData"
|
||||||
|
:custom-table-title="tools.customTableTitle"
|
||||||
|
:height="mainTableHeight"
|
||||||
|
:table-data="tableData"
|
||||||
|
@delete="delItem"
|
||||||
|
@edit="edit"
|
||||||
|
@download="download"
|
||||||
|
@preview="preview"
|
||||||
|
@reload="getTableData"
|
||||||
|
@selectionChange="selectionChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #pagination>
|
||||||
|
<pagination ref="pagination" :page-obj="pageObj" :tableData="tableData" :table-id="tableId" @pageNo='pageNo'
|
||||||
|
@pageSize='pageSize'></pagination>
|
||||||
|
</template>
|
||||||
|
</cn-data-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios'
|
||||||
|
import SourcesTable from '@/components/table/setting/SourcesTable'
|
||||||
|
import cnDataList from '@/components/table/CnDataList'
|
||||||
|
import dataListMixin from '@/mixins/data-list'
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
import { tagIntentOptions, tagCategoryOptions, tagSourceOptions } from '@/utils/constants'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Sources',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
builtinColor: false,
|
||||||
|
url: api.setting.source.source,
|
||||||
|
tagIntentOptions,
|
||||||
|
tagCategoryOptions,
|
||||||
|
tagSourceOptions,
|
||||||
|
tableId: 'sourcesTable',
|
||||||
|
builtinLeftLoading: false,
|
||||||
|
isInit: true,
|
||||||
|
intent: '',
|
||||||
|
category: '',
|
||||||
|
source: '',
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
const { query } = useRoute()
|
||||||
|
const urlPageNo = ref(parseInt(query.pageNo) || 1)
|
||||||
|
|
||||||
|
return {
|
||||||
|
urlPageNo
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [dataListMixin],
|
||||||
|
components: {
|
||||||
|
Loading,
|
||||||
|
cnDataList,
|
||||||
|
SourcesTable
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getTableData()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
search (params) {
|
||||||
|
this.name = params.q
|
||||||
|
params = { name: this.name }
|
||||||
|
this.pageObj.pageNo = 1
|
||||||
|
this.getTableData(params)
|
||||||
|
this.$refs.dataTable.expandedIds = []
|
||||||
|
},
|
||||||
|
delBatch () {
|
||||||
|
const ids = []
|
||||||
|
if (this.batchDeleteObjs && this.batchDeleteObjs.length > 0) {
|
||||||
|
this.batchDeleteObjs.forEach(item => {
|
||||||
|
ids.push(item.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (ids.length === 0) {
|
||||||
|
this.$alert(this.$t('tip.pleaseSelect'), {
|
||||||
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
|
type: 'warning'
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$confirm(this.$t('tip.confirmDelete'), {
|
||||||
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
|
cancelButtonText: this.$t('tip.no'),
|
||||||
|
customClass: 'del-model-message-box',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
this.toggleLoading(true)
|
||||||
|
axios.delete(this.url + '?ids=' + ids).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.delFlag = true
|
||||||
|
this.$message({
|
||||||
|
duration: 2000,
|
||||||
|
type: 'success',
|
||||||
|
message: this.$t('tip.deleteSuccess')
|
||||||
|
})
|
||||||
|
let params = null
|
||||||
|
if (this.intent) {
|
||||||
|
params = { intent: this.intent }
|
||||||
|
}
|
||||||
|
if (this.category) {
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
category: this.category
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.name) {
|
||||||
|
params = {
|
||||||
|
...params,
|
||||||
|
name: this.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.getTableData(params)
|
||||||
|
} else {
|
||||||
|
this.$message.error(response.data.message)
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
this.$message.error(e.response.data.message)
|
||||||
|
}).finally(() => {
|
||||||
|
this.toggleLoading(false)
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
if (this.isSelectedStatus !== undefined) {
|
||||||
|
this.isSelectedStatus = false
|
||||||
|
this.disableDelete = true
|
||||||
|
this.batchDeleteObjs = []
|
||||||
|
this.$refs.dataTable.expandedIds = []
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTableData (params) {
|
||||||
|
this.searchLabel = null
|
||||||
|
if (params) {
|
||||||
|
this.searchLabel = { ...this.searchLabel, ...params }
|
||||||
|
}
|
||||||
|
this.searchLabel = { ...this.searchLabel, ...this.pageObj }
|
||||||
|
this.isNoData = false
|
||||||
|
this.toggleLoading(true)
|
||||||
|
// delete this.searchLabel.total
|
||||||
|
let listUrl = this.url
|
||||||
|
if (this.listUrl) {
|
||||||
|
listUrl = this.listUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isInit) {
|
||||||
|
axios.get(listUrl, { params: this.searchLabel }).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.tableData = response.data.data.list.map(item => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
config: item.config ? JSON.parse(item.config) : {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.pageObj.total = response.data.data.total
|
||||||
|
this.isNoData = !this.tableData || this.tableData.length === 0
|
||||||
|
})
|
||||||
|
// TODO 回到顶部
|
||||||
|
} else {
|
||||||
|
this.isNoData = true
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.toggleLoading(false)
|
||||||
|
this.$refs.dataTable.expandedIds = []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.isInit = false
|
||||||
|
},
|
||||||
|
add () {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source/create',
|
||||||
|
query: {
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
edit (u) {
|
||||||
|
this.object = u
|
||||||
|
this.rightBox.show = true
|
||||||
|
},
|
||||||
|
editTag () {
|
||||||
|
if (this.batchDeleteObjs.length === 0) {
|
||||||
|
this.$alert(this.$t('tip.pleaseSelectForEdit'), {
|
||||||
|
confirmButtonText: this.$t('tip.yes'),
|
||||||
|
type: 'warning'
|
||||||
|
}).catch(() => {
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.jumpToEditPage(this.batchDeleteObjs[0].id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jumpToEditPage (id) {
|
||||||
|
const pageNo = this.$router.currentRoute.value.query.pageNo
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source/edit',
|
||||||
|
query: {
|
||||||
|
t: +new Date(),
|
||||||
|
pageNoForTable: pageNo || 1,
|
||||||
|
id: id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
479
src/views/setting/sources/SourcesForm.vue
Normal file
479
src/views/setting/sources/SourcesForm.vue
Normal file
@@ -0,0 +1,479 @@
|
|||||||
|
<template>
|
||||||
|
<div class="sources-form">
|
||||||
|
<loading :loading="myLoading"></loading>
|
||||||
|
<div class="sources-form__header">{{ sourceObj.id ? $t('sources.editSource') : $t('sources.createSource') }}</div>
|
||||||
|
<div class="sources-form__body">
|
||||||
|
<el-form ref="baseForm" :model="sourceObj" label-position="top" style="width: 620px" :rules="rules">
|
||||||
|
<el-form-item :label="$t('overall.name')" prop="name">
|
||||||
|
<el-input v-model="sourceObj.name" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item :label="$t('sources.dataFormat')" prop="dataFormat">
|
||||||
|
<el-select v-model="sourceObj.dataFormat" placeholder="">
|
||||||
|
<el-option
|
||||||
|
v-for="item in formatOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="form__body__label">{{ $t('overall.fields') }}</div>
|
||||||
|
<el-form ref="fieldsForm" :model="sourceObj.fieldsData">
|
||||||
|
<div class="form-fields__block">
|
||||||
|
<div class="block__header">
|
||||||
|
<div class="block__header-name">{{ $t('overall.name') }}</div>
|
||||||
|
<div class="block__header-type">{{ $t('overall.type') }}</div>
|
||||||
|
<div class="block__header-default">{{ $t('overall.default') }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block__body">
|
||||||
|
<div class="block__body-container" v-for="(item, index) in sourceObj.fieldsData.data" :key="index">
|
||||||
|
<el-form-item :prop="`data.${index}.name`" :rules="fieldsRules.name">
|
||||||
|
<div class="block__body-name">
|
||||||
|
<el-input :ref="`name-${index}`" v-model="item.name" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`data.${index}.type`" :rules="fieldsRules.type">
|
||||||
|
<div class="block__body-type">
|
||||||
|
<el-select ref="field-type" v-model="item.type" placeholder="">
|
||||||
|
<el-option
|
||||||
|
v-for="ite in typeOption"
|
||||||
|
:key="ite.value"
|
||||||
|
:label="ite.label"
|
||||||
|
:value="ite.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`data.${index}.default`">
|
||||||
|
<div class="block__body-default">
|
||||||
|
<el-input :ref="`default-${index}`" v-model="item.default" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<i class="cn-icon cn-icon-close remove-btn" v-if="sourceObj.fieldsData.data.length > 1" @click="removeFieldItem(index)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block__footer">
|
||||||
|
<!--新增按钮-->
|
||||||
|
<el-button class="addFieldBtn" @click="addFieldItem">
|
||||||
|
<i class="cn-icon cn-icon-add add-field-btn"></i>
|
||||||
|
{{$t('overall.add')}}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="form__body__label">{{ $t('setting.lookups') }}</div>
|
||||||
|
<el-form ref="lookupsForm" :model="sourceObj.lookupsData">
|
||||||
|
<div class="form-fields__block">
|
||||||
|
<div class="block__body">
|
||||||
|
<div class="block__body-container" v-for="(item, index) in sourceObj.lookupsData.data" :key="index">
|
||||||
|
<el-form-item :prop="`data.${index}.function`" :rules="lookupRules.function">
|
||||||
|
<div class="block__body-function">
|
||||||
|
<el-select v-model="item.function" :placeholder="$t('setting.functionName')" @change="onChangeFunction(index)">
|
||||||
|
<el-option
|
||||||
|
v-for="ite in lookupsObj.functionOption"
|
||||||
|
:key="ite.value"
|
||||||
|
:label="ite.label"
|
||||||
|
:value="ite.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`data.${index}.lookup_field`" :rules="lookupRules.lookup_field">
|
||||||
|
<div class="block__body-field">
|
||||||
|
<el-select v-model="item.lookup_field" :placeholder="$t('setting.lookupField')">
|
||||||
|
<el-option
|
||||||
|
v-for="ite in lookupsObj.lookupFieldsOption"
|
||||||
|
:key="ite.name"
|
||||||
|
:label="ite.name"
|
||||||
|
:value="ite.name"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`data.${index}.output_type`" :rules="lookupRules.output_type">
|
||||||
|
<div class="block__body-field">
|
||||||
|
<el-select v-model="item.output_type" :placeholder="$t('setting.outputField')">
|
||||||
|
<el-option
|
||||||
|
v-for="ite in lookupsObj.outputFieldsOption[item.function]"
|
||||||
|
:key="ite.value"
|
||||||
|
:label="ite.label"
|
||||||
|
:value="ite.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :prop="`data.${index}.output_field`" :rules="lookupRules.output_field">
|
||||||
|
<div class="block__body-field-name">
|
||||||
|
<el-input v-model="item.output_field" :placeholder="$t('setting.outputFieldName')" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<i class="cn-icon cn-icon-close remove-btn" v-if="sourceObj.lookupsData.data.length > 1" @click="removeLookupItem(index)"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="block__footer">
|
||||||
|
<!--新增按钮-->
|
||||||
|
<el-button class="addFieldBtn" @click="addLookupItem">
|
||||||
|
<i class="cn-icon cn-icon-add add-field-btn"></i>
|
||||||
|
{{$t('overall.add')}}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="form__body__label">{{ $t('overall.remark') }}</div>
|
||||||
|
<el-input
|
||||||
|
class="form-description"
|
||||||
|
maxlength="255"
|
||||||
|
show-word-limit
|
||||||
|
:rows="5"
|
||||||
|
size='mini'
|
||||||
|
type="textarea"
|
||||||
|
resize='none'
|
||||||
|
v-model="sourceObj.description"
|
||||||
|
id="role-box-input-remark"/>
|
||||||
|
|
||||||
|
<div class="form-setting__block margin-b-20">
|
||||||
|
<div class="block-title">{{ $t('overall.status') }}</div>
|
||||||
|
<el-switch
|
||||||
|
v-model="sourceObj.enable"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
:active-text="$t(switchStatus(sourceObj.enable))"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sources-form__footer">
|
||||||
|
<button class="business-button business-button--light tag__btn" @click="cancel">
|
||||||
|
<span>{{ $t('overall.cancel') }}</span>
|
||||||
|
</button>
|
||||||
|
<button style="position: relative;" :class="{'disabled': blockOperation.save}"
|
||||||
|
:disabled="blockOperation.save" class="business-button tag__btn" @click="saveSource">
|
||||||
|
<loading :loading="blockOperation.save"></loading>
|
||||||
|
<span>{{ $t('overall.save') }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import _ from 'lodash'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
import { ElMessageBox } from 'element-plus'
|
||||||
|
import i18n from '@/i18n'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
import { switchStatus } from '@/utils/tools'
|
||||||
|
export default {
|
||||||
|
name: 'SourceForm',
|
||||||
|
components: {
|
||||||
|
Loading
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
const nameValidator = (rule, value, callback) => {
|
||||||
|
// 校验value包含字母、数字和下划线,并且不是全数字、全下划线和连续下划线
|
||||||
|
const regex = /^(?=.*[a-zA-Z])(?=.*\d|^(?!\d+$))[a-zA-Z\d]+(?:_[a-zA-Z\d]+)*$/
|
||||||
|
return regex.test(value)
|
||||||
|
}
|
||||||
|
const nameRepeat = (rule, value, callback) => {
|
||||||
|
// 字段重复校验
|
||||||
|
let validate = true
|
||||||
|
const repeatList = this.sourceObj.fieldsData.data.filter(d => d.name === value)
|
||||||
|
if (repeatList.length > 1) {
|
||||||
|
validate = false
|
||||||
|
}
|
||||||
|
return validate
|
||||||
|
}
|
||||||
|
const outputFieldRepeat = (rule, value, callback) => {
|
||||||
|
// 输出字段不能和输入字段重名
|
||||||
|
let validate = true
|
||||||
|
const repeatList = this.sourceObj.fieldsData.data.filter(d => d.name === value)
|
||||||
|
if (repeatList.length > 0) {
|
||||||
|
validate = false
|
||||||
|
}
|
||||||
|
return validate
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
rules: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||||
|
],
|
||||||
|
dataFormat: [
|
||||||
|
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
fieldsRules: {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
||||||
|
{ validator: nameValidator, message: i18n.global.t('validate.onlyAllowNumberLetter_'), trigger: 'blur' },
|
||||||
|
{ validator: nameRepeat, message: i18n.global.t('validate.fieldDuplicate'), trigger: 'blur' }
|
||||||
|
],
|
||||||
|
type: [
|
||||||
|
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
lookupRules: {
|
||||||
|
function: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }],
|
||||||
|
lookup_field: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }],
|
||||||
|
output_type: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }],
|
||||||
|
output_field: [
|
||||||
|
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
||||||
|
{ validator: nameValidator, message: i18n.global.t('validate.onlyAllowNumberLetter_'), trigger: 'blur' },
|
||||||
|
{ validator: outputFieldRepeat, message: i18n.global.t('validate.outputFieldNotLookupField'), trigger: 'blur' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// format下拉框数据
|
||||||
|
formatOptions: [
|
||||||
|
{ label: 'json', value: 'json' },
|
||||||
|
{ label: 'csv', value: 'csv' }
|
||||||
|
],
|
||||||
|
// field的type下拉框
|
||||||
|
typeOption: [
|
||||||
|
{ label: 'string', value: 'string' },
|
||||||
|
{ label: 'int', value: 'int' },
|
||||||
|
{ label: 'float', value: 'float' },
|
||||||
|
{ label: 'long', value: 'long' },
|
||||||
|
{ label: 'double', value: 'double' }
|
||||||
|
],
|
||||||
|
blockOperation: { save: false },
|
||||||
|
addEditFlag: false, // 新增最后一个field标识
|
||||||
|
lookupsObj: {
|
||||||
|
// lookup的function name下拉列表
|
||||||
|
functionOption: [
|
||||||
|
{ label: 'GEOIP_LOOKUP', value: 'GEOIP_LOOKUP' },
|
||||||
|
{ label: 'ASN_LOOKUP', value: 'ASN_LOOKUP' }
|
||||||
|
],
|
||||||
|
// lookup的字段下拉列表
|
||||||
|
lookupFieldsOption: this.sourceObj.fieldsData.data,
|
||||||
|
// lookup的output字段下拉列表
|
||||||
|
outputFieldsOption: {
|
||||||
|
GEOIP_LOOKUP: [
|
||||||
|
{ label: 'COUNTRY', value: 'COUNTRY' },
|
||||||
|
{ label: 'PROVINCE', value: 'PROVINCE' },
|
||||||
|
{ label: 'CITY', value: 'CITY' },
|
||||||
|
{ label: 'LONGITUDE', value: 'LONGITUDE' },
|
||||||
|
{ label: 'LATITUDE', value: 'LATITUDE' },
|
||||||
|
{ label: 'ISP', value: 'ISP' },
|
||||||
|
{ label: 'ORGANIZATION', value: 'ORGANIZATION' }
|
||||||
|
],
|
||||||
|
ASN_LOOKUP: [
|
||||||
|
{ label: 'ASN', value: 'ASN' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lookupsIndex: -1,
|
||||||
|
lookupsForm: {
|
||||||
|
function: '',
|
||||||
|
lookup_field: '',
|
||||||
|
output_type: '',
|
||||||
|
output_field: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
if (this.sourceId) {
|
||||||
|
this.initDetailInfo()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
switchStatus,
|
||||||
|
/**
|
||||||
|
* 编辑时初始化source详情
|
||||||
|
*/
|
||||||
|
initDetailInfo () {
|
||||||
|
axios.get(`${api.setting.source.source}/${this.sourceId}`).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
if (!response.data.data) {
|
||||||
|
throw new Error('No data found, id: ' + this.sourceId)
|
||||||
|
}
|
||||||
|
this.myLoading = false
|
||||||
|
this.sourceObj = { ...this.sourceObj, ...response.data.data, sourceId: this.sourceId }
|
||||||
|
this.sourceObj.fieldsData.data = JSON.parse(this.sourceObj.fields)
|
||||||
|
this.sourceObj.lookupsData.data = JSON.parse(this.sourceObj.lookups)
|
||||||
|
} else {
|
||||||
|
console.error(response.data)
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source',
|
||||||
|
query: {
|
||||||
|
pageNo: this.pageNoForTable ? Number(this.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async saveSource () {
|
||||||
|
const valid1 = await this.$refs.baseForm.validate((valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
const valid2 = await this.$refs.fieldsForm.validate((valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
const valid3 = await this.$refs.lookupsForm.validate((valid) => {
|
||||||
|
return valid
|
||||||
|
})
|
||||||
|
if (valid1 && valid2 && valid3) {
|
||||||
|
this.myLoading = true
|
||||||
|
this.sourceObj.fields = JSON.stringify(this.sourceObj.fieldsData.data)
|
||||||
|
this.sourceObj.lookups = JSON.stringify(this.sourceObj.lookupsData.data)
|
||||||
|
if (!this.sourceId) {
|
||||||
|
// post调用是新增,put是编辑
|
||||||
|
axios.post(api.setting.source.source, this.sourceObj).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.$message({
|
||||||
|
duration: 2000,
|
||||||
|
type: 'success',
|
||||||
|
message: this.$t('tip.saveSuccess')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source',
|
||||||
|
query: {
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error(response.data.message)
|
||||||
|
this.$message.error(this.errorMsgHandler(response))
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
}).finally(() => {
|
||||||
|
this.myLoading = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
axios.put(api.setting.source.source, this.sourceObj).then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||||
|
|
||||||
|
const { query } = this.$route
|
||||||
|
const queryInfo = {
|
||||||
|
pageNo: self.pageNoForTable ? Number(self.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
if (query.name && query.id) {
|
||||||
|
queryInfo.sourceId = query.id
|
||||||
|
queryInfo.name = this.settingObj.name
|
||||||
|
}
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source',
|
||||||
|
query: queryInfo
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error(response.data.message)
|
||||||
|
this.$message.error(this.errorMsgHandler(response))
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
this.$message.error(this.errorMsgHandler(e))
|
||||||
|
}).finally(() => {
|
||||||
|
this.myLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel () {
|
||||||
|
const self = this
|
||||||
|
if (this.isPreviewChange) {
|
||||||
|
ElMessageBox.confirm(this.$t('tip.leavePage'), {
|
||||||
|
confirmButtonText: this.$t('tip.confirm'),
|
||||||
|
cancelButtonText: this.$t('overall.cancel'),
|
||||||
|
message: this.$t('tip.leavePageTips'),
|
||||||
|
title: this.$t('tip.leavePage'),
|
||||||
|
// type: 'warning',
|
||||||
|
iconClass: 'width:0px;height:0px;',
|
||||||
|
customClass: 'del-model'
|
||||||
|
}).then(() => {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source',
|
||||||
|
query: {
|
||||||
|
pageNo: self.pageNoForTable ? Number(self.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
|
} else {
|
||||||
|
this.$router.push({
|
||||||
|
path: '/setting/source',
|
||||||
|
query: {
|
||||||
|
pageNo: self.pageNoForTable ? Number(self.pageNoForTable) : 1,
|
||||||
|
t: +new Date()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addFieldItem () {
|
||||||
|
this.$refs.fieldsForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.addEditFlag = true
|
||||||
|
this.sourceObj.fieldsData.data.push({ name: '', type: '', default: '' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addLookupItem () {
|
||||||
|
this.$refs.lookupsForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
this.lookupsIndex = -1
|
||||||
|
this.addEditFlag = true
|
||||||
|
this.sourceObj.lookupsData.data.push({ function: '', lookup_field: '', output_type: '', output_field: '' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
removeFieldItem (i) {
|
||||||
|
this.addEditFlag = false
|
||||||
|
this.sourceObj.fieldsData.data.splice(i, 1)
|
||||||
|
},
|
||||||
|
removeLookupItem (i) {
|
||||||
|
this.addEditFlag = false
|
||||||
|
this.sourceObj.lookupsData.data.splice(i, 1)
|
||||||
|
},
|
||||||
|
// lookups的function切换,重置outputField
|
||||||
|
onChangeFunction (index) {
|
||||||
|
this.sourceObj.lookupsData.data[index].output_type = ''
|
||||||
|
// this.$refs.lookupsForm.clearValidate('output_type')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
const { query } = useRoute()
|
||||||
|
const sourceId = ref(query.id || '')
|
||||||
|
const pageNoForTable = ref(query.pageNoForTable || 1)
|
||||||
|
const myLoading = ref(!!sourceId.value)
|
||||||
|
const blankObject = {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
dataFormat: '',
|
||||||
|
fields: [],
|
||||||
|
// fields列表数据
|
||||||
|
fieldsData: {
|
||||||
|
data: [{ name: '', type: '', default: '' }]
|
||||||
|
},
|
||||||
|
lookups: [],
|
||||||
|
// lookups列表数据
|
||||||
|
lookupsData: {
|
||||||
|
data: [{ function: '', lookup_field: '', output_type: '', output_field: '' }]
|
||||||
|
},
|
||||||
|
description: '',
|
||||||
|
enable: 1
|
||||||
|
}
|
||||||
|
const sourceObj = ref(_.cloneDeep(blankObject))
|
||||||
|
return {
|
||||||
|
sourceId,
|
||||||
|
pageNoForTable,
|
||||||
|
myLoading,
|
||||||
|
sourceObj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user