ui-vue3/src/views/resources/applications/tabs/config.vue (461 lines of code) (raw):
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<template>
<div class="__container_app_config">
<config-page :options="options">
<template v-slot:form_log="{ current }">
<a-form-item :label="$t('applicationDomain.operatorLog')" name="logFlag">
<a-switch v-model:checked="current.form.logFlag"></a-switch>
</a-form-item>
</template>
<template v-slot:form_flow="{ current }">
<a-space direction="vertical" size="middle" class="flowWeight-box">
<a-card :id="'flowWeight' + i" v-for="(item, i) in current.form.rules">
<template #title>
{{ $t('applicationDomain.flowWeight') }} {{ i + 1 }}
<div style="float: right">
<a-space>
<a-button danger type="dashed" @click="deleteFlowWeight(i)">
<Icon style="font-size: 20px" icon="fluent:delete-12-filled"></Icon>
</a-button>
</a-space>
</div>
</template>
<a-form-item :name="'rules[' + i + '].weight'" label="权重">
<a-input-number min="1" v-model:value="item.weight"></a-input-number>
</a-form-item>
<a-form-item label="作用范围">
<a-button type="primary" @click="addScopeItem(i)"> 添加</a-button>
<a-table
style="width: 40vw"
:pagination="false"
:columns="scopeColumns"
:data-source="item.scope"
>
<template #bodyCell="{ column, record, index: scopeItemIndex }">
<template v-if="column.key === 'key'">
<a-form-item :name="'rules[' + i + '].scope.key'">
<a-input v-model:value="record.key"></a-input>
</a-form-item>
</template>
<template v-if="column.key === 'condition'">
<a-form-item :name="'rules[' + i + '].scope.condition'">
<a-input v-model:value="record.condition"></a-input>
</a-form-item>
</template>
<template v-if="column.key === 'value'">
<a-form-item :name="'rules[' + i + '].scope.value'">
<a-input v-model:value="record.value"></a-input>
</a-form-item>
</template>
<template v-if="column.key === 'operation'">
<a-form-item :name="'rules[' + i + '].scope.operation'">
<a-button type="link" @click="deleteScopeItem(i, scopeItemIndex)">
删除</a-button
>
</a-form-item>
</template>
</template>
</a-table>
</a-form-item>
</a-card>
</a-space>
</template>
<template v-slot:form_gray="{ current }">
<a-space direction="vertical" size="middle">
<a-card v-for="(item, i) in current.form.rules">
<template #title>
{{ $t('applicationDomain.gray') }} {{ i + 1 }}
<div style="float: right">
<a-space>
<a-button danger type="dashed" @click="deleteGrayIsolation(i)">
<Icon style="font-size: 20px" icon="fluent:delete-12-filled"></Icon>
</a-button>
</a-space>
</div>
</template>
<a-form-item :name="'rules[' + i + '].name'" label="环境名称">
<a-input v-model:value="item.name"></a-input>
</a-form-item>
<a-form-item label="作用范围">
<a-space direction="vertical" size="middle">
<a-button type="primary" @click="addGrayScopeItem(i)"> 添加</a-button>
<a-table
style="width: 40vw"
:pagination="false"
:columns="grayTableColumns"
:data-source="item.scope"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'label'">
<a-form-item :name="'rules[' + i + '].scope.key'">
<a-input v-model:value="record.label"></a-input>
</a-form-item>
</template>
<template v-if="column.key === 'condition'">
<a-form-item :name="'rules[' + i + '].scope.condition'">
<a-input v-model:value="record.condition"></a-input>
</a-form-item>
</template>
<template v-if="column.key === 'value'">
<a-form-item :name="'rules[' + i + '].scope.value'">
<a-input v-model:value="record.value"></a-input>
</a-form-item>
</template>
<template v-if="column.key === 'operation'">
<a-form-item :name="'rules[' + i + '].scope.operation'">
<a-button type="link" @click="deleteGrayScopeItem(i, index)">
删除</a-button
>
</a-form-item>
</template>
</template>
</a-table>
</a-space>
</a-form-item>
</a-card>
</a-space>
</template>
</config-page>
</div>
</template>
<script setup lang="ts">
import { nextTick, onMounted, reactive, ref } from 'vue'
import ConfigPage from '@/components/ConfigPage.vue'
import { Icon } from '@iconify/vue'
import {
getAppGrayIsolation,
getAppLogSwitch,
getAppTrafficWeight,
updateAppGrayIsolation,
updateAppLogSwitch,
updateAppTrafficWeight
} from '@/api/service/app'
import { useRoute } from 'vue-router'
import { scrollIntoView } from '@/utils/UIUtil'
const route = useRoute()
const scopeColumns = [
{ key: 'key', title: 'label' },
{ key: 'condition', title: 'condition' },
{ key: 'value', title: 'value' },
{ key: 'operation', title: '操作' }
]
let options: any = reactive({
list: [
{
title: 'applicationDomain.operatorLog',
key: 'log',
form: {
logFlag: false
},
submit: (form: any) => {
return new Promise((resolve) => {
resolve(updateLogFlag(form?.logFlag))
})
},
reset(form: any) {
form.logFlag = false
}
},
{
title: 'applicationDomain.flowWeight',
key: 'flow',
ext: {
title: '添加权重配置',
fun(rules: any) {
addFlowWeight()
// 使用 nextTick 确保 DOM 已更新
nextTick(() => {
const index =
options.list.find((item: any) => item.key === 'flow')?.form.rules.length - 1
if (index >= 0) {
scrollIntoView('flowWeight' + index)
}
})
}
},
form: {
rules: [
{
weight: 10,
scope: []
}
]
},
submit(form: {}) {
return new Promise((resolve) => {
resolve(updateFlowWeight())
})
},
reset() {
getFlowWeight()
}
},
{
title: 'applicationDomain.gray',
key: 'gray',
ext: {
title: '添加灰度环境',
fun() {
addGrayIsolation()
}
},
form: {
rules: [
{
name: 'env-nam',
scope: {
key: 'env',
value: {
exact: 'gray'
}
}
}
]
},
submit(form: {}) {
return new Promise((resolve) => {
resolve(updateGrayIsolation())
})
},
reset() {
getGrayIsolation()
}
}
],
current: [0]
})
// Is execution log acquisition enabled?
const getLogFlag = async () => {
const res = await getAppLogSwitch(<string>route.params?.pathId)
console.log(res)
if (res?.code == 200) {
options.list.forEach((item: any) => {
if (item.key === 'log') {
item.form.logFlag = res.data.operatorLog
return
}
})
}
}
// Modify the execution log switch
const updateLogFlag = async (operatorLog: boolean) => {
const res = await updateAppLogSwitch(<string>route.params?.pathId, operatorLog)
console.log(res)
if (res?.code == 200) {
await getLogFlag()
}
}
// Obtain flow weight
const getFlowWeight = async () => {
const res = await getAppTrafficWeight(<string>route.params?.pathId)
if (res?.code == 200) {
options.list.forEach((item: any) => {
if (item.key === 'flow') {
item.form.rules = JSON.parse(JSON.stringify(res.data.flowWeightSets))
//Separate the traffic weight data sent by the backend.
item.form.rules.forEach((weight: any) => {
weight.scope.forEach((scopeItem: any) => {
scopeItem.label = scopeItem.key
scopeItem.condition = scopeItem.value ? Object.keys(scopeItem.value)[0] : ''
scopeItem.value = scopeItem.value ? Object.values(scopeItem.value)[0] : ''
})
})
}
})
}
}
// Modify flow weight
const updateFlowWeight = async () => {
let flowWeightSets: any = []
options.list.forEach((item: any) => {
if (item.key === 'flow') {
item.form.rules.forEach((weight: any) => {
let weightItemTem = {
weight: weight.weight,
scope: []
}
weight.scope.forEach((scopeItem: any) => {
const { key, value, condition } = scopeItem
let scopeItemTem = {
key: scopeItem.label || key,
value: {}
}
if (condition) {
scopeItemTem.value[condition] = value
}
weightItemTem.scope.push(scopeItemTem)
})
flowWeightSets.push(weightItemTem)
})
}
})
const res = await updateAppTrafficWeight(<string>route.params?.pathId, flowWeightSets)
if (res.code === 200) {
await getFlowWeight()
}
}
// add weight
const addFlowWeight = () => {
options.list.forEach((item: any) => {
if (item.key === 'flow') {
item.form.rules.push({
weight: 10,
scope: [
{
key: '',
condition: '',
value: ''
}
]
})
}
})
}
// delete weightItem
const deleteFlowWeight = (index: number) => {
options.list.forEach((item: any) => {
if (item.key === 'flow') {
item.form.rules.splice(index, 1)
}
})
}
// add scopeItem
const addScopeItem = (index: number) => {
options.list.forEach((item: any) => {
if (item.key === 'flow') {
let newData = {
key: '',
condition: '',
value: ''
}
// console.log("lhg",item.form.rules)
item.form.rules[index].scope.push(newData)
return
}
})
}
const deleteScopeItem = (weightIndex: number, scopeItemIndex: number) => {
options.list.forEach((item: any) => {
if (item.key === 'flow') {
item.form.rules[weightIndex].scope.splice(scopeItemIndex, 1)
}
})
}
const grayTableColumns = [
{ key: 'label', title: 'label', dataIndex: 'label' },
{ key: 'condition', title: 'condition', dataIndex: 'condition' },
{ key: 'value', title: 'value', dataIndex: 'value' },
{ key: 'operation', title: 'operation', dataIndex: 'operation' }
]
// Obtain GrayIsolation
const getGrayIsolation = async () => {
const res = await getAppGrayIsolation(<string>route.params?.pathId)
if (res?.code == 200) {
options.list.forEach((item: any) => {
if (item.key === 'gray') {
const graySets = res.data.graySets
if (graySets.length > 0) {
graySets.forEach((grayItem: any) => {
grayItem.scope.forEach((scopeItem: any) => {
scopeItem.label = scopeItem.key
scopeItem.condition = scopeItem.value ? Object.keys(scopeItem.value)[0] : ''
scopeItem.value = scopeItem.value ? Object.values(scopeItem.value)[0] : ''
})
})
}
item.form.rules = graySets
}
})
}
}
// Modify GrayIsolation
const updateGrayIsolation = async () => {
let graySets: any = []
options.list.forEach((item: any) => {
if (item.key === 'gray') {
item.form.rules.forEach((grayItem: any) => {
let grayItemTem = {
name: grayItem.name,
scope: []
}
grayItem.scope.forEach((scopeItem: any) => {
const { key, value, condition } = scopeItem
let scopeItemTem = {
key: scopeItem.label,
value: {}
}
if (condition) {
scopeItemTem.value[condition] = value
}
grayItemTem.scope.push(scopeItemTem)
})
graySets.push(grayItemTem)
})
}
})
const res = await updateAppGrayIsolation(<string>route.params?.pathId, graySets)
if (res.code === 200) {
await getGrayIsolation()
}
}
// add GrayIsolation
const addGrayIsolation = () => {
options.list.forEach((item: any) => {
if (item.key === 'gray') {
item.form.rules.push({
name: '',
scope: [
{
key: '',
condition: '',
value: ''
}
]
})
}
})
}
const addGrayScopeItem = (index: number) => {
options.list.forEach((item: any) => {
if (item.key === 'gray') {
let newData = {
key: '',
condition: '',
value: ''
}
// console.log("lhg",item.form.rules)
item.form.rules[index].scope.push(newData)
return
}
})
}
// delete GrayIsolationItem
const deleteGrayScopeItem = (weightIndex: number, scopeItemIndex: number) => {
options.list.forEach((item: any) => {
if (item.key === 'gray') {
item.form.rules[weightIndex].scope.splice(scopeItemIndex, 1)
}
})
}
// delete GrayIsolation
const deleteGrayIsolation = (index: number) => {
options.list.forEach((item: any) => {
if (item.key === 'gray') {
item.form.rules.splice(index, 1)
}
})
}
onMounted(() => {
getLogFlag()
getFlowWeight()
getGrayIsolation()
})
</script>
<style lang="less" scoped>
.__container_app_config {
.flowWeight-box {
width: 100%;
height: 100%;
//overflow: scroll;
}
}
</style>