Commit 75b008ed by 周海峰

Merge branch 'master' of https://code.palacesun.com/wuchao/nse-ui

parents 2b60e6ce 60a27752
......@@ -12,3 +12,59 @@ export function selectDataProject(data) {
data: data
})
}
export function checkProjectNum(data) {
return request({
url: '/core/tdataproject/checkProjectNum',
method: 'post',
data: data
})
}
export function getdatascopeprojectlist(data) {
return request({
url: '/core/datascopeproject/getdatascopeprojectlist',
method: 'post',
data: data
})
}
export function checkDatasystemName(data) {
return request({
url: '/core/tdataproject/checkDatasystemName',
method: 'post',
data: data
})
}
export function checkDatasystem(data) {
return request({
url: '/core/tdataproject/checkDatasystem',
method: 'post',
data: data
})
}
export function queryByEditSort(data) {
return request({
url: '/core/tdatasource/queryByEditSort',
method: 'post',
data: data
})
}
export function selectProDataSource(data) {
return request({
url: '/core/tdatasource/selectProDataSource',
method: 'post',
data: data
})
}
export function queryShemas(data) {
return request({
url: '/core/searchsensitivedata/queryShemas',
method: 'post',
data: data
})
}
......@@ -12,3 +12,55 @@ export function query(query) {
params: query
})
}
/**
* 脱敏算法 - 新增算法
* @param {*} data
* @returns
*/
export function save(data) {
return request({
url: '/core/desensitizationrule/save',
method: 'post',
data: data
})
}
/**
* 脱敏算法 - 获取函数列表
* @param {*} query
* @returns
*/
export function queryFunctionList(query) {
return request({
url: '/core/desensitizationAlgorithm/queryFunctionList',
method: 'get',
params: query
})
}
/**
* 脱敏算法 - 删除算法
* @param {*} data
* @returns
*/
export function del(data) {
return request({
url: '/core/desensitizationrule/delete',
method: 'post',
data: data
})
}
/**
* 脱敏算法 - 测试算法
* @param {*} data
* @returns
*/
export function test(data) {
return request({
url: '/core/desensitizationrule/test',
method: 'post',
data: data
})
}
\ No newline at end of file
......@@ -104,3 +104,32 @@ export function delValue(data) {
})
}
/**
* 知识库 - 导出excel
* @param {*} data
* @returns
*/
export function exportExcel(data) {
return request({
url: '/core/dictionaryexcel/export',
method: 'post',
data: data,
responseType: 'blob'
})
}
/**
* 知识库 - 导入
* @param {*} data
* @returns
*/
export function importfile(data) {
return request({
url: '/core/dictionaryexcel/importfile',
method: 'post',
data: data,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
\ No newline at end of file
import request from '@/utils/request'
/**
* 加密规则 - 查询加密规则列表
* @param {*} query
* @returns
*/
export function query(query) {
return request({
url: '/core/encryption/query',
method: 'get',
params: query
})
}
/**
* 加密规则 - 查询加密方式列表
* @param {*} query
* @returns
*/
export function initEncryptionTypeList(query) {
return request({
url: '/core/encryption/initEncryptionTypeList',
method: 'get',
params: query
})
}
/**
* 加密规则 - 获取字典分类
* @param {*} query
* @returns
*/
export function getDictinaryTypes(query) {
return request({
url: '/core/dictionary/getDictinaryTypes',
method: 'get',
params: query
})
}
/**
* 加密规则 - 新增加密分类
* @param {*} data
* @returns
*/
export function save(data) {
return request({
url: '/core/encryption/save',
method: 'post',
data: data
})
}
/**
* 加密规则 - 删除加密分类
* @param {*} data
* @returns
*/
export function deleteType(data) {
return request({
url: '/core/encryption/delete',
method: 'post',
data: data
})
}
/**
* 加密规则 - 密钥生成
* @param {*} query
* @returns
*/
export function getRandomValue(query) {
return request({
url: '/core/encryption/getRandomValue',
method: 'get',
params: query
})
}
/**
* 加密规则 - 测试
* @param {*} data
* @returns
*/
export function testEncryption(data) {
return request({
url: '/core/encryption/testEncryption',
method: 'post',
data: data
})
}
/**
* 加密规则 - 新增密钥
* @param {*} data
* @returns
*/
export function saveSecretKey(data) {
return request({
url: '/core/encryption/saveSecretKey',
method: 'post',
data: data
})
}
/**
* 加密规则 - 删除密钥
* @param {*} data
* @returns
*/
export function delSecretKey(data) {
return request({
url: '/core/encryption/delSecretKey',
method: 'post',
data: data
})
}
<script setup lang="ts" name="CustomUpload">
import { ref, getCurrentInstance, computed, onMounted, watch } from 'vue'
import { getToken } from '@/utils/auth'
import { ElMessage, ElMessageBox } from 'element-plus'
import { parseTime } from '@/utils/ruoyi'
import axios from 'axios'
// import { filePreview } from '@/api/preview'
const { proxy } = getCurrentInstance() as any
// <CustomUpload v-model:file-list="fileList"/>
// const fileList = ref([
// {
// name: 'food.jpeg',
// fileSize: '23423',
// fileType: 'img',
// url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
// createTime: '2024-01-24 16:31'
// },
// {
// name: 'food.jpeg',
// fileSize: '23423',
// fileType: 'img',
// url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
// createTime: '2024-01-24 16:31'
// }
// ])
type IFileList = Array<any> | null | undefined
const emit = defineEmits<{
'update:fileList': [fileList: IFileList],
'onSuccess'
}>()
const props = withDefaults(defineProps<{
fileList: IFileList
buttonPermission?: Array<string>
needType?: boolean
needSize?: boolean
needTime?:boolean
needStatus?:boolean,
acceptTypeList?:Array<string>
limit?:number,
prompt?:string,
uploadType?:number,
listShow?: boolean
}>(), {
buttonPermission: () => ['upload', 'delete'],
needType: true,
needSize: true,
needTime: true,
needStatus: true,
limit: 100,
prompt: '点击或将文件拖拽到此处上传',
uploadType: 1,
listShow: false,
// acceptTypeList: () => ['png', 'jpg', 'doc', 'docx', 'pdf']
})
const uploadFileUrl = (props.uploadType === 1 ? ref(import.meta.env.VITE_APP_BASE_API + '/core/dictionaryexcel/importfile') : ref(import.meta.env.VITE_APP_BASE_API + '/eo/TTenantContractlabelTemplateController/uploadTemporary')) // 上传文件服务器地址
const headers = ref({
Token: getToken(),
'from-source': 'platformUi',
'Content-Type': 'mulipart/form-data'
})
// const FileList = ref<Array<any>>([])
const FileList = computed({
get() {
return props.fileList
},
set(val: any) {
// console.log('fileList computed', val)
emit('update:fileList', val)
}
})
const uploadLoading = computed(() => {
if (FileList.value != null && FileList.value.some(item => item.status === 'uploading')) {
return true
}
return false
})
// const fileListlengthCompute = computed(() => {
// return props.fileList.length
// })
// watch(() => props.fileList, (val: IFileList) => {
// console.log('props.fileList', val)
// if (!val) {
// FileList.value = []
// return
// }
// FileList.value = JSON.parse(JSON.stringify(props.fileList))
// }, { deep: true, immediate: true })
// watch(fileListlengthCompute, (val) => {
// console.log(val)
// if (val === 0) {
// emit('update:fileList', [])
// FileList.value = []
// }
// }, { deep: true, immediate: true })
function updateFileList() {
emit('onSuccess')
// emit('update:fileList', FileList.value.filter(item => item.status === 'success'))
}
function beforeUpload(file) {
console.log('beforeUpload', file)
let type = file.name.split('.')
type = type[type.length - 1]
if (props.acceptTypeList.indexOf(type) >= 0) {
const list = {}
for (const key in file) {
list[key] = file[key]
}
// status:uploading、success、error 文件上传状态
// progress 文件上传进度
FileList.value.push({ ...list, progress: 0, status: 'uploading' })
// updateFileList()
httpRequest(file, parms => {
showProgress(list, parms)
})
// 阻止 el-upload的默认上传
return false
}
proxy.$modal.msgError(`文件格式不正确, 请上传${props.acceptTypeList.join('/')}格式文件!`)
return false
}
async function httpRequest(file, callback) {
let formData = new FormData()
formData.append('fileUpload', file)
let progress = 0
axios({
headers: headers.value,
method: 'post',
url: uploadFileUrl.value,
data: formData,
onUploadProgress: progressEvent => { // 获取文件上传进度 axios自带的
progress = (progressEvent.loaded / progressEvent.total * 100) | 0
callback({ progress, status: 'uploading' })
}
}).then((res) => { // 成功状态
// console.log('res', res)
let data = res.data.data
proxy.$emit('uploadSuccessCallback', data)
if (props.uploadType === 1) {
callback({ progress, status: 'success', url: data.url, id: '' })
} else {
callback({ progress, status: 'success', url: data.url, id: data.id })
updateFileList()
}
}).catch(() => { // 失败状态
callback({ progress, status: 'error' })
})
}
function showProgress(file, parms) {
const { progress, status, url } = parms
const arr = [...FileList.value].map(items => {
if (items.uid === file.uid) {
items.progress = progress
items.status = status
items.url = url
items.fileType = file.type
items.fileSize = file.size
items.createTime = parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}')
items.id = parms.id
}
return items
})
FileList.value = [...arr]
// updateFileList()
}
function handleAvatarSuccess(response, uploadFile) {
console.log(response)
console.log(uploadFile)
}
function handlePreviewFile(file) {
console.log(file)
filePreview(file.url)
}
function handleDownFile(file) {
const fileUrl = file.url // 文件的URL地址
fetch(fileUrl)
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.setAttribute('download', file.name)
document.body.appendChild(link)
link.click()
})
.catch(error => {
console.error(error)
})
}
function handleDeleteFile(index) {
FileList.value.splice(index, 1)
// updateFileList()
}
const cancelEvent = () => {
console.log('cancel!')
}
</script>
<template>
<div class="custom-upload-container" v-loading="uploadLoading" element-loading-text="文件上传中,请耐心等待,期间切勿进行任何操作,避免文件上传失败导致丢失。">
<el-upload
v-if="buttonPermission.indexOf('upload') >= 0"
:file-list="FileList"
:show-file-list="false"
class="upload-demo"
action="/"
drag
multiple
:before-upload="beforeUpload"
:on-success="handleAvatarSuccess"
:limit="limit"
:prompt="prompt"
>
<!-- <el-button
icon="Upload"
type="primary"
:loading="uploadLoading">上传文件</el-button> -->
<div class="upload-back">
<div style="padding: 10px 0;">
<el-upload drag action="" :auto-upload="false" :file-list="fileList" :on-change="handleFileChange"
:show-file-list="false" :limit="limit" :on-exceed="handleExceed">
<div class="flex-container">
<!-- <img class="logo-upload" :src="logoUpload" alt=""> -->
<div>
<el-icon :size="52" color="rgb(51, 153, 255)">
<upload-filled />
......@@ -255,122 +12,41 @@ const cancelEvent = () => {
<div class="accept-type-container">{{ props.prompt }}</div>
</div>
</div>
</div>
</el-upload>
<el-row style="padding-top: 8px;" v-if="FileList&&FileList.length>0 && listShow">
<el-table :data="FileList">
<el-table-column
type="index"
width="65"
align="center"
fixed="left"
label="序号"/>
<el-table-column
prop="name"
align="left"
min-width="160"
:show-overflow-tooltip="true"
label="名称">
<template v-slot="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column
v-if="needType"
prop="fileType"
align="left"
:show-overflow-tooltip="true"
label="类型">
<template v-slot="scope">
{{ scope.row.fileType }}
</template>
</el-table-column>
<el-table-column
v-if="needSize"
align="left"
width="140"
prop="fileSize"
label="大小(KB)">
<template v-slot="scope">
{{ Number(scope.row.fileSize)/1000 }}
</template>
</el-table-column>
<el-table-column
v-if="needStatus"
align="center"
prop="name"
label="上传状态"
min-width="140">
<template v-slot="scope">
<template v-if="scope.row.status === 'success' || scope.row.name || scope.row.url"><el-tag class="ml-2" type="success">上传成功</el-tag></template>
<template v-else-if="scope.row.status === 'error'"><el-tag class="ml-2" type="danger">上传失败</el-tag></template>
<el-progress v-else :percentage="scope.row.progress"/>
</template>
</el-table-column>
<el-table-column
v-if="needTime"
align="left"
min-width="200"
prop="createTime"
label="上传时间" />
<el-table-column
align="center"
fixed="right"
label="操作"
width="200">
<template #default="scope">
<el-button
link
icon="View"
type="primary"
size="small"
:disabled="scope.row.status === 'error' || scope.row.status === 'uploading'"
@click="handlePreviewFile(scope.row)"
>预览</el-button>
<el-button
link
icon="Download"
type="primary"
size="small"
:disabled="scope.row.status === 'error' || scope.row.status === 'uploading'"
@click="handleDownFile(scope.row)">下载</el-button>
</div>
</template>
<el-popconfirm
v-if="buttonPermission.indexOf('delete') >= 0"
confirm-button-text="确认"
cancel-button-text="取消"
icon-color="#626AEF"
title="确认删除?"
@confirm="handleDeleteFile(scope.$index)"
@cancel="cancelEvent"
>
<template #reference>
<el-button
link
icon="Delete"
type="primary"
size="small"
:disabled="scope.row.status === 'uploading'"
>删除</el-button>
</template>
</el-popconfirm>
<script setup>
import { ref, watch, defineProps, defineEmits } from 'vue';
const props = defineProps({
prompt: {
type: String,
default: '点击或拖拽文件到此处进行上传'
},
loading: Boolean,
limit: {
type: Number,
default: 1
},
fileList: {
type: Array,
default: () => []
}
});
const emit = defineEmits(['file-change']);
// 处理文件数量超出限制
const handleExceed = (files, uploadFiles) => {
emit('file-change', files[0]);
};
</template>
</el-table-column>
</el-table>
</el-row>
</div>
</template>
const handleFileChange = (file, fileList) => {
emit('file-change', file, fileList);
};
</script>
<style lang="scss" scoped>
.custom-upload-container {
width: 100%;
border-radius: 8px;
}
:deep(.el-upload){
:deep(.el-upload){
width: 100%;
.flex-container {
display: flex;
......@@ -382,12 +58,4 @@ const cancelEvent = () => {
}
}
}
.upload-demo {
// padding-top: 24px;
// padding-bottom: 16px;
}
.upload-item {
margin-left: 5px;
}
</style>
<script setup lang="ts" name="ExpressionEditor">
import { ref, onMounted, toRefs } from "vue";
import ModalPop from "./ModalPop.vue"
import { ref, onMounted, toRefs, watch, reactive } from "vue";
import ModalPop from "./ModalPop.vue";
import { queryFunctionList, test } from "@/api/ruleConfig/algorithm";
const props = defineProps<{
modelValue: boolean;
data?: Object;
rulename?: String;
}>();
const emit = defineEmits(["update:modelValue", "confirm", "cancel"]);
const editorName = ref("");
const editorValue = ref("");
const infoText = ref('')
const listData = ref([
{
name: 'convert_base1()'
},
{
name: 'convert_base2()'
}
])
const infoText = ref("");
const listData = ref([]);
const testVisible = ref(false);
const testResult = ref(""); // 执行结果
const testData = reactive({
expression: "",
param: "",
});
// 确认
const confirm = () => {
emit("confirm", editorValue.value);
};
// 测试
const test = () => {
console.log("test");
};
const cancel = () => {
editorValue.value = JSON.parse(JSON.stringify(props.rulename));
editorName.value = JSON.parse(JSON.stringify(props.rulename));
emit("cancel");
}
};
// 划过事件
const hoverFunc = (item) => {
infoText.value = item;
}
infoText.value = item.remark;
};
// 获取函数列表
const getQueryFuncList = () => {
queryFunctionList({}).then((res) => {
const { data } = res;
listData.value = data;
});
};
const change = (val) => {
if(!val) return;
console.log(props.data)
editorValue.value = props.data.name;
// 执行测试
const executeTest = () => {
testData.expression = editorValue.value;
test(testData).then((res) => {
const { flag, data } = res;
if (flag) {
testResult.value = data;
}
});
};
// 测试关闭
const testCancel = () => {
testVisible.value = false;
testData.param = ''
testResult.value = "";
}
watch(
() => props.modelValue,
(newVal) => {
if (props.modelValue) {
getQueryFuncList();
}
},
{ deep: true, immediate: true }
);
watch(
() => props.rulename,
(newVal) => {
editorValue.value = JSON.parse(JSON.stringify(props.rulename));
editorName.value = JSON.parse(JSON.stringify(props.rulename));
},
{ deep: true, immediate: true }
);
</script>
<template>
<ModalPop v-model="props.modelValue" title="编辑器" @cancel="cancel" @change="change">
<div>
<ModalPop v-model="props.modelValue" title="编辑器" @cancel="cancel">
<template #content>
<div class="title">算法名称 :</div>
<div class="title">算法名称 : {{ editorName }}</div>
<div class="content">
<div class="content_left">
<div class="content_left_tap">函数</div>
<div class="content_left_list">
<el-scrollbar height="362px">
<div class="function__item" @mouseover="hoverFunc(item)" v-for="(item,index) in listData" :key="index">{{ item.name }}</div>
<div class="function__item" @mouseover="hoverFunc(item)" v-for="(item,index) in listData" :key="index">
{{ item.name }}</div>
</el-scrollbar>
</div>
</div>
......@@ -65,39 +103,55 @@ const change = (val) => {
<div class="content_right_info_content">定义:{{ infoText }}</div>
</div>
<div class="content_right_editor">
<el-input
type="textarea"
placeholder="请输入内容"
v-model="editorValue"
/>
<el-input type="textarea" placeholder="请输入内容" v-model="editorValue" />
</div>
</div>
</div>
<div style="display: flex; justify-content: center; padding-top: 20px;">
<el-button type="primary" style="width: 150px;" @click="test">测试</el-button>
<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>
</template>
</ModalPop>
<!-- 测试 -->
<ModalPop v-model="testVisible" width="800px" title="测试" @cancel="testCancel">
<template #content>
<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" />
<el-button type="primary" style="margin-left: 10px;" @click="executeTest">执行</el-button>
</div>
</el-form-item>
<el-form-item label="执行结果:" label-width="180px">
<div>{{ testResult }}</div>
</el-form-item>
<div style="display: flex; justify-content: center; padding-top: 20px;">
<el-button type="primary" style="width: 150px;" @click="testCancel">关闭</el-button>
</div>
</template>
</ModalPop>
</div>
</template>
<style lang="scss" scoped>
.title{
height: 32px; line-height: 32px;
.title {
height: 32px;
line-height: 32px;
}
.content{
.content {
display: flex;
height: 400px;
width: 100%;
&_left{
&_left {
height: 100%;
width: 322px;
border-width: 1px;
border-style: solid;
border-color: rgb(220, 229, 235);
border-image: initial;
&_tap{
&_tap {
height: 36px;
line-height: 36px;
font-size: 14px;
......@@ -106,46 +160,46 @@ const change = (val) => {
padding-left: 20px;
color: rgb(44, 158, 247);
}
&_list{
&_list {
height: 100%;
.function__item{
.function__item {
padding-left: 20px;
cursor: pointer;
color: #7A8596;
color: #7a8596;
}
.function__item:hover{
.function__item:hover {
background: rgb(243, 245, 250);
}
}
}
&_right{
&_right {
margin-left: 10px;
height: 100%;
flex: 1;
&_info{
&_info {
height: 146px;
border-style: solid;
border-color: rgb(220, 229, 235);
border-image: initial;
border-width: 1px 1px 0px;
padding: 0px 20px;
&_title{
&_title {
height: 42px;
line-height: 42px;
color: rgb(122, 132, 149);
font-size: 14px;
font-weight: 700;
}
&_content{
&_content {
margin-top: -4px;
color: rgb(122, 132, 149);
font-size: 12px;
word-break: break-all;
}
}
&_editor{
&_editor {
width: 100%;
:deep(.el-textarea__inner){
:deep(.el-textarea__inner) {
box-sizing: border-box !important;
height: 254px !important;
min-height: 254px !important;
......
......@@ -223,6 +223,8 @@ const getTestConnect = () => {
// 检测
const detection = () => {
// console.log('检测')
form.value.dbtype = titleName.value;
checkVersion(form.value).then((res) => {
const { flag, data, msg } = res
if (flag) {
......
......@@ -2,7 +2,7 @@
<el-dialog
v-model="dialogVisible"
:title="dialogTitle"
destroy-on-close
:before-close="handleClose"
>
<div class="dialog-content">
......@@ -17,9 +17,9 @@
label-width="100px"
label-position="top"
>
<el-form-item label="项目名称" prop="projectName" required>
<el-form-item label="项目名称" prop="name" required>
<el-input
v-model="formData.projectName"
v-model="formData.name"
placeholder="请输入项目名称"
maxlength="200"
show-word-limit
......@@ -50,11 +50,9 @@
<div v-if="activeStep === 2">
<div class="step-title">数据库</div>
<div class="filter-container">
<el-select v-model="dbFilter.type" placeholder="全部" class="filter-select">
<el-option label="全部" value="all" />
<el-option label="MySQL" value="mysql" />
<el-option label="Oracle" value="oracle" />
<el-option label="SQL Server" value="sqlserver" />
<el-select v-model="dbFilter.type" placeholder="请选择" class="filter-select">
<el-option v-for="(item,index) in sourceTypeList" :key="index" :label="item.text" :value="item.text" />
</el-select>
<el-input
......@@ -82,8 +80,8 @@
:key="db.id"
class="db-item"
>
<el-checkbox :label="db.id">
{{ db.name }}
<el-checkbox :label="db.tid">
{{ db.sysname }}
</el-checkbox>
</div>
</el-checkbox-group>
......@@ -99,12 +97,12 @@
<el-scrollbar height="300px">
<div
v-for="db in selectedDbDetails"
:key="db.id"
:key="db.tid"
class="selected-db-item"
>
<div class="db-name">{{ db.name }}</div>
<div class="db-ip">{{ db.ip }}</div>
<div class="db-username">用户名: {{ db.username }}</div>
<div class="db-name">{{ db.sysname }}</div>
<div class="db-ip">{{ db.dbip }}</div>
<div class="db-username">{{ db.username }}</div>
</div>
</el-scrollbar>
</div>
......@@ -123,12 +121,12 @@
<div class="datasource-list">
<div
v-for="db in selectedDbDetails"
:key="db.id"
:key="db.tid"
class="datasource-item"
:class="{ active: selectedDataSource === db.id }"
@click="selectDataSource(db.id)"
:class="{ active: selectedDataSource === db.tid }"
@click="selectDataSource(db.tid)"
>
{{ db.id }} {{ db.name }}
{{ db.sysname }}
</div>
</div>
</el-scrollbar>
......@@ -256,8 +254,21 @@
<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessageBox } from 'element-plus'
import { ElMessage } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import {
getdatascopeprojectlist,
checkDatasystemName,
checkDatasystem,
queryByEditSort,
selectProDataSource,
queryShemas
} from '@/api/project'
import useAppStore from '@/store/modules/app'
const appStore = useAppStore()
const props = defineProps({
visible: {
type: Boolean,
......@@ -266,7 +277,7 @@ const props = defineProps({
projectData: {
type: Object,
default: () => ({
projectName: '',
name: '',
remark: '',
projectType: 'normal',
databases: [],
......@@ -289,9 +300,55 @@ const dialogVisible = computed({
set: (value) => emit('update:visible', value)
})
// 初始化标志
const initialized = ref(false)
// 监听对话框显示状态变化
watch(dialogVisible, (newVal) => {
if (newVal && !initialized.value) {
// 对话框打开且未初始化时执行
console.log('初始化对话框数据')
initDialog()
} else if (!newVal) {
console.log('重置对话框数据')
// 对话框关闭时重置初始化标志
initialized.value = false
}
}, { deep: true })
// 当对话框显示时执行的函数
const initDialog = () => {
console.log('对话框已打开,执行初始化操作')
querySelectOrDic()
initialized.value = true
}
const querySelectOrDic = () => {
selectProDataSource({
systemstyle: 1
}).then(res=>{
console.log('selectProDataSourceRes',res)
sourceTypeList.value = res.data
dbFilter.value.type = res.data.length > 0 ? res.data[res.data.length - 1].text : ''
})
}
const reset = () => {
sourceTypeList.value = []
formData.value = {}
activeStep.value = 1
dbFilter.value.type = ''
dbFilter.value.keyword = ''
allDatabases.value = []
selectedDbs.value = []
}
const sourceTypeList = ref([])
// 表单数据
const formData = ref({
projectName: '',
id: '',
name: '',
remark: '',
projectType: 'normal',
databases: [],
......@@ -315,16 +372,16 @@ const dialogTitle = computed(() => {
// 第二步:数据库配置相关
const dbFilter = ref({
type: 'all',
type: '',
keyword: ''
})
const allDatabases = ref([
{ id: 1, name: '若依配测系统', ip: '172.19.1.166', username: 'root', type: 'mysql' },
{ id: 2, name: '测试数据库1', ip: '192.168.1.100', username: 'admin', type: 'mysql' },
{ id: 3, name: '生产数据库', ip: '10.0.0.1', username: 'dba', type: 'oracle' },
{ id: 4, name: '开发数据库', ip: '172.16.1.50', username: 'dev', type: 'mysql' },
{ id: 5, name: '备份数据库', ip: '172.16.1.51', username: 'backup', type: 'sqlserver' }
// { id: 1, name: '若依配测系统', ip: '172.19.1.166', username: 'root', type: 'mysql' },
// { id: 2, name: '测试数据库1', ip: '192.168.1.100', username: 'admin', type: 'mysql' },
// { id: 3, name: '生产数据库', ip: '10.0.0.1', username: 'dba', type: 'oracle' },
// { id: 4, name: '开发数据库', ip: '172.16.1.50', username: 'dev', type: 'mysql' },
// { id: 5, name: '备份数据库', ip: '172.16.1.51', username: 'backup', type: 'sqlserver' }
])
const selectedDbs = ref([])
......@@ -333,11 +390,11 @@ const selectAll = ref(false)
// 第三步:Schema选择相关
const selectedDataSource = ref(null)
const allSchemas = ref([
'information_schema',
'mysql',
'performance_schema',
'ry',
'sys'
// 'information_schema',
// 'mysql',
// 'performance_schema',
// 'ry',
// 'sys'
])
const selectedSchemas = ref([])
const selectAllSchemas = ref(false)
......@@ -379,14 +436,14 @@ const selectedDomains = ref(['domain2', 'domain3', 'domain4', 'domain6', 'domain
// 计算属性
const filteredDatabases = computed(() => {
return allDatabases.value.filter(db => {
const typeMatch = dbFilter.value.type === 'all' || db.type === dbFilter.value.type
const keywordMatch = db.name.includes(dbFilter.value.keyword)
return typeMatch && keywordMatch
// const typeMatch = db.type === dbFilter.value.type
const keywordMatch = db.sysname.includes(dbFilter.value.keyword)
return keywordMatch
})
})
const selectedDbDetails = computed(() => {
return allDatabases.value.filter(db => selectedDbs.value.includes(db.id))
return allDatabases.value.filter(db => selectedDbs.value.includes(db.tid))
})
const selectedDomainDetails = computed(() => {
......@@ -397,7 +454,7 @@ const selectedDomainDetails = computed(() => {
// 方法
const handleSelectAll = (val) => {
if (val) {
selectedDbs.value = filteredDatabases.value.map(db => db.id)
selectedDbs.value = filteredDatabases.value.map(db => db.tid)
} else {
selectedDbs.value = []
}
......@@ -445,10 +502,59 @@ const handlePrevStep = () => {
}
}
// 下一步/完成
const loginUser = {
tsysUser: {
id: appStore.userInfo.user.id,
username: appStore.userInfo.user.username
}
}
const handleNextStep = async () => {
if (activeStep.value < 4) {
if (activeStep.value === 1) {
try {
// 调用第一步的验证接口
const response = await validateStep1()
if (response.flag === true) {
checkDatasystem().then(res=>{
if (res.flag === true){
activeStep.value++
if(activeStep.value === 2){
queryByEditSort({
projectId: formData.value.id || '',
dbtype: dbFilter.value.type,
loginUser:loginUser,
flag:1
}).then(res=>{
allDatabases.value = res.data
})
}
}else{
ElMessage.error(res.msg)
}
}).catch(err=>{
ElMessage.error(err.msg)
})
} else {
// 验证失败,显示错误信息
ElMessage.error(response.msg || '第一步验证失败')
return // 停止继续执行
}
} catch (error) {
console.error('第一步验证接口调用失败:', error)
ElMessage.error('网络错误,请稍后重试')
return
}
} else if (activeStep.value < 4) {
if(activeStep.value === 3) {
// selectedDbDetails
}
// 其他步骤直接前进
activeStep.value++
} else {
// 最后一步提交数据
formData.value.databases = selectedDbDetails.value
......@@ -458,6 +564,31 @@ const handleNextStep = async () => {
dialogVisible.value = false
}
}
// 第一步验证接口函数
const validateStep1 = async () => {
// 这里调用实际的API接口
// 示例:return await api.validateStep1(formData)
return await checkDatasystemName({
name: formData.value.name,
id: formData.value.id
})
// 模拟API调用
// return new Promise((resolve) => {
// setTimeout(() => {
// // 模拟成功响应
// resolve({
// flag: true,
// msg: '验证成功'
// })
// // 模拟失败响应
// // resolve({
// // flag: false,
// // msg: '数据库连接失败,请检查连接信息'
// // })
// }, 1000)
// })
}
// 取消
const handleCancel = () => {
......@@ -470,6 +601,7 @@ const handleClose = (done) => {
confirmButtonText: '确定',
cancelButtonText: '取消'
}).then(() => {
reset()
done()
}).catch(() => {
// 取消关闭
......@@ -478,7 +610,7 @@ const handleClose = (done) => {
// 监听数据变化
watch(selectedDbs, (newVal) => {
selectAll.value = newVal.length > 0 && newVal.length === filteredDatabases.value.length
selectAll.value = newVal.length > 0 && newVal.length === allDatabases.value.length
})
watch(selectedSchemas, (newVal) => {
......@@ -493,12 +625,81 @@ watch(selectedDomains, (newVal) => {
}, { deep: true })
// 初始化时自动选择第一个数据源
watch(selectedDbDetails, (newVal) => {
if (newVal.length > 0 && !selectedDataSource.value) {
selectedDataSource.value = newVal[0].id
watch(selectedDbDetails,async (newVal,oldVal) => {
if(newVal.length > 0){
if(JSON.stringify(newVal) !== JSON.stringify(oldVal)){
await fetchAllSchemas(newVal)
}
if(!selectedDataSource.value){
selectedDataSource.value = newVal[0].tid
}
}
}, { immediate: true })
const fetchAllSchemas = async (databases) => {
try {
// 清空之前的数据
allSchemas.value = []
// 使用Promise.all保证顺序但并行请求(如需严格顺序请使用for循环)
const results = await Promise.all(
databases.map(db =>
queryShemas({
dbType: db.dbtype,
dataSystemId: db.tid
}).catch(error => {
console.error(`获取数据库 ${db.sysname} 的Schema失败:`, error)
return {
dataSystemId: db.tid,
error: true,
message: `获取数据库 ${db.sysname} 的Schema失败`
}
})
)
)
// 处理结果
const successResults = results.filter(r => !r.error)
const errorResults = results.filter(r => r.error)
// 合并成功的数据
successResults.forEach(res => {
if (res.data && Array.isArray(res.data)) {
allSchemas.value = [...allSchemas.value, ...res.data]
}
})
// 显示结果信息
if (successResults.length > 0) {
console.log(`成功获取 ${successResults.length} 个数据库的Schema数据`)
}
if (errorResults.length > 0) {
console.log(`${errorResults.length} 个数据库的Schema获取失败`)
}
} catch (error) {
console.error('获取Schema数据过程中出错:', error)
ElMessage.error('获取Schema数据过程中出错')
} finally {
// isLoading.value = false
}
}
// 监听传入的项目数据变化
watch(() => props.projectData, (newVal) => {
if (props.mode === 'edit') {
......
......@@ -8,7 +8,9 @@ import ExportDialog from './ExportDialog.vue'
import { useRouter } from 'vue-router'
import {changeRoute} from '@/utils/switchRoute'
import {
selectDataProject
selectDataProject,
checkProjectNum,
getdatascopeprojectlist
} from '@/api/project'
import useAppStore from '@/store/modules/app'
......@@ -139,12 +141,34 @@ function getList() {
const dialogVisible = ref(false)
const dialogMode = ref('add')
const currentProject = ref(null)
const addLoading = ref(false)
// 显示新增对话框
const showAddDialog = () => {
dialogMode.value = 'add'
addLoading.value = true
checkProjectNum().then(res=>{
console.log('checkProjectNum',res)
if(res.flag){
currentProject.value = null
dialogVisible.value = true
// getdatascopeprojectlist().then(res=>{
// currentProject.value = null
// dialogVisible.value = true
// })
addLoading.value = false
}else{
addLoading.value = false
}
}).catch(err=>{
addLoading.value = false
})
//
}
// 处理项目操作
......@@ -177,6 +201,7 @@ const handleCommandProject = (command, project) => {
const handleEnterProject = (project) => {
console.log('进入项目:', project)
changeRoute()
sessionStorage.setItem('projectId',project.id)
router.push({ path:'/indexManage/ItemManage',query: { projectId: project.id } })
......@@ -280,6 +305,7 @@ onMounted(()=>{
</template>
<template #buttons>
<el-button
:loading="addLoading"
type="primary"
icon="Plus"
@click="showAddDialog"
......
<script setup name="Algorithm">
import { onMounted, ref, toRefs } from 'vue'
import { Split } from 'view-ui-plus';
import { ElMessage } from "element-plus";
import CollapseView from '@/components/CollapseView/index.vue'
import formModule from './modules/formModule.vue'
import ModalPop from "@/components/EditPop/ModalPop.vue"
import { query } from '@/api/ruleConfig/algorithm.js'
import { query, del } from '@/api/ruleConfig/algorithm.js'
const splitNum = ref(0.31) // 左右分割比例
const collapseList = ref([])
const rulenameList = ref([]) // 规则名称列表
const searchValue = ref('')
const data = reactive({
formEdit: {
name: "",
},
formAdd: {
name: "",
addForm: {},
editForm: {},
delData: {
id: ''
}
});
const { formEdit, formAdd } = toRefs(data);
const { addForm, editForm, delData } = toRefs(data);
const modalData = reactive({
show: false,
......@@ -33,26 +34,41 @@ const modalData = reactive({
const modalPopShow = ref(false)
// 获取数据
const getCollapse = () => {
query({dataarea: searchValue.value}).then(res => {
const getCollapse = (type) => {
query({ dataarea: searchValue.value }).then(res => {
rulenameList.value = []
const { data } = res
collapseList.value = data.map(item => {
const list = item.ruleList.map(itemTwo => {
rulenameList.value.push(itemTwo.rulename)
return {
...itemTwo,
name: itemTwo.rulename,
defaulttype: itemTwo.defaluttype,
isCheck: false,
isDelete: true,
}
})
return {
...item,
list: list,
isAdd: true,
isView: false,
isDelete: false,
}
})
if (type === 'edit') return
if (collapseList.value.length <= 0) return
if (collapseList.value[0].ruleList.length > 0) {
editForm.value = collapseList.value[0].ruleList[0]
} else {
const { id } = collapseList.value[0]
editForm.value = {
dataarea_id: id
}
}
})
// collapseList.value = data.map(item => {
// const list = item.list.map(itemTwo => {
// return {
// ...itemTwo,
// isCheck: false,
// isDelete: true,
// }
// })
// return {
// ...item,
// list: list,
// isAdd: true,
// isView: false,
// isDelete: false,
// }
// })
}
// 新增算法关闭
......@@ -62,32 +78,50 @@ const modalPopCancel = () => {
// 新增算法
const collapseAdd = (item) => {
console.log('添加事件', item)
formAdd.value = {}
// console.log('添加事件', item)
const { id } = item
addForm.value = {
dataarea_id: id
}
modalPopShow.value = true
}
// 删除事件
const collapseDelete = (item) => {
console.log('删除事件', item)
// console.log('删除事件', item)
const { rulename } = item
delData.value = item
modalData.show = true
modalData.icon = 'error'
modalData.text = '删除后无法恢复,是否确认删除[' + item.name + ']?'
modalData.text = '删除后无法恢复,是否确认删除[' + rulename + ']?'
}
// 删除回调
const modalConfirm = () => {
const { id } = delData.value
const data = {
ruleId: id
}
del(data).then(res => {
const { flag } = res
if (flag) {
ElMessage.success('删除成功')
getCollapse()
modalData.show = false
} else {
ElMessage.error('删除失败')
}
})
}
// 点击监听
const collapseChange = (item) => {
formEdit.value = item
editForm.value = item.item
}
// 算法确认
const formModuleConfirm = (item) => {
console.log('新增算法', item)
const formModuleConfirm = (val) => {
getCollapse(val)
modalPopShow.value = false
}
......@@ -106,7 +140,7 @@ onMounted(() => {
<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%;">
<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">
......@@ -114,7 +148,10 @@ onMounted(() => {
</el-icon>
</template>
</el-input>
<CollapseView :list="collapseList" @add="collapseAdd" @childDelete="collapseDelete" @change="collapseChange" />
<el-scrollbar style="width: 100%;flex: 1;padding-right: 38px;">
<CollapseView :list="collapseList" @add="collapseAdd" @childDelete="collapseDelete"
@change="collapseChange" />
</el-scrollbar>
</div>
</template>
<template #right>
......@@ -127,7 +164,7 @@ onMounted(() => {
<span style="margin-left: 5px;">脱敏规则</span>
</div>
<div class="right-content">
<formModule v-model="formEdit" type="edit" />
<formModule :itemData="editForm" :nameList="rulenameList" type="edit" @confirm="formModuleConfirm" />
</div>
</div>
</div>
......@@ -139,9 +176,10 @@ onMounted(() => {
@confirm="modalConfirm"></Modal>
<!-- 新增算法 -->
<ModalPop v-model="modalPopShow" title="编辑器" @cancel="modalPopCancel">
<ModalPop v-model="modalPopShow" title="新增算法" @cancel="modalPopCancel">
<template #content>
<formModule v-model="formAdd" type="add" @cancel="modalPopCancel" @confirm="formModuleConfirm" />
<formModule :itemData="addForm" :nameList="rulenameList" type="add" @cancel="modalPopCancel"
@confirm="formModuleConfirm" />
</template>
</ModalPop>
</div>
......
<script setup lang="ts" name="Form">
import { onMounted, reactive, ref, toRefs, watch } from "vue";
import { Switch } from "view-ui-plus";
import ExpressionEditor from '@/components/EditPop/ExpressionEditor.vue'
import type { FormInstance } from "element-plus";
import { ElMessage } from "element-plus";
import ExpressionEditor from "@/components/EditPop/ExpressionEditor.vue";
import { save } from "@/api/ruleConfig/algorithm";
const props = defineProps<{
modelValue: boolean;
itemData: Object;
type: string;
nameList: any;
}>();
const emit = defineEmits(["update:modelValue", 'cancel','confirm']);
const emit = defineEmits(["cancel", "confirm"]);
const data = reactive({
rules: {},
form: <any>{
dataarea_id: "",
defaluttype: "0",
expression: "",
id: "",
rulename: "",
rulesource: "",
},
rules: {
expression: [
{
required: true,
message: "请输入表达式",
trigger: ["blur"],
},
],
},
});
const { rules } = toRefs(data);
const { form, rules } = toRefs(data);
const editorShow = ref(false);
const readOnly = ref(true);
const editor = ref({});
const rulenameList = ref([])
const formRef = ref<FormInstance>();
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === 'edit' ? true : false;
},
{ deep: true, immediate: true }
);
// 重置
const reset = () => {
form.value = {
dataarea_id: "",
defaulttype: "0",
enc_name: "",
encryption_id: "",
secretkey_id: "",
};
};
// 打开编辑器
const openEditor = () => {
editorShow.value = true
editor.value = props.modelValue
}
editorShow.value = true;
editor.value = form.value.expression;
};
// 取消
const cancel = () => {
if (props.type === 'edit') {
readOnly.value = true
}else if (props.type === 'add') {
emit('cancel')
if (props.type === "edit") {
readOnly.value = true;
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
} else if (props.type === "add") {
emit("cancel");
}
}
};
const confirm = () => {
if (props.type === 'edit') {
readOnly.value = true
formRef.value?.validate((valid) => {
if (valid) {
saveFunc();
} else {
}
emit('confirm')
}
});
};
const saveFunc = () => {
if (props.type === "edit") {
form.value = { ...form.value, ...{ id: form.value.id } };
}
save(form.value).then((res) => {
const { flag } = res;
if (flag) {
ElMessage.success(
props.type === "add" || !form.value.id ? "新增成功" : "修改成功"
);
if (props.type === "edit") {
readOnly.value = true;
} else if (props.type === "add") {
reset();
}
emit("confirm", props.type);
}
});
};
// 算法名称验证
const validateRulename = (rule, value, callback) => {
if (form.value.id && form.value.rulename === value) {
callback();
return false;
}
const state = rulenameList.value.includes(value);
if (state) {
callback(new Error('算法名称已存在'));
} else {
callback();
}
};
// 编辑器确认
const formConfirm = (val) => {
editorShow.value = false
props.modelValue.name = val
}
editorShow.value = false;
form.value.expression = val;
};
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === "edit" ? true : false;
},
{ deep: true, immediate: true }
);
watch(
() => props.itemData,
(newVal) => {
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)
}
}
},
{ deep: true, immediate: true }
);
watch(
() => props.nameList,
(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)
}
},
{ deep: true, immediate: true }
);
</script>
<template>
<div>
<el-form ref="formRef" :model="modelValue" label-width="100px" :disabled="readOnly">
<el-form-item label="算法名称" required>
<el-input v-model="modelValue.name"></el-input>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" :disabled="readOnly">
<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="表达式" required>
<el-input type="textarea" rows="8" v-model="modelValue.name"></el-input>
<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-form-item>
<el-form-item label="默认规则">
<Switch :disabled="readOnly">
<Switch true-value="1" false-value="0" v-model="form.defaluttype" :disabled="readOnly">
<template #open>
<span></span>
</template>
......@@ -86,7 +182,7 @@ const formConfirm = (val) => {
<el-button type="primary" style="width: 150px;" @click="confirm" v-if="!readOnly">确认</el-button>
</div>
<ExpressionEditor v-model="editorShow" :data="editor" @cancel=" editorShow = false" @confirm="formConfirm" />
<ExpressionEditor v-model="editorShow" :rulename="editor" @cancel=" editorShow = false" @confirm="formConfirm" />
</div>
</template>
......
......@@ -14,9 +14,8 @@ const collapseList = ref([])
const encryptionList = ref([]) // 加密规则列表
const data = reactive({
formData: {
name: "",
},
addForm: {},
editForm: {},
queryParams: {
dataarea: ''
},
......@@ -25,7 +24,7 @@ const data = reactive({
}
});
const { formData, queryParams, delData } = toRefs(data);
const { addForm, editForm, queryParams, delData } = toRefs(data);
const modalData = reactive({
show: false,
......@@ -37,7 +36,7 @@ const modalData = reactive({
const modalPopShow = ref(false)
// 获取数据
const getCollapse = () => {
const getCollapse = (type) => {
query(queryParams.value).then(res => {
const { data } = res
collapseList.value = data.map(item => {
......@@ -57,14 +56,15 @@ const getCollapse = () => {
isDelete: false,
}
})
if (type === 'edit') return
if (collapseList.value.length <= 0) return
if (collapseList.value[0].secretkeyList.length > 0) {
formData.value = {
editForm.value = {
dataarea_id: collapseList.value[0].id,
...collapseList.value[0].secretkeyList[0]
}
} else {
formData.value = {
editForm.value = {
dataarea_id: collapseList.value[0].id
}
}
......@@ -80,7 +80,7 @@ const modalPopCancel = () => {
const collapseAdd = (item) => {
// console.log('添加事件', item)
const { id } = item
formData.value = {
addForm.value = {
dataarea_id: id
}
modalPopShow.value = true
......@@ -88,7 +88,7 @@ const collapseAdd = (item) => {
// 删除事件
const collapseDelete = (item) => {
console.log('删除事件', item)
// console.log('删除事件', item)
const { name } = item
delData.value = item
modalData.show = true
......@@ -112,21 +112,20 @@ const modalConfirm = () => {
ElMessage.error('删除失败')
}
})
}
// 点击监听
const collapseChange = (item) => {
console.log('修改事件', item)
formData.value = {
// console.log('修改事件', item)
editForm.value = {
...item.item
}
}
// 算法确认
const formModuleConfirm = (item) => {
console.log('新增算法', item)
getCollapse()
const formModuleConfirm = (val) => {
// console.log('新增算法', val)
getCollapse(val)
modalPopShow.value = false
}
......@@ -183,7 +182,7 @@ onMounted(() => {
<span style="margin-left: 5px;">加密算法</span>
</div>
<div class="right-content">
<formModule :itemData="formData" :encryptionDict="encryptionList" type="edit" @cancel="modalPopCancel"
<formModule :itemData="editForm" :encryptionDict="encryptionList" type="edit" @cancel="modalPopCancel"
@confirm="formModuleConfirm" />
</div>
</div>
......@@ -196,9 +195,9 @@ onMounted(() => {
@confirm="modalConfirm"></Modal>
<!-- 新增加密算法 -->
<ModalPop v-model="modalPopShow" title="编辑器" @cancel="modalPopCancel">
<ModalPop v-model="modalPopShow" width="800px" title="新增加密算法" @cancel="modalPopCancel">
<template #content>
<formModule :itemData="formData" :encryptionDict="encryptionList" type="add" @cancel="modalPopCancel"
<formModule :itemData="addForm" :encryptionDict="encryptionList" type="add" @cancel="modalPopCancel"
@confirm="formModuleConfirm" />
</template>
</ModalPop>
......
<script setup lang="ts" name="Form">
import { onMounted, reactive, ref, toRefs, watch } from "vue";
import { onMounted, reactive, ref, toRefs, watch, computed } from "vue";
import { Switch } from "view-ui-plus";
import type { FormInstance } from "element-plus";
import { ElMessage } from "element-plus";
......@@ -47,10 +47,10 @@ const data = reactive({
});
const { form, rules } = toRefs(data);
const encryptionList = ref<any[]>([]); // 加密规则选项列表
const secretkeyList = ref<any[]>([]); // 密钥选项列表
const readOnly = ref(true);
const formRef = ref<FormInstance>();
const encryptionList = computed(() => props.encryptionDict); // 加密规则选项列表
// 重置
const reset = () => {
......@@ -85,7 +85,7 @@ const confirm = () => {
};
const saveFunc = () => {
console.log(form.value)
// console.log(form.value)
if (props.type === "edit") {
form.value = { ...form.value, ...{ id: form.value.id } }
}
......@@ -135,9 +135,6 @@ watch(
() => props.itemData,
(newVal) => {
if (props.itemData) {
if (!props.itemData.enc_name) {
reset()
}
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
if (props.type === "edit" && form.value.secretkey_id) {
......@@ -148,13 +145,6 @@ watch(
{ deep: true, immediate: true }
);
watch(
() => props.encryptionDict,
(newVal) => {
encryptionList.value = props.encryptionDict;
},
{ deep: true, immediate: true }
);
</script>
<template>
......
......@@ -8,7 +8,7 @@ import AddClass from './modules/AddClass.vue' // 分类
import AddValue from './modules/AddValue.vue' // 值
import uploadModule from './modules/uploadModule.vue' // 上传模块
import { dictinaryTypes, query, delDictionaryType, delValue } from '@/api/ruleConfig/dictionary'
import { dictinaryTypes, query, delDictionaryType, delValue, exportExcel } from '@/api/ruleConfig/dictionary'
const splitNum = ref(0.31) // 左右分割比例
......@@ -118,7 +118,7 @@ const modalConfirm = () => {
}
if (value === queryParams.value.typecode) {
getData()
}else{
} else {
getData('class')
}
})
......@@ -143,7 +143,7 @@ const modalConfirm = () => {
// 分类查看
const classView = (item) => {
if(queryParams.value.typecode === item.value) return
if (queryParams.value.typecode === item.value) return
queryParams.value.typecode = item.value
queryParams.value.typename = item.text
getTableData()
......@@ -159,6 +159,7 @@ const AddDomainConfirm = (item) => {
console.log('导入', item)
getTableData()
}
modalPopData.type = ''
modalPopData.show = false
}
......@@ -172,7 +173,7 @@ const importClick = () => {
// 获取分类名称
const getClassName = (value) => {
const item = classList.value.find(item => item.value === value)
return item? item.text : ''
return item ? item.text : ''
}
// 获取列表数据
......@@ -183,7 +184,7 @@ const getData = (type) => {
if (classList.value.length <= 0) return
if (type === 'class') {
getTableData()
}else {
} else {
queryParams.value.typecode = classList.value[0].value
queryParams.value.typename = classList.value[0].text
getTableData()
......@@ -200,6 +201,21 @@ const getTableData = () => {
})
}
// 导出excel
const exportExcelFunc = () => {
exportExcel({ typecode: queryParams.value.typecode }).then(response => {
const { data } = response;
const blob = new Blob([response], { type: 'application/vnd.ms-excel,charset=utf-8' });
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = `${queryParams.value.typename}知识库.xlsx`
link.click()
URL.revokeObjectURL(link.href)
ElMessage.success('导出成功')
})
}
onMounted(() => {
getData()
})
......@@ -249,7 +265,7 @@ onMounted(() => {
</el-form-item>
<div style="display: flex;">
<el-button icon="Upload" type="primary" @click="importClick">导入</el-button>
<el-button icon="Download" type="success">导出</el-button>
<el-button icon="Download" type="success" @click="exportExcelFunc">导出</el-button>
<el-button icon="Plus" type="primary" @click="addValueClick('add')">新增值</el-button>
</div>
</div>
......@@ -287,8 +303,8 @@ onMounted(() => {
<template #content>
<AddClass :itemData="addClassForm" :type="modalPopData.operation" @cancel="modalPopCancel"
@confirm="AddDomainConfirm" v-if="modalPopData.type === 'class'" />
<AddValue :itemData="addValueForm" :type="modalPopData.operation" :classDict="classList" @cancel="modalPopCancel"
@confirm="AddDomainConfirm" v-if="modalPopData.type === 'value'" />
<AddValue :itemData="addValueForm" :type="modalPopData.operation" :classDict="classList"
@cancel="modalPopCancel" @confirm="AddDomainConfirm" v-if="modalPopData.type === 'value'" />
<uploadModule @cancel="modalPopCancel" @confirm="AddDomainConfirm" v-if="modalPopData.type === 'upload'" />
</template>
</ModalPop>
......
<script setup lang="ts" name="AddValue">
import { onMounted, reactive, ref, toRefs, watch } from "vue";
import { onMounted, reactive, ref, toRefs, watch, computed } from "vue";
import type { FormInstance } from "element-plus";
import { ElMessage } from "element-plus";
......@@ -36,7 +36,7 @@ const data = reactive({
const { form, rules } = toRefs(data);
const formRef = ref<FormInstance>();
const classDictList = ref<any[]>([]);
const classDictList = computed(() => props.classDict);
// 重置
const reset = () => {
......@@ -81,20 +81,12 @@ watch(
() => props.itemData,
(newVal) => {
if (props.itemData) {
const data = JSON.parse(JSON.stringify(props.itemData))
form.value = {...form.value, ...data}
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
}
},
{ deep: true, immediate: true }
);
watch(
() => props.classDict,
(newVal) => {
classDictList.value = props.classDict;
},
{ deep: true, immediate: true }
);
</script>
<template>
......
<script setup lang="ts" name="AddClass">
import { ref } from "vue";
import CustomUpload from "@/components/CustomUpload/index.vue"
import { ref, reactive } from "vue";
import { ElMessage } from "element-plus";
import CustomUpload from "@/components/CustomUpload/index.vue";
import { importfile } from "@/api/ruleConfig/dictionary";
const emit = defineEmits(["update:modelValue", "cancel", "confirm"]);
const emit = defineEmits(["cancel", "confirm"]);
const radioValue = ref(1);
const fileList = ref<File[]>([]);
const uploadLoading = ref(false);
const uploadFile = ref({});
const smart = ref(1)
// 取消
const cancel = () => {
......@@ -14,32 +17,45 @@ const cancel = () => {
// 确认
const confirm = () => {
console.log(fileList.value);
// emit("confirm");
if (!uploadFile.value.name) {
ElMessage.error("请先选择文件");
return;
}
uploadLoading.value = true;
const formData = new FormData();
formData.append('fileUpload', uploadFile.value.raw);
formData.append('smart', smart.value.toString());
importfile(formData).then((res) => {
const { flag } = res;
if (flag) {
uploadLoading.value = false;
ElMessage.success('导入成功');
emit("confirm");
}
});
};
const handleUpload = (file: File) => {
console.log(file);
// 上传文件
// 处理上传结果
// 更新modelValue
const handleFileChange = (file) => {
uploadFile.value = file;
};
</script>
<template>
<div>
<div class="mb20">
<CustomUpload v-model:file-list="fileList" :limit="1" :needType="false" :needSize="false" :listShow="false" prompt='点击或拖拽文件到此处上传' />
<CustomUpload :prompt='uploadFile ? uploadFile.name : ""' :loading="uploadLoading"
@file-change="handleFileChange" />
</div>
<el-form-item label="上传方式" label-width="200px">
<el-radio-group v-model="radioValue">
<el-radio-group v-model="smart">
<el-radio :label="1">覆盖原数据</el-radio>
<el-radio :label="2">追加数据</el-radio>
<el-radio :label="0">追加数据</el-radio>
</el-radio-group>
</el-form-item>
<div class="btn">
<el-button type="info" style="width: 150px;" @click="cancel">取消</el-button>
<el-button type="primary" style="width: 150px;" @click="confirm">确认</el-button>
<el-button type="primary" :loading="uploadLoading" style="width: 150px;" @click="confirm">确认</el-button>
</div>
</div>
</template>
......
......@@ -30,29 +30,12 @@ const { form, rules } = toRefs(data);
const readOnly = ref(true);
const formRef = ref<FormInstance>();
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === 'edit' ? true : false;
},
{ deep: true, immediate: true }
);
watch(
() => props.itemData,
(newVal) => {
if (props.type === 'edit' && props.itemData) {
form.value = JSON.parse(JSON.stringify(props.itemData))
}
},
{ deep: true, immediate: true }
);
// 取消
const cancel = () => {
if (props.type === 'edit') {
form.value = props.itemData
readOnly.value = true
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
} else if (props.type === 'add') {
emit('cancel')
form.value = {}
......@@ -107,6 +90,24 @@ const addDataAreaFun = () => {
})
}
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === 'edit' ? true : false;
},
{ deep: true, immediate: true }
);
watch(
() => props.itemData,
(newVal) => {
if (props.type === 'edit' && props.itemData) {
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
}
},
{ deep: true, immediate: true }
);
</script>
......
<script setup name="Discover">
import { onMounted, ref, toRefs } from 'vue'
import { Split } from 'view-ui-plus';
import { ElMessage } from 'element-plus'
import CollapseView from '@/components/CollapseView/index.vue'
import AddEncryption from './modules/AddEncryption.vue' // 加密表单
import AddKey from './modules/AddKey.vue' // 密钥表单
import ModalPop from "@/components/EditPop/ModalPop.vue"
import { query, initEncryptionTypeList, getDictinaryTypes, deleteType, delSecretKey } from '@/api/ruleConfig/encryption'
const splitNum = ref(0.31) // 左右分割比例
const collapseList = ref([])
const collapseList = ref([]) // 左侧列表数据
const encryptionTypeList = ref([]) // 加密类型列表
const dictinaryTypes = ref([]) // 字典类型列表
const typeNameList = ref([]) // 分类名称列表
const keyNameList = ref([]) // 分类名称列表
const data = reactive({
editEncryptionForm: {
name: "",
},
addEncryptionForm: {
name: "",
encryptionForm: {},
keyForm: {},
queryParams: {
encryption_name: ''
},
editKeyForm: {
name: "",
},
addKeyForm: {
name: "",
delData: {
id: ''
}
});
const { editEncryptionForm, addEncryptionForm, editKeyForm, addKeyForm } = toRefs(data);
const { encryptionForm, keyForm, queryParams, delData } = toRefs(data);
const rightType = ref('encryption') // 右侧展示类型
const modalData = reactive({
show: false,
......@@ -42,48 +44,40 @@ const modalPopData = reactive({
})
// 获取数据
const getCollapse = () => {
const data = [
{
name: '测试加密',
list: [
{
name: '按混合证件号字段查询'
}
]
},
{
name: '通用规则',
list: [
{
name: 'aaaaa'
},
{
name: 'bbbbb'
}
]
},
{
name: '解密数据',
list: []
}
]
const getCollapse = (type) => {
query(queryParams.value).then(res => {
const { data } = res
collapseList.value = data.map(item => {
const list = item.list.map(itemTwo => {
return {
...itemTwo,
name: itemTwo.secret_key_name,
isCheck: false,
isDelete: true,
}
})
return {
...item,
dataarea: item.encryption_name,
list: list,
isAdd: true,
isView: true,
isDelete: true,
}
})
if (type === 'edit') return
if (collapseList.value.length <= 0) return
modalData.type = 'encryption'
encryptionForm.value = collapseList.value[0]
})
}
// 获取加密类型列表
const getInitEncryptionTypeList = () => {
initEncryptionTypeList({}).then(res => {
const { data } = res
encryptionTypeList.value = data
})
}
// 新增关闭
......@@ -93,78 +87,119 @@ const modalPopCancel = () => {
// 新增加密
const addDomainClick = (item) => {
console.log('新增加密')
typeNameList.value = []
collapseList.value.forEach(item => {
typeNameList.value.push(item.encryption_name)
})
modalPopData.title = '新增加密'
modalPopData.type = 'encryption'
addEncryptionForm.value = {}
encryptionForm.value = {}
modalPopData.show = true
}
// 新增密钥
const collapseAdd = (item) => {
console.log('新增密钥', item)
keyNameList.value = []
item.list.forEach(item => {
keyNameList.value.push(item.secret_key_name)
})
const { encryption_name, encryption_type, id } = item
modalPopData.title = '新增密钥'
modalPopData.type = 'key'
addKeyForm.value = {}
keyForm.value = {
encryption_name: encryption_name,
encryption_type: encryption_type,
encryption_id: id
}
modalPopData.show = true
}
// 删除密钥
const collapseDelete = (item) => {
console.log('删除密钥', item)
modalData.type = 'key'
modalData.cancel = true
modalData.icon = 'error'
modalData.text = '删除后无法恢复,是否确认删除[' + item.name + ']?'
modalData.show = true
}
// 删除加密
const collapseMainDeletion = (item) => {
console.log('删除加密事件', item)
const { encryption_name } = item
delData.value = item
modalData.type = 'encryption'
modalData.cancel = false
modalData.icon = 'error'
modalData.text = '删除后无法恢复,是否确认删除[' + item.name + ']?'
modalData.text = '删除后无法恢复,是否确认删除[' + encryption_name + ']?'
modalData.show = true
}
// 删除密钥
const collapseDelete = (item) => {
const { secret_key_name } = item
delData.value = item
modalData.type = 'key'
modalData.cancel = true
modalData.icon = 'error'
modalData.text = '删除后无法恢复,是否确认删除[' + secret_key_name + ']?'
modalData.show = true
}
// 提示回调
const modalConfirm = () => {
if (modalData.type === 'encryption') {
console.log('删除加密确认')
const { id } = delData.value
deleteType({ encryptionId: id }).then(res => {
const { flag } = res
if (flag) {
ElMessage.success('删除成功')
getCollapse()
} else {
ElMessage.error('删除失败')
}
})
} else if (modalData.type === 'key') {
console.log('删除密钥确认')
} else if (modalData.type === 'default') {
console.log('设置默认项')
const { id } = delData.value
delSecretKey({ keyId: id }).then(res => {
const { flag } = res
if (flag) {
ElMessage.success('删除成功')
getCollapse()
} else {
ElMessage.error('删除失败')
}
})
}
modalData.show = false
}
// 加密查看
const collapseView = (item) => {
editEncryptionForm.value = item
typeNameList.value = []
collapseList.value.forEach(item => {
typeNameList.value.push(item.encryption_name)
})
encryptionForm.value = item
rightType.value = 'encryption'
}
// 规则点击监听
const collapseChange = (item) => {
editKeyForm.value = item
// 密钥点击监听
const collapseChange = (itemData) => {
const { parentItem, item } = itemData
const { encryption_name, encryption_type } = parentItem
keyNameList.value = []
parentItem.list.forEach(itemLi => {
keyNameList.value.push(itemLi.secret_key_name)
})
console.log('密钥点击监听', item)
keyForm.value = { ...item, ...{ encryption_name: encryption_name, encryption_type: encryption_type } }
rightType.value = 'key'
}
// 新增确认
const AddDomainConfirm = (item) => {
const AddFormConfirm = (item) => {
if (modalPopData.type === 'encryption') {
console.log('新增加密确认', item)
getCollapse(item)
} else if (modalPopData.type === 'key') {
console.log('新增密钥确认', item)
getCollapse(item)
}
modalPopData.show = false
}
onMounted(() => {
getCollapse()
getInitEncryptionTypeList()
})
</script>
......@@ -184,17 +219,17 @@ onMounted(() => {
<el-button class="mr10" icon="Download" type="primary">备份</el-button>
</div>
<div class="mb20" style="display: flex;align-items: center;justify-content: space-between;">
<el-input class="mr20" placeholder="加密方式搜索">
<el-input class="mr20" v-model="queryParams.encryption_name" placeholder="加密方式搜索">
<template #suffix>
<el-icon style="vertical-align: middle;">
<el-icon style="vertical-align: middle;cursor: pointer;" @click="getCollapse">
<search />
</el-icon>
</template>
</el-input>
<el-button type="primary" icon="Plus" @click="addDomainClick">新增加密</el-button>
</div>
<CollapseView :list="collapseList" @add="collapseAdd" @mainDeletion="collapseMainDeletion" @childDelete="collapseDelete"
@change="collapseChange" @view="collapseView" />
<CollapseView :list="collapseList" @add="collapseAdd" @mainDeletion="collapseMainDeletion"
@childDelete="collapseDelete" @change="collapseChange" @view="collapseView" />
</div>
</template>
<template #right>
......@@ -207,8 +242,11 @@ onMounted(() => {
<span style="margin-left: 5px;">{{ rightType === 'encryption' ? '加密定义' : '密钥定义' }}</span>
</div>
<div class="right-content">
<AddEncryption v-model="editEncryptionForm" type="edit" v-if="rightType === 'encryption'" />
<AddKey v-model="editKeyForm" type="edit" v-if="rightType === 'key'" />
<AddEncryption :itemData="encryptionForm" :encryptionTypeDict="encryptionTypeList"
:typeNameDict="typeNameList" type="edit" v-if="rightType === 'encryption'" @cancel="modalPopCancel"
@confirm="AddFormConfirm" />
<AddKey :itemData="keyForm" :encryptionTypeDict="encryptionTypeList" :keyNameDict="keyNameList"
type="edit" v-if="rightType === 'key'" @cancel="modalPopCancel" @confirm="AddFormConfirm" />
</div>
</div>
</div>
......@@ -222,10 +260,10 @@ onMounted(() => {
<!-- 新增加密 / 密钥 -->
<ModalPop :width="'850'" v-model="modalPopData.show" :title="modalPopData.title" @cancel="modalPopCancel">
<template #content>
<AddEncryption v-model="addEncryptionForm" type="add" @cancel="modalPopCancel" @confirm="AddDomainConfirm"
v-if="modalPopData.type === 'encryption'" />
<AddKey v-model="addKeyForm" type="add" @cancel="modalPopCancel" @confirm="AddDomainConfirm"
v-if="modalPopData.type === 'key'" />
<AddEncryption :itemData="encryptionForm" :encryptionTypeDict="encryptionTypeList" :typeNameDict="typeNameList"
type="add" @cancel="modalPopCancel" @confirm="AddFormConfirm" v-if="modalPopData.type === 'encryption'" />
<AddKey :itemData="keyForm" :encryptionTypeDict="encryptionTypeList" :keyNameDict="keyNameList" type="add"
@cancel="modalPopCancel" @confirm="AddFormConfirm" v-if="modalPopData.type === 'key'" />
</template>
</ModalPop>
</div>
......
<script setup lang="ts" name="AddDomain">
import { onMounted, reactive, ref, toRefs, watch } from "vue";
import { onMounted, reactive, ref, toRefs, watch, computed } from "vue";
import type { FormInstance } from "element-plus";
import { ElMessage } from 'element-plus'
import { save } from '@/api/ruleConfig/encryption'
const props = defineProps<{
modelValue: boolean;
itemData: Object;
type: string;
encryptionTypeDict: Array<any>;
typeNameDict: any;
}>();
const emit = defineEmits(["update:modelValue", 'cancel','confirm']);
const emit = defineEmits(['cancel','confirm']);
const data = reactive({
rules: {},
form: <any>{
},
rules: {
encryption_type: [
{
required: true,
message: "请选择加密方式",
trigger: ["change"],
},
],
},
});
const { rules } = toRefs(data);
const { form, rules } = toRefs(data);
const readOnly = ref(true);
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === 'edit' ? true : false;
},
{ deep: true, immediate: true }
);
const typeNameList = ref([])
const encryptionTypeOptions = computed(() => props.encryptionTypeDict)
const formRef = ref<FormInstance>();
// 取消
const cancel = () => {
if (props.type === 'edit') {
readOnly.value = true
}else if (props.type === 'add') {
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
} else if (props.type === 'add') {
emit('cancel')
form.value = {}
}
}
const confirm = () => {
formRef.value?.validate((valid) => {
if (valid) {
addDataFun()
} else {
}
});
}
// 添加加密分类
const addDataFun = () => {
if (props.type === 'edit') {
form.value = {...form.value,...{id: form.value.id}}
}
save(form.value).then(res => {
const { flag } = res
if (flag) {
ElMessage.success((props.type === "add" || !form.value.id) ? "新增成功" : "修改成功");
if (props.type === 'edit') {
readOnly.value = true
} else if (props.type === 'add') {
form.value = {}
}
emit('confirm')
emit('confirm', props.type)
}
})
}
// 分类称验证
const validateRulename = (rule, value, callback) => {
const state = typeNameList.value.includes(value);
if (state) {
callback(new Error('加密名称已存在'));
} else {
callback();
}
};
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === 'edit' ? true : false;
},
{ deep: true, immediate: true }
);
watch(
() => props.itemData,
(newVal) => {
if (props.type === 'edit' && props.itemData) {
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
if (props.type === 'edit') {
typeNameList.value = typeNameList.value.filter(item => item !== data.encryption_name)
}
}
},
{ deep: true, immediate: true }
);
watch(
() => props.typeNameDict,
(newVal) => {
typeNameList.value = props.typeNameDict
const data = JSON.parse(JSON.stringify(props.itemData));
if (props.type === 'edit' && data) {
typeNameList.value = typeNameList.value.filter(item => item !== data.encryption_name)
}
},
{ deep: true, immediate: true }
);
</script>
<template>
<div>
<el-form ref="formRef" :model="modelValue" label-width="100px" :disabled="readOnly">
<el-form-item label="加密名称" required>
<el-input v-model="modelValue.name"></el-input>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" :disabled="readOnly">
<el-form-item label="加密名称" prop="encryption_name" required :rules="[{ required: true, message: '请输入加密名称', trigger:'blur' },{ required: true, validator: validateRulename, trigger:'blur' }]">
<el-input v-model="form.encryption_name"></el-input>
</el-form-item>
<el-form-item label="加密方式" required>
<el-form-item label="加密方式" prop="encryption_type" required>
<div style="width: 100%;background: #F3F5FA;">
<el-input v-model="modelValue.name" v-if="readOnly"></el-input>
<el-select v-model="modelValue.name" v-if="!readOnly">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
<el-select v-model="form.encryption_type">
<el-option v-for="item in encryptionTypeOptions" :key="item.value" :label="item.text" :value="item.value">
</el-option>
</el-select>
</div>
</el-form-item>
<el-form-item label="备注">
<el-input type="textarea" rows="4" v-model="modelValue.name"></el-input>
<el-input type="textarea" rows="4" v-model="form.note"></el-input>
</el-form-item>
</el-form>
<div class="btn">
......@@ -76,4 +152,9 @@ const confirm = () => {
display: flex;
justify-content: center;
}
:deep(.el-form-item__error) {
left: auto;
right: 30px;
top: 24%;
}
</style>
\ No newline at end of file
<script setup lang="ts" name="AddRules">
import { onMounted, reactive, ref, toRefs, watch } from "vue";
import { Switch } from "view-ui-plus";
import { onMounted, reactive, ref, toRefs, watch, computed } from "vue";
import type { FormInstance } from "element-plus";
import { ElMessage } from "element-plus";
import { getRandomValue, testEncryption, saveSecretKey } from '@/api/ruleConfig/encryption'
const props = defineProps<{
modelValue: boolean;
itemData: Object;
type: string;
encryptionTypeDict: Array<any>;
keyNameDict: any;
}>();
const emit = defineEmits(["update:modelValue", "cancel", "confirm"]);
const emit = defineEmits(['cancel','confirm']);
const data = reactive({
rules: {},
});
const { rules } = toRefs(data);
form: <any>{
const readOnly = ref(true);
const radio = ref(1);
const radioOptions = ref([
{
label: "正则表达式",
value: 1,
},
rules: {
sectet_key_value: [
{
label: "自定义方法",
value: 2,
required: true,
message: "密钥值不能为空",
trigger: ["change"],
},
{
label: "字典发现",
value: 3,
],
},
]);
});
const { form, rules } = toRefs(data);
const readOnly = ref(true);
const testParam = ref(""); // 测试参数
const encryptedValue = ref(""); // 加密后的值
const formRef = ref<FormInstance>();
const keyNameList = ref([])
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === "edit" ? true : false;
},
{ deep: true, immediate: true }
);
// 取消
const cancel = () => {
if (props.type === "edit") {
readOnly.value = true;
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
} else if (props.type === "add") {
emit("cancel");
}
};
const confirm = () => {
if (props.type === "edit") {
readOnly.value = true;
formRef.value?.validate((valid) => {
if (valid) {
saveSecretKeyFun()
} else {
}
});
};
// 添加密钥
const saveSecretKeyFun = () => {
const { encryption_id, secret_key_name, sectet_key_value, id } = form.value;
let data = {
encryption_id: encryption_id,
secret_key_name: secret_key_name,
sectet_key_value: sectet_key_value,
}
if (props.type === 'edit') {
data = {...data,...{id: id}}
}
saveSecretKey(data).then(res => {
const { flag } = res
if (flag) {
ElMessage.success((props.type === "add" || !form.value.id) ? "新增成功" : "修改成功");
if (props.type === 'edit') {
readOnly.value = true
} else if (props.type === 'add') {
form.value = {}
}
testParam.value = ""
encryptedValue.value = ""
emit('confirm', props.type)
}
})
}
// 密钥生成
const getKeyGeneration = () => {
const { encryption_type } = form.value;
getRandomValue({ type: encryption_type}).then((res) => {
const { flag, data } = res;
if (flag){
form.value.sectet_key_value = data;
}
});
};
// 测试
const getKeyText = () => {
const { encryption_type } = form.value;
if (!encryption_type) {
return ElMessage.error("密钥值不能为空!");
}
const data = {
param: testParam.value,
type: encryption_type,
secret_key: form.value.sectet_key_value,
}
testEncryption(data).then((res) => {
const { flag, data } = res;
if (flag){
encryptedValue.value = data;
}
});
}
// 分类称验证
const validateRulename = (rule, value, callback) => {
const state = keyNameList.value.includes(value);
if (state) {
callback(new Error('加密名称已存在'));
} else {
callback();
}
emit("confirm");
};
watch(
() => props.type,
(newVal) => {
readOnly.value = props.type === "edit" ? true : false;
},
{ deep: true, immediate: true }
);
watch(
() => props.itemData,
(newVal) => {
if (props.itemData) {
const data = JSON.parse(JSON.stringify(props.itemData));
form.value = { ...form.value, ...data };
if (props.type === 'edit' && data) {
keyNameList.value = keyNameList.value.filter(item => item !== data.secret_key_name)
}
}
},
{ deep: true, immediate: true }
);
watch(
() => props.keyNameDict,
(newVal) => {
keyNameList.value = props.keyNameDict
const data = JSON.parse(JSON.stringify(props.itemData));
if (props.type === 'edit' && data) {
keyNameList.value = keyNameList.value.filter(item => item !== data.secret_key_name)
}
},
{ deep: true, immediate: true }
);
</script>
<template>
<div>
<el-form ref="formRef" :model="modelValue" label-width="100px" :disabled="readOnly">
<el-form-item label="密钥名称" required>
<el-input v-model="modelValue.name"></el-input>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" :disabled="readOnly">
<el-form-item label="密钥名称" prop="secret_key_name" required :rules="[{ required: true, message: '请输入加密名称', trigger:'blur' },{ required: true, validator: validateRulename, trigger:'blur' }]">
<el-input v-model="form.secret_key_name"></el-input>
</el-form-item>
<el-form-item label="加密算法">
<el-input v-model="modelValue.name" disabled></el-input>
<el-input v-model="form.encryption_name" disabled></el-input>
</el-form-item>
<el-form-item label="密钥值" required>
<el-form-item label="密钥值" prop="sectet_key_value" required>
<div style="width: 100%;display: flex;align-items: center;">
<el-input v-model="modelValue.name" style="flex: 1;"></el-input>
<el-button type="primary" style="margin-left: 8px;" v-if="!readOnly">密钥生成</el-button>
<el-input v-model="form.sectet_key_value" disabled style="flex: 1;"></el-input>
<el-button type="primary" style="margin-left: 8px;" @click="getKeyGeneration" v-if="!readOnly">密钥生成</el-button>
</div>
</el-form-item>
<el-form-item label="测试">
<div style="width: 100%;display: flex;align-items: center;">
<el-input v-model="modelValue.name" style="flex: 1;"></el-input>
<el-button type="primary" style="margin-left: 8px;" v-if="!readOnly">测试</el-button>
<el-input v-model="testParam" style="flex: 1;"></el-input>
<el-button type="primary" style="margin-left: 8px;" @click="getKeyText" v-if="!readOnly">测试</el-button>
</div>
</el-form-item>
<el-form-item label="加密后的值">
<el-input v-model="modelValue.name" disabled></el-input>
<el-input v-model="encryptedValue" disabled></el-input>
</el-form-item>
</el-form>
<div class="btn">
......@@ -91,7 +193,7 @@ const confirm = () => {
<style lang="scss" scoped>
.el-form-item {
margin-bottom: 8px;
margin-bottom: 15px;
}
.btn {
padding: 20px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论