Commit f36a8ad9 by wanglizhen

脱敏算法模块上传

parent aba361d4
src/assets/images/assetLibrary/default.png

3.16 KB | W: | H:

src/assets/images/assetLibrary/default.png

958 Bytes | W: | H:

src/assets/images/assetLibrary/default.png
src/assets/images/assetLibrary/default.png
src/assets/images/assetLibrary/default.png
src/assets/images/assetLibrary/default.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -27,8 +27,8 @@ const confirm = () => {
};
const cancel = () => {
editorName.value = JSON.parse(JSON.stringify(props.editor.rulename));
editorValue.value = JSON.parse(JSON.stringify(props.editor.expression));
editorName.value = props.editor.rulename ? JSON.parse(JSON.stringify(props.editor.rulename)) : '';
editorValue.value = props.editor.expression ? JSON.parse(JSON.stringify(props.editor.expression)) : '';
emit("cancel");
};
......@@ -58,9 +58,9 @@ const executeTest = () => {
// 测试关闭
const testCancel = () => {
testVisible.value = false;
testData.param = ''
testData.param = "";
testResult.value = "";
}
};
watch(
() => props.modelValue,
......@@ -75,8 +75,8 @@ watch(
watch(
() => props.editor,
(newVal) => {
editorName.value = JSON.parse(JSON.stringify(props.editor.rulename));
editorValue.value = JSON.parse(JSON.stringify(props.editor.expression));
editorName.value = props.editor.rulename ? JSON.parse(JSON.stringify(props.editor.rulename)) : '';
editorValue.value = props.editor.expression ? JSON.parse(JSON.stringify(props.editor.expression)) : '';
},
{ deep: true, immediate: true }
);
......@@ -84,9 +84,8 @@ watch(
<template>
<div>
<ModalPop v-model="props.modelValue" title="编辑器" @cancel="cancel">
<template #content>
<div class="title">算法名称 : {{ editorName }}</div>
<el-dialog title="编辑器" v-model="props.modelValue" :before-close="cancel" width="1100">
<div class="title">算法名称: <span style="color: rgba(33, 103, 217, 1);">{{ editorName }}</span></div>
<div class="content">
<div class="content_left">
<div class="content_left_tap">函数</div>
......@@ -107,17 +106,15 @@ watch(
</div>
</div>
</div>
<div style="display: flex; justify-content: center; padding-top: 20px;">
<el-button type="primary" style="width: 150px;" @click="testVisible = true">测试</el-button>
<el-button type="info" style="width: 150px;" @click="cancel">取消</el-button>
<el-button type="primary" style="width: 150px;" @click="confirm">确认</el-button>
<div style="display: flex; justify-content: center; padding: 60px 0 30px 0;">
<el-button type="primary" style="width: 80px;" @click="testVisible = true">测试</el-button>
<el-button style="width: 80px;" @click="cancel">取消</el-button>
<el-button type="primary" style="width: 80px;" @click="confirm">确认</el-button>
</div>
</template>
</ModalPop>
</el-dialog>
<!-- 测试 -->
<ModalPop v-model="testVisible" width="800px" title="测试" @cancel="testCancel">
<template #content>
<el-dialog title="测试" v-model="testVisible" :before-close="testCancel" width="1100">
<el-form-item label="输入参数$value的值:" label-width="180px" prop="expression">
<div style="width: 100%;display: flex; justify-content: center;">
<el-input placeholder="输入参数$value的值" v-model="testData.param" />
......@@ -130,13 +127,14 @@ watch(
<div style="display: flex; justify-content: center; padding-top: 20px;">
<el-button type="primary" style="width: 150px;" @click="testCancel">关闭</el-button>
</div>
</template>
</ModalPop>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.title {
margin-bottom: 20px;
padding-left: 22px;
height: 32px;
line-height: 32px;
}
......
<script setup lang="ts" name="collapseView">
import { ref, computed } from 'vue'
import { Collapse, Panel } from 'view-ui-plus';
import { ref, computed } from "vue";
import { Collapse, Panel } from "view-ui-plus";
const emit = defineEmits(["add", "view", "mainDeletion", "default", "childDelete", "change"]);
const emit = defineEmits([
"add",
"view",
"mainDeletion",
"default",
"childDelete",
"change",
]);
const props = defineProps<{
list: Array<any>;
fatherIndex: Array<any>;
currentId: Array<any>;
}>();
const listData = computed(() => props.list)
const listData = computed(() => props.list);
const activeId = computed(() => props.currentId);
const fatherIndex = computed(() => props.fatherIndex);
const childIndex = ref(null);
// 新增
const addClick = (item) => {
emit("add",item);
}
emit("add", item);
};
// 查看
const viewClick = (item) => {
emit("view",item);
}
const viewClick = (item, index) => {
const { isView, list } = item
if (isView) {
emit("view", item);
} else {
if(list.length <= 0) return
emit("view", index);
}
};
// 主删除
const mainDeletion = (item) => {
emit("mainDeletion",item);
}
emit("mainDeletion", item);
};
// 子级监听
const itemClick = (item1, item2) => {
const itemClick = (item,index) => {
childIndex.value = index
const parentItem = listData.value[fatherIndex.value]
const data = {
parentItem: item1,
item: item2
}
emit("change",data);
}
parentItem: parentItem,
item: item,
};
emit("change", data);
};
// 默认项
const defaultClick = (item) => {
emit("default",item);
}
emit("default", item);
};
// 子删除
const childDelete = (item) => {
emit("childDelete",item);
}
emit("childDelete", item);
};
</script>
<template>
<Collapse simple>
<Panel :name="item.name" v-for="(item, index) in listData" :key="index">
{{ item.dataarea }}
<span class="collapse-item__btns--box">
<el-icon color="rgb(253, 84, 81)" :size="16" v-if="item.isAdd" @click.stop="addClick(item)">
<circle-plus-filled />
<div class="collapse">
<div class="fatherLevel">
<el-scrollbar style="width: 100%;height: 100%;">
<div class="panel" :class="fatherIndex === index ? 'active' : ''" v-for="(item, index) in listData" :key="index" @click.stop="viewClick(item,index)">
<div class="add" v-if="item.isAdd" @click.stop="addClick(item)">
<el-icon :size="10" color="#fff">
<plus />
</el-icon>
<el-icon color="#2c9ef7" :size="16" v-if="item.isView" @click.stop="viewClick(item)" style="margin-left: 8px;">
<View />
</div>
<div class="name">{{ item.dataarea }}</div>
<el-icon color="rgba(212, 48, 48, 1)" :size="16" v-if="item.isDelete" @click.stop="mainDeletion(item)"
style="margin-right: 17px;">
<circle-close-filled />
</el-icon>
<el-icon color="rgb(13, 215, 141)" :size="16" v-if="item.isDelete" @click.stop="mainDeletion(item)" style="margin-left: 8px;">
<delete />
<el-icon :size="14" color="rgba(53, 64, 79, 1)" v-if="item.list && item.list.length > 0">
<arrow-right />
</el-icon>
</span>
<template #content>
<div>
<div class="rule__item" v-for="(itemTwo, i) in item.list" :key="i" @click="itemClick(item,itemTwo)">
<span>{{ itemTwo.name }}</span>
<div class="default" v-if="itemTwo.defaulttype === '1'"></div>
<div class="rule__item__btns">
<el-icon color="#2c9ef7" :size="15" v-if="itemTwo.isCheck && itemTwo.defaulttype !== '1'" @click.stop="defaultClick(itemTwo)" style="margin-right: 8px;" >
<circle-check />
</div>
</el-scrollbar>
</div>
<div class="childLevel" v-if="listData[fatherIndex] && listData[fatherIndex].list.length > 0">
<el-scrollbar style="width: 100%;height: 100%;padding: 0 9px;">
<div class="panel" :class="activeId === item.id ? 'active' : ''" v-for="(item, index) in listData[fatherIndex].list" :key="index" @click.stop="itemClick(item,index)" >
<div class="line"></div>
<div class="name">{{ item.name }}</div>
<div class="default" v-if="item.defaulttype === '1'"></div>
<div class="btns" :style="item.defaulttype === '1' ? 'margin-right: 30px;':''">
<el-icon color="rgba(33, 103, 217, 1)" v-if="item.isCheck && item.defaulttype !== '1'" :size="16" @click.stop="defaultClick(item)" style="margin-right: 10px;">
<circle-check-filled />
</el-icon>
<el-icon color="rgb(13, 215, 141)" :size="15" v-if="itemTwo.isDelete" @click.stop="childDelete(itemTwo)">
<delete />
<el-icon color="rgba(212, 48, 48, 1)" v-if="item.isDelete" :size="16" @click.stop="childDelete(item)">
<circle-close-filled />
</el-icon>
</div>
</div>
</el-scrollbar>
</div>
</div>
</template>
</Panel>
</Collapse>
</template>
<style lang="scss" scoped>
:deep(.ivu-collapse-content) {
padding: 0 0 0 14px;
}
:deep(.ivu-collapse-content-box) {
padding-bottom: 0;
}
.ivu-collapse-header {
padding-left: 0;
}
.ivu-collapse-simple {
border: none !important;
.ivu-collapse-item {
position: relative;
border: none !important;
.collapse {
width: 100%;
height: 100%;
display: flex;
.fatherLevel {
width: 282px;
height: 100%;
.panel {
padding-right: 28px;
width: 100%;
height: 50px;
border-bottom: 1px dashed rgba(186, 193, 204, 1);
display: flex;
align-items: center;
cursor: pointer;
.add {
margin-left: 18px;
width: 16px;
height: 16px;
border-radius: 4px;
background: rgba(133, 147, 167, 1);
display: flex;
align-items: center;
justify-content: center;
}
.ivu-collapse-item:before {
content: " ";
width: calc(100% - 14px);
height: 1px;
background: #f3f5fa;
position: absolute;
top: 0;
left: 14px;
.name {
flex: 1;
margin-left: 12px;
font-size: 14px;
line-height: 22px;
color: rgba(53, 64, 79, 1);
}
.ivu-collapse-item:first-child:before {
height: 0;
}
}
.collapse-item__btns--box {
position: absolute;
right: 4px;
}
.rule__item {
.active{
background: rgba(235, 242, 255, 1);
}
}
.childLevel {
padding: 1px 0;
flex: 1;
height: 100%;
border-radius: 8px;
background: rgba(235, 242, 255, 1);
overflow: hidden;
.panel {
position: relative;
padding-left: 20px;
cursor: pointer;
border-bottom: 1px solid #f3f5fa;
height: 30px;
line-height: 30px;
width: 100%;
height: 50px;
border-bottom: 1px dashed rgba(186, 193, 204, 1);
display: flex;
align-items: center;
justify-content: space-between;
&__btns {
padding-top: 7px;
padding-right: 28px;
font-size: 14px;
line-height: 22px;
color: rgba(53, 64, 79, 1);
border-radius: 8px;
cursor: pointer;
.line {
width: 2.26px;
height: 20px;
border-radius: 8px;
background: rgba(33, 103, 217, 1);
opacity: 0;
}
.name {
flex: 1;
margin-left: 19px;
font-size: 14px;
font-weight: 400;
letter-spacing: 0px;
line-height: 22px;
color: rgba(53, 64, 79, 1);
}
.btns {
margin-right: 14px;
line-height: 14px;
display: none;
line-height: 30px;
}
.default {
position: absolute;
top: 0;
right: 0;
width: 28px;
height: 30px;
background: url("@/assets/images/assetLibrary/default.png") no-repeat
center center;
top: 7px;
right: 4px;
width: 21.93px;
height: 22.24px;
background: url("@/assets/images/assetLibrary/default.png") no-repeat center
center;
background-size: 100% 100%;
pointer-events: none;
}
}
.rule__item:hover {
color: #21333f;
background: #f3f5fa;
.rule__item__btns {
.active{
background: #fff;
.line{
opacity: 1;
}
.name{
color: rgba(33, 103, 217, 1);
}
.btns{
display: block;
}
}
}
}
</style>
\ No newline at end of file
<script setup lang="ts" name="AddEdit">
import { ref, toRefs, reactive, getCurrentInstance } from 'vue'
import FormGroup from './modules/formGroup.vue'
import img from '@/assets/images/assetLibrary/index.js'
const emit = defineEmits(["update:modelValue", "confirm", "cancel"])
const props = defineProps<{
modelValue: boolean;
}>();
const step = ref('edit') // select edit
const selectData = reactive({
name: '',
type: ''
})
const listData = ref([
{
title: '关系型数据库',
type: 1,
list: [
{
name: 'MYSQL',
icon: img.MYSQL,
},
{
name: 'ORACLE',
icon: img.ORACLE,
},
{
name: 'POSTGRESQL',
icon: img.POSTGRESQL,
},
// {
// name: 'DB2',
// icon: img.DB2,
// },
{
name: 'MSSQLSERVER',
icon: img.MSSQLSERVER,
},
// {
// name: 'MARIADB',
// icon: img.MARIADB,
// },
// {
// name: 'GBASE8S',
// icon: img.GBASE8S,
// },
{
name: 'KINGBASE',
icon: img.KINGBASE,
},
{
name: 'DM',
icon: img.DM,
},
// {
// name: 'GREENPLUM',
// icon: img.GREENPLUM,
// },
// {
// name: 'GAUSS',
// icon: img.GAUSS,
// },
// {
// name: 'OCEANBASE',
// icon: img.OCEANBASE,
// },
// {
// name: 'GAUSSDB',
// icon: img.GAUSSDB,
// }
]
},
// {
// title: 'NoSQL',
// type: 2,
// list: [
// {
// name: 'ES',
// icon: img.ES,
// },
// {
// name: 'MONGODB',
// icon: img.MONGODB,
// }
// ]
// },
// {
// title: '消息队列',
// type: 3,
// list: [
// {
// name: 'KAFKA',
// icon: img.KAFKA,
// }
// ]
// }
])
const hadoopData = reactive({
index: null,
list: [
{
name: 'Apache',
icon1: img.apache1,
icon2: img.apache2,
list: [
{
name: 'HIVE',
icon: img.HIVE,
type: 4,
}
]
},
{
name: 'CLOUDERA',
icon1: img.cloudera1,
icon2: img.cloudera2,
list: [
{
name: 'HIVE',
icon: img.HIVE,
type: 4,
}
]
},
{
name: '星环',
icon1: img.star1,
icon2: img.star2,
list: [
{
name: 'HIVE_TDH',
icon: img.HIVE,
type: 4,
}
]
}
]
})
// hadoop事件
const hadoopClick = (index) => {
hadoopData.index = index
}
// 新增
const editTo = (item,type) => {
// selectData.name = item.name
// selectData.type = type
// step.value = 'edit'
}
// 新增回调
const modalConfirm = () => {
console.log('modalConfirm')
}
</script>
<template>
<el-dialog title="提示" v-model="modelValue" width="1100">
</el-dialog>
<div class="app-container scroller">
<PageTitle back @back="emit('page', 'list')">
<template #title>
<span id="badDebt" class="title-icon">
新增数据源
<PageTour tourType="badDebt" />
</span>
</template>
</PageTitle>
<div class="app-container__body">
<div v-if="step === 'select'">
<div class="listBox" v-for="(item,index) in listData" :key="index">
<div class="title">{{ item.title }}</div>
<div class="img-warpper">
<img class="img" :src="liItem.icon" :alt="liItem.name" @click="editTo(liItem, item.type)" v-for="(liItem, i) in item.list" :key="i">
</div>
</div>
<!-- <div class="title">Hadoop品牌:<span class="data-base-name">{{ hadoopData.index !== null ? hadoopData.list[hadoopData.index].name : '' }}</span></div>
<div style="display: inline-block;">
<div class="hadoop-list-box">
<div class="hadoop-item-box" :class="hadoopData.index === index ? 'hadoop-item-box-active' : ''" v-for="(item,index) in hadoopData.list" :key="index" @click="hadoopClick(index)">
<img :src="item.icon1" alt="">
<img :src="item.icon2" alt="" class="hidden-img">
<div class="name">
<span>{{ item.name }}</span>
<div class="bar"></div>
</div>
</div>
</div>
</div>
<div style="padding-top: 10px;color: #7a8495;">*点击图标切换Hadoop品牌</div>
<div v-if="hadoopData.index !== null" style="color: rgb(102, 102, 102); font-size: 16px; font-weight: bold; padding: 10px 0px;">Hadoop</div>
<div class="img-warpper" v-if="hadoopData.index !== null">
<img class="img" :src="item.icon" :alt="item.name" @click="editTo(item, item.type)" v-for="(item, index) in hadoopData.list[hadoopData.index].list" :key="index">
</div> -->
</div>
<div v-if="step === 'edit'" style="padding: 30px 150px;">
<div style="padding-bottom: 20px;">
<span style="color: rgb(102, 102, 102);">数据源类型:</span>
<span class="source-title">{{ selectData.name }}</span>
</div>
<FormGroup page="add" :title="selectData.name" :type="selectData.type" @cancel="step = 'select'" @confirm="modalConfirm" />
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.title {
color: #21333f;
font-size: 16px;
line-height: 20px;
font-weight: 700;
padding: 10px 0 10px 12px;
.data-base-name{
color: #2c9ef7;
font-size: 20px;
font-weight: 400;
}
}
.img-warpper {
background-color: #f3f5fa;
padding: 7.5px;
margin-top: 24px;
margin-bottom: 50px;
margin-left: 12px;
line-height: 1;
.img {
width: 132px;
font-size: 0;
margin: 0 10px 10px 0;
cursor: pointer;
}
}
.hadoop-list-box {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-ms-flex-pack: distribute;
justify-content: space-around;
background: #f1f3f5;
padding: 10px;
.hadoop-item-box {
padding: 8px;
background: #fff;
cursor: pointer;
position: relative;
-webkit-transition: -webkit-box-shadow 0.3s;
transition: -webkit-box-shadow 0.3s;
transition: box-shadow 0.3s;
transition: box-shadow 0.3s, -webkit-box-shadow 0.3s;
margin-right: 16px;
img {
font-size: 0;
vertical-align: bottom;
width: 132px;
}
.hidden-img {
position: absolute;
left: 8px;
opacity: 0;
-webkit-transition: opacity 0.5s;
transition: opacity 0.5s;
}
.name {
height: 20px;
line-height: 20px;
text-align: center;
margin-top: 8px;
position: relative;
.bar {
position: absolute;
opacity: 0;
background-color: #1f85df;
height: 2px;
width: 0;
-webkit-transition: all 0.2s;
transition: all 0.2s;
left: 0;
bottom: -4px;
}
}
}
.hadoop-item-box-active{
-webkit-box-shadow: 0 0 10px #888;
box-shadow: 0 0 10px #888;
.hidden-img{
opacity: 1;
}
.name{
.bar{
opacity: 1;
width: 132px;
left: 0;
}
}
}
.hadoop-item-box:hover {
-webkit-box-shadow: 0 0 10px #888;
box-shadow: 0 0 10px #888;
.hidden-img {
opacity: 1;
}
}
}
.source-title{
font-size: 18px;
font-weight: 700;
color: #1f85df;
}
</style>
\ No newline at end of file
......@@ -9,9 +9,9 @@ import ModalPop from "@/components/EditPop/ModalPop.vue"
import { query, del } from '@/api/ruleConfig/algorithm.js'
const splitNum = ref(0.31) // 左右分割比例
const collapseList = ref([])
const rulenameList = ref([]) // 规则名称列表
const fatherIndex = ref(0) // 父级索引
const searchValue = ref('')
const data = reactive({
......@@ -58,14 +58,15 @@ const getCollapse = (type) => {
if (type === 'edit') return
if (collapseList.value.length <= 0) return
if (collapseList.value[0].ruleList.length > 0) {
fatherIndex.value = 0
editForm.value = collapseList.value[0].ruleList[0]
} else {
fatherIndex.value = null
const { id } = collapseList.value[0]
editForm.value = {
dataarea_id: id
}
}
})
}
......@@ -74,6 +75,12 @@ const modalPopCancel = () => {
modalPopShow.value = false
}
// 一级点击
const collapseView = (index) => {
console.log(index)
fatherIndex.value = index
}
// 新增算法
const collapseAdd = (item) => {
// console.log('添加事件', item)
......@@ -139,83 +146,157 @@ onMounted(() => {
</script>
<template>
<div class="app-container scroller">
<PageTitle>
<template #title>
脱敏算法
</template>
</PageTitle>
<div class="app-container__body">
<Split v-model="splitNum">
<template #left>
<div class="demo-split-pane" style="padding: 0 38px 10px 0;width: 100%;overflow: auto;height: 100%;display: flex;flex-direction: column;">
<el-input class="mb20" v-model="searchValue" placeholder="脱敏规则搜索">
<template #suffix>
<el-icon style="vertical-align: middle;cursor: pointer;" @click="getCollapse">
<div class="pageTitle">
<img class="icon" src="@/assets/images/ruleConfig/algorithmPage.png" alt="">
<span>脱敏算法</span>
</div>
<div class="box">
<div class="left">
<el-input v-model="searchValue" placeholder="脱敏规则搜索" style="width: 369px;margin-bottom: 15px;">
<template #prefix>
<el-icon>
<search />
</el-icon>
</template>
<template #append>
<el-button icon="search" class="searchBut" @click="getCollapse">搜索</el-button>
</template>
</el-input>
<el-scrollbar style="width: 100%;flex: 1;padding-right: 38px;">
<CollapseView :list="collapseList" @add="collapseAdd" @childDelete="collapseDelete"
@change="collapseChange" />
</el-scrollbar>
<div class="collapseView">
<CollapseView :list="collapseList" :fatherIndex="fatherIndex" :currentId="editForm.id" @add="collapseAdd"
@childDelete="collapseDelete" @view="collapseView" @change="collapseChange" />
</div>
</template>
<template #right>
<div class="demo-split-pane">
<div class="right">
<div class="right-title">
<el-icon>
<info-filled />
</el-icon>
<span style="margin-left: 5px;">脱敏规则</span>
</div>
<div class="right">
<div class="line"></div>
<div style="padding: 26px 28px 0 28px;">
<DividerTitle title-name="脱敏规则" />
<div class="right-content">
<formModule :itemData="editForm" :nameList="rulenameList" type="edit" @confirm="formModuleConfirm" />
</div>
</div>
</div>
</template>
</Split>
</div>
</div>
<!-- 提示框 -->
<Modal v-model="modalData.show" :icon="modalData.icon" :cancel="modalData.cancel" :text="modalData.text"
@confirm="modalConfirm"></Modal>
<!-- 新增算法 -->
<ModalPop v-model="modalPopShow" title="新增算法" @cancel="modalPopCancel">
<template #content>
<el-dialog title="新增算法" v-model="modalPopShow" :before-close="modalPopCancel" width="900">
<div style="padding: 30px 120px;">
<formModule v-if="modalPopShow" :itemData="addForm" :nameList="rulenameList" type="add" @cancel="modalPopCancel"
@confirm="formModuleConfirm" />
</template>
</ModalPop>
@confirm="formModuleConfirm"/>
</div>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.app-container__body {
height: calc(
100vh - var(--navbar-height) - var(--container-pd) - var(--container-pd)
) !important;
.right {
padding: 6px 10px 10px;
height: 100%;
&-title {
padding: 0px 0px 10px 10px;
padding: 20px 0 0 0;
.pageTitle {
margin-bottom: 20px;
display: flex;
align-items: center;
font-weight: 700;
color: #515a6e;
font-size: 16px;
font-weight: 500;
letter-spacing: 0px;
line-height: 22px;
color: rgba(53, 64, 79, 1);
.icon {
margin-right: 6px;
width: 16px;
height: 16px;
}
}
.box {
display: flex;
flex: 1;
overflow: hidden;
.left {
margin-right: 30px;
width: 565px;
overflow: auto;
height: 100%;
display: flex;
flex-direction: column;
.searchBut {
height: 40px;
background: var(--el-color-primary);
color: var(--el-color-white);
border-radius: 0px 5px 5px 0px;
}
.collapseView {
width: 100%;
flex: 1;
overflow: hidden;
}
}
.right {
flex: 1;
height: 100%;
background: rgba(255, 255, 255, 1);
.line {
width: 100%;
height: 2px;
border-radius: 5px 5px 0px 0px;
background: linear-gradient(
90deg,
rgba(33, 103, 217, 1) 0%,
rgba(17, 200, 250, 1) 34.03%,
rgba(33, 103, 217, 1) 64.58%,
rgba(48, 128, 255, 1) 100%
);
}
&-content {
padding: 10px 0px;
width: 80%;
margin: 20px auto;
width: 100%;
.openEditor {
position: absolute;
bottom: 0;
right: 0;
}
:deep(.formBox) {
border-radius: 5px;
background: #ebebeb;
border: 1px solid rgba(29, 178, 245, 1);
overflow: hidden;
.el-form-item__content {
margin-left: 1px;
background: #f5fcff;
}
.el-form-item__label {
height: 40px;
line-height: 40px;
background: #f5fcff;
color: rgba(148, 148, 148, 1);
}
.el-form-item {
margin-bottom: 1px;
}
.el-input {
height: 40px;
line-height: 40px;
}
.is-disabled {
background: #f5fcff;
.el-input__wrapper {
background: #f5fcff;
box-shadow: none;
border-radius: 0;
}
.el-input__inner {
-webkit-text-fill-color: rgba(53, 64, 79, 1);
}
}
.el-form-item__error {
top: 30% !important;
left: auto !important;
right: 89px !important;
}
}
}
&-btn {
padding: 20px 20px 20px 100px;
......@@ -223,5 +304,6 @@ onMounted(() => {
justify-content: center;
}
}
}
}
</style>
\ No newline at end of file
......@@ -39,10 +39,10 @@ const { form, rules } = toRefs(data);
const editorShow = ref(false);
const readOnly = ref(true);
const editor = ref({
rulename: '',
expression: ''
rulename: "",
expression: "",
});
const rulenameList = ref([])
const rulenameList = ref([]);
const formRef = ref<FormInstance>();
// 重置
......@@ -61,7 +61,7 @@ const openEditor = () => {
editorShow.value = true;
editor.value = {
rulename: form.value.rulename,
expression: form.value.expression
expression: form.value.expression,
};
};
......@@ -109,7 +109,7 @@ const saveFunc = () => {
const validateRulename = (rule, value, callback) => {
const state = rulenameList.value.includes(value);
if (state) {
callback(new Error('算法名称已存在'));
callback(new Error("算法名称已存在"));
} else {
callback();
}
......@@ -138,8 +138,10 @@ watch(
if (props.itemData) {
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
if (props.type === 'edit') {
rulenameList.value = rulenameList.value.filter(item => item !== data.rulename)
if (props.type === "edit") {
rulenameList.value = rulenameList.value.filter(
(item) => item !== data.rulename
);
}
}
},
......@@ -151,8 +153,10 @@ watch(
(newVal) => {
rulenameList.value = props.nameList;
const data = JSON.parse(JSON.stringify(props.itemData));
if (props.type === 'edit' && data) {
rulenameList.value = rulenameList.value.filter(item => item !== data.rulename)
if (props.type === "edit" && data) {
rulenameList.value = rulenameList.value.filter(
(item) => item !== data.rulename
);
}
},
{ deep: true, immediate: true }
......@@ -161,30 +165,31 @@ watch(
<template>
<div>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" :disabled="readOnly">
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px" :disabled="readOnly">
<div class="formBox">
<el-form-item label="算法名称" prop="rulename" required
:rules="[{ required: true, message: '请输入算法名称', trigger:'blur' },{ required: true, validator: validateRulename, trigger:'blur' }]">
<el-input v-model="form.rulename"></el-input>
</el-form-item>
<el-form-item label="表达式" prop="expression" required>
<el-input type="textarea" rows="8" v-model="form.expression"></el-input>
<el-button class="openEditor" type="primary" @click="openEditor">打开编辑器</el-button>
<el-input v-model="form.expression"></el-input>
<el-button class="openEditor" type="text" @click="openEditor" v-if="!readOnly">打开编辑器</el-button>
</el-form-item>
<el-form-item label="默认规则">
<Switch true-value="1" false-value="0" v-model="form.defaluttype" :disabled="readOnly">
<template #open>
<span></span>
</template>
<template #close>
<span></span>
</template>
</Switch>
<div class="is-disabled" v-if="readOnly" style="width: 100%;height: 100%;">
<div class="el-input__wrapper" style="height: 100%;">{{ form.defaluttype === '1' ? '是':'否' }}</div>
</div>
<el-radio-group v-model="form.defaluttype" v-if="!readOnly" style="margin-left: 10px;">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-form>
<div class="btn">
<el-button type="primary" style="width: 150px;" @click="readOnly = false" v-if="readOnly">编辑</el-button>
<el-button type="info" style="width: 150px;" @click="cancel" v-if="!readOnly">取消</el-button>
<el-button type="primary" style="width: 150px;" @click="confirm" v-if="!readOnly">确认</el-button>
<el-button type="primary" style="width: 80px;" @click="readOnly = false" v-if="readOnly">编辑</el-button>
<el-button type="primary" style="width: 80px;" @click="confirm" v-if="!readOnly">确认</el-button>
<el-button style="width: 80px;" @click="cancel" v-if="!readOnly">取消</el-button>
</div>
<ExpressionEditor v-model="editorShow" :editor="editor" @cancel=" editorShow = false" @confirm="formConfirm" />
......@@ -195,11 +200,17 @@ watch(
.openEditor {
position: absolute;
bottom: 0;
right: 0;
top: 0;
right: 10px;
margin: auto;
text-decoration: underline;
}
.btn {
padding: 20px;
padding: 40px 20px 20px 20px;
display: flex;
justify-content: center;
}
:deep(.el-input__inner) {
height: 34px;
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论