Commit 2b60e6ce by 周海峰

项目加密设置页面

parent 755912ad
......@@ -889,6 +889,93 @@ export function queryExtendColumnSize(data) {
})
}
/**
* 查询加密类型
* @param {*} data
* @returns {"code":"200","msg":"","totalCount":0,"flag":true,"data":["jdbc","webhdfs"]}
*/
export function enctypes(data) {
return request({
url: '/core/tablerule/enctypes',
method: 'post',
data: data
})
}
/**
* 查询后缀
* @param {*} data
* @returns
* {
* "code": "POP_00014",
* "msg": "成功。",
* "totalCount": 0,
* "flag": true,
* "data": {
* "cipherSuffix": "_cipher",
* "initialSuffix": "_initial",
* "copySuffix": "_copy"
* }
* }
*/
export function queryPostfix(data) {
return request({
url: '/core/encryption/queryPostfix',
method: 'post',
data: data
})
}
/**
* 查询版本
* @param {*} data id
* @returns
* {
* "code": "POP_00014",
* "msg": "成功。",
* "totalCount": 0,
* "flag": true,
* "data": [
* {
* "value": "TaskVersion",
* "text": "任务版本",
* "flag": null,
* "filePath": null,
* "id": null,
* "dbType": null,
* "schmeid": null,
* "dataSystemId": null,
* "tid": null
* },
* {
* "value": "null",
* "text": "无版本",
* "flag": null,
* "filePath": null,
* "id": null,
* "dbType": null,
* "schmeid": null,
* "dataSystemId": null,
* "tid": null
* }
* ]
* }
*/
export function queryversion(data) {
return request({
url: '/core/fieldscopedata/queryversion',
method: 'post',
data: data
})
}
//=========== 点击字段的设置===========开始
/**
......@@ -1037,9 +1124,51 @@ export function encryptionQuery(data) {
return request({
url: '/core/encryption/query',
method: 'get',
data: data
query: data
})
}
//=========== 点击字段的设置===========结束
/**
* 删除多余列(表字段)
* @param {*} data
* @returns
*/
export function delTableColumn(data) {
return request({
url: '/switchfield/delTableColumn',
method: 'POST',
data: data
})
}
/**
* 保存加密配置
* @param {*} data
* {
* datasystemid: '',
* projectId: '',
* map: {
* ry#|#sys_user#|#dept_id: {
* columnType: "BIGINT",
* describe_info: "11",
* encdigit: "0",
* encryptionSecretKeyId: "",
* flag: "0",
* note: "部门ID",
* realitycolumnsize: "19",
* twoindex: "0"
* }
* }
* @returns
*/
export function save(data) {
return request({
url: '/core/encryptionconfig/save',
method: 'POST',
data: data
})
}
<template>
<div class="basic-info-tab">
<el-descriptions
title="系统基本信息"
title=""
border
:column="1"
size="medium"
>
<el-descriptions-item label="项目">若依配测系统</el-descriptions-item>
<el-descriptions-item label="数据源">若依配测系统</el-descriptions-item>
<el-descriptions-item label="数据源类型">MYSQL</el-descriptions-item>
<el-descriptions-item label="IP">172.19.1.166</el-descriptions-item>
<el-descriptions-item label="管理的SCHEMA">ry</el-descriptions-item>
<el-descriptions-item label="项目">{{ nodeInfo.projectName || ''}}</el-descriptions-item>
<el-descriptions-item label="数据源">{{ nodeInfo.datasystemName || ''}}</el-descriptions-item>
<el-descriptions-item label="数据源类型">{{ nodeInfo.dbType || ''}}</el-descriptions-item>
<el-descriptions-item label="IP">{{ nodeInfo.ip || ''}}</el-descriptions-item>
<el-descriptions-item label="管理的SCHEMA">{{ nodeInfo.schema || ''}}</el-descriptions-item>
<el-descriptions-item label="字段数">{{ nodeInfo.totalFiledNum || ''}}</el-descriptions-item>
<el-descriptions-item label="加密表数量">{{ nodeInfo.encryptTableCount || ''}}</el-descriptions-item>
<el-descriptions-item label="加密字段数量">{{ nodeInfo.encryptFiledCount || ''}}</el-descriptions-item>
<el-descriptions-item label="未加密字段数量">{{ nodeInfo.unencryptTableCount || ''}}</el-descriptions-item>
<el-descriptions-item label="未加密字段数量">{{ nodeInfo.unencryptFiledCount || ''}}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<script setup>
// 可以留空,因为数据是静态的
import { computed } from 'vue'
const props = defineProps({
nodeData: {
type: Object,
default: () => ({})
}
})
// 可根据不同级别节点展示不同内容
const nodeType = computed(() => props.nodeData?.type)
const nodeInfo = computed(() => props.nodeData || {})
</script>
<style scoped>
......
......@@ -5,51 +5,68 @@
<el-form :inline="true" :model="filterForm" class="filter-form">
<el-form-item label="字段名过滤:">
<el-input
v-model="filterForm.fieldName"
v-model="filterForm.columnname"
placeholder="字段名模糊搜索"
clearable
style="width: 200px;"
/>
</el-form-item>
<el-form-item label="状态:">
<el-select style="width: 200px;" v-model="filterForm.status" placeholder="全部" clearable>
<el-option label="已加密" value="encrypted" />
<el-option label="未加密" value="unencrypted" />
<el-select style="width: 200px;" v-model="filterForm.flag" placeholder="全部" clearable>
<el-option label="全部" value="" />
<el-option v-for="item in encryptFlag" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<!-- <el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form-item> -->
</el-form>
</div>
<!-- 表格区域 -->
<div class="table-wrapper" style="position:relative;">
<el-table
:data="filteredTableData"
border
style="width: 100%; margin-top: 15px;"
max-height="500px"
:row-class-name="tableRowClassName"
>
<!-- 左浮动列 -->
<el-table-column prop="pk" label="主键" width="60" align="left" fixed />
<el-table-column prop="fieldName" label="字段名" width="150" align="left" fixed/>
<el-table-column prop="fieldType" label="字段类型" width="120" align="center" />
<el-table-column prop="length" label="长度" width="80" align="center" />
<el-table-column prop="algorithm" label="加密算法" width="120" align="center" />
<el-table-column label="主键" width="60" align="left" fixed >
<template #default="scope">
<el-tag v-if="scope.row.primarykey === '1'" type="success"></el-tag>
</template>
</el-table-column>
<el-table-column prop="columnname" label="字段名" width="180" />
<el-table-column prop="typename" label="类型" width="120" />
<el-table-column prop="columnsize" label="长度" width="80" />
<el-table-column prop="maskingrulename" label="加密算法" width="120" align="center" />
<el-table-column label="密钥" width="120" align="center">
<template #default="{ row }">
<el-button type="text" @click="openEncryptionDialog(row)">设置</el-button>
<el-button v-if="row.secretkeyName" link type="primary" >{{ row.secretkeyName }}</el-button>
<el-button v-else link type="primary" @click="openEncryptionDialog(row)">设置</el-button>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100" align="center">
<el-table-column label="状态" width="100" align="center">
<template #default="{ row }">
<el-tag v-if="row.status === 'encrypted'" type="success" size="small">已加密</el-tag>
<el-tag v-else type="info" size="small">未加密</el-tag>
<span>{{ getFlagName(row.flag) }}</span>
</template>
</el-table-column>
<!-- 操作 -->
<el-table-column label="操作" width="100" align="center">
<template #default="{ row }">
<el-button v-if="row.secretkeyName && ['1', '5', '44', '10', '11'].includes(row.flag)" type="primary" size="small" @click="handleEditField(row)">解密</el-button>
<el-button v-if="row.secretkeyName && ['4', '6', '7', '9', '12'].includes(row.flag)" type="primary" size="small" @click="handleEditField(row)">加密</el-button>
</template>
</el-table-column>
<!-- 源长度 -->
<el-table-column label="源长度" width="100" align="center">
<template #default="{ row }">
<el-button link type="success" v-if="row.secretkeyName">{{ row.columnsize }}</el-button>
</template>
</el-table-column>
<!-- 右浮动列 -->
<el-table-column prop="comment" label="注释" align="left" min-width="200" />
<el-table-column prop="remarks" label="注释" align="left" min-width="200" />
<el-table-column label="描述信息" align="left" fixed="right">
<template #default="{ row }">
<el-input
......@@ -61,23 +78,22 @@
</template>
</el-table-column>
<el-table-column prop="plaintextProcess" label="明文处理" align="left" fixed="right"/>
</el-table>
<div
v-if="!isEditing"
class="table-mask-click"
@click="handleTableMaskClick"
style="position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(255,255,255,0.01);z-index:11;cursor:not-allowed;"
></div>
</div>
<!-- 操作按钮区域 -->
<div class="action-buttons">
<el-button type="primary" @click="handleBatchEncrypt">批量加密</el-button>
<el-button type="primary" @click="handleBatchDecrypt">批量解密</el-button>
<el-button type="primary" @click="handleDeleteColumns">删除多余列</el-button>
<el-button
type="primary"
@click="toggleEditMode"
>
{{ isEditing ? '保存' : '编辑' }}
</el-button>
<el-button v-if="!isEditing" type="primary" @click="handleBatchEncrypt">批量加密</el-button>
<el-button v-if="!isEditing" type="primary" @click="handleBatchDecrypt">批量解密</el-button>
<el-button v-if="!isEditing" type="primary" @click="handleDeleteColumns">删除多余列</el-button>
<el-button v-if="!isEditing" type="primary" @click="toggleEditMode">编辑</el-button>
<el-button v-if="isEditing" type="info" @click="toggleEditMode">取消</el-button>
<el-button v-if="isEditing" type="primary" @click="handleSave">保存</el-button>
</div>
......@@ -92,33 +108,43 @@
<script setup>
import { ref, computed, reactive } from 'vue'
import EncryptionRuleDialog from './EncryptionRuleDialog.vue'
import { ElMessageBox } from 'element-plus'
const props = defineProps({
tableData: {
type: Array,
required: true,
default: () => [
{
pk: 'PK',
fieldName: 'table_id',
fieldType: 'BIGINT',
length: '19',
algorithm: '',
status: 'unencrypted',
comment: '编号',
description: '主键ID',
plaintextProcess: ''
},
// 其他数据行...
]
default: () => []
}
})
const emit = defineEmits(['batch-encrypt', 'batch-decrypt', 'delete-columns', 'edit-field', 'update-field'])
// 状态标识对象数组
const encryptFlag = [
{ value: '-2', label: '解密中' },
{ value: '-1', label: '加密中' },
{ value: '1', label: '加密完成' },
{ value: '5', label: '加密完成' },
{ value: '4', label: '加密失败' },
{ value: '44', label: '解密失败' },
{ value: '6', label: '解密完成' },
{ value: '7', label: '解密完成' },
{ value: '9', label: '加密替换失败' },
{ value: '10', label: '解密替换失败' },
{ value: '11', label: '解密校验失败' },
{ value: '12', label: '加密校验失败' }
]
/**
* 加密状态标识
*/
const getFlagName = (flag) => {
const found = encryptFlag.find(item => item.value === String(flag))
return found ? found.label : ''
}
// 搜索表单
const filterForm = reactive({
fieldName: '',
status: ''
flag: ''
})
// 编辑模式
......@@ -129,6 +155,7 @@ const tableRowClassName = ({ row, rowIndex }) => {
return row.status === 'encrypted' ? 'encrypted-row' : ''
}
// 处理搜索
const handleSearch = () => {
// 搜索逻辑已在计算属性中实现
......@@ -139,7 +166,6 @@ const toggleEditMode = () => {
isEditing.value = !isEditing.value
}
// 处理描述信息变更
const handleDescriptionChange = (row) => {
emit('update-field', row)
......@@ -161,15 +187,19 @@ const handleDeleteColumns = () => {
emit('delete-columns')
}
const handleSave = () => {
emit('save-changes')
}
// 过滤表格数据
const filteredTableData = computed(() => {
return props.tableData.filter(item => {
const matchesName = filterForm.fieldName
? item.fieldName.includes(filterForm.fieldName)
const matchesName = filterForm.columnname
? item.columnname.includes(filterForm.columnname)
: true
const matchesStatus = filterForm.status
? item.status === filterForm.status
const matchesStatus = filterForm.flag
? item.flag === filterForm.flag
: true
return matchesName && matchesStatus
......@@ -193,6 +223,10 @@ const handleRuleConfirm = (ruleData) => {
console.log('确认加密规则:', ruleData)
// 更新表格数据或调用API
}
const handleTableMaskClick = () => {
ElMessageBox.alert('当前是只读状态,编辑可点击编辑按钮进行编辑!')
}
</script>
<style scoped>
......@@ -235,4 +269,9 @@ const handleRuleConfirm = (ruleData) => {
color: #333;
font-weight: normal;
}
.table-mask-click {
/* 只拦截点击事件,不影响滚动和悬浮 */
pointer-events: auto;
}
</style>
\ No newline at end of file
......@@ -2,18 +2,23 @@
<div class="structure-tab">
<el-table
:data="tableData"
max-height="500px"
border
style="width: 100%"
:header-cell-style="{ background: '#f5f7fa', color: '#333' }"
:row-style="{ height: '40px' }"
:cell-style="{ padding: '8px 0', textAlign: 'center' }"
>
<el-table-column prop="pk" label="主键" width="120" fixed/>
<el-table-column prop="fieldName" label="字段名" width="180" />
<el-table-column prop="comment" label="注释" min-width="200" />
<el-table-column prop="fieldType" label="类型" width="120" />
<el-table-column prop="length" label="长度" width="120" />
<el-table-column prop="precision" label="精度" width="120" />
<el-table-column label="主键" width="80" fixed>
<template #default="scope">
<el-tag v-if="scope.row.primarykey === '1'" type="success"></el-tag>
</template>
</el-table-column>
<el-table-column prop="columnname" label="字段名" width="180" />
<el-table-column prop="remarks" label="注释" min-width="200" />
<el-table-column prop="typename" label="类型" width="120" />
<el-table-column prop="columnsize" label="长度" width="120" />
<el-table-column prop="decimaldigits" label="精度" width="120" />
</el-table>
</div>
</template>
......@@ -23,18 +28,7 @@ const props = defineProps({
tableData: {
type: Array,
required: true,
default: () => [
{ pk: '', fieldName: 'business_name', comment: '生成业务名', fieldType: 'VARCHAR', length: '30', precision: '' },
{ pk: '', fieldName: 'business_name_...', comment: '', fieldType: 'TEXT', length: '65535', precision: '' },
{ pk: '', fieldName: 'class_name', comment: '实体类名称', fieldType: 'VARCHAR', length: '100', precision: '' },
{ pk: '', fieldName: 'create_by', comment: '创建者', fieldType: 'VARCHAR', length: '64', precision: '' },
{ pk: '', fieldName: 'create_time', comment: '创建时间', fieldType: 'DATETIME', length: '19', precision: '' },
{ pk: '', fieldName: 'function_author', comment: '生成功能作者', fieldType: 'VARCHAR', length: '50', precision: '' },
{ pk: '', fieldName: 'function_name', comment: '生成功能名', fieldType: 'VARCHAR', length: '50', precision: '' },
{ pk: '', fieldName: 'gen_path', comment: '生成路径(不填...', fieldType: 'VARCHAR', length: '200', precision: '' },
{ pk: '', fieldName: 'gen_type', comment: '生成代码方式(0...', fieldType: 'CHAR', length: '1', precision: '' },
{ pk: '', fieldName: 'module_name', comment: '生成模块名', fieldType: 'VARCHAR', length: '30', precision: '' }
]
default: () => []
}
})
</script>
......
<template>
<div class="table-info-tab">
<!-- 表基本信息 -->
<el-descriptions
title="表基本信息"
title=""
border
:column="1"
size="medium"
>
<el-descriptions-item label="字段数">224</el-descriptions-item>
<el-descriptions-item label="加密表数量">0</el-descriptions-item>
<el-descriptions-item label="加密字段数量">0</el-descriptions-item>
<el-descriptions-item label="未加密表数量">20</el-descriptions-item>
<el-descriptions-item label="未加密字段数量">224</el-descriptions-item>
<el-descriptions-item label="操作人">admin</el-descriptions-item>
<el-descriptions-item label="操作时间">2023-05-15 14:30:22</el-descriptions-item>
<el-descriptions-item label="字段数">{{ nodeData.totalColumnCount }}</el-descriptions-item>
<el-descriptions-item label="未加密字段数量">{{ nodeData.unencryptColumnCount }}</el-descriptions-item>
<el-descriptions-item label="加密字段数量">{{ nodeData.encryptColumnCount }}</el-descriptions-item>
<el-descriptions-item label="操作人">{{ nodeData.operator }}</el-descriptions-item>
<el-descriptions-item label="操作时间">{{ nodeData.operationTime }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<script setup>
// 可以留空,因为数据是静态的
const props = defineProps({
nodeData: {
type: Object,
default: () => ({})
}
})
</script>
<style scoped>
......
......@@ -27,6 +27,18 @@
<span class="custom-tree-node">
<i :class="getNodeIcon(data.type)" class="node-icon"></i>
<span>{{ node.label }}</span>
<template v-if="data.type === 'category'">
<i class="el-icon-collection icon-category" style="margin-left:6px;color:#F7BA2A;font-size:16px;"></i>
</template>
<template v-if="data.type === 'system'">
<i class="el-icon-s-platform icon-system" style="margin-left:6px;color:#409EFF;font-size:16px;"></i>
</template>
<template v-if="data.type === 'database'">
<i class="el-icon-s-data icon-database" style="margin-left:6px;color:#67C23A;font-size:16px;"></i>
</template>
<template v-if="data.type === 'table'">
<i class="el-icon-s-grid icon-table" style="margin-left:6px;color:#E6A23C;font-size:16px;"></i>
</template>
</span>
</template>
</el-tree>
......@@ -125,9 +137,11 @@ const handleNodeClick = (data) => {
<style scoped>
.tree-filter-container {
max-height: 700px;
overflow-y: auto;
width: 100%;
height: 100%;
background-color: #f5f5f5;
/* background-color: #f5f5f5; */
padding: 10px;
border-right: 1px solid #e6e6e6;
}
......@@ -152,6 +166,19 @@ const handleNodeClick = (data) => {
color: #606266;
}
.icon-category {
vertical-align: middle;
}
.icon-system {
vertical-align: middle;
}
.icon-database {
vertical-align: middle;
}
.icon-table {
vertical-align: middle;
}
:deep(.el-tree-node__content) {
height: 36px;
}
......
......@@ -59,7 +59,7 @@
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
<span>Copyright © 2018-2025 All Rights Reserved.</span>
</div>
</div>
</template>
......@@ -86,8 +86,8 @@ const appStore = useAppStore()
const { proxy } = getCurrentInstance()
const loginForm = ref({
username: "admin",
password: "admin123",
username: "",
password: "",
rememberMe: false,
code: "",
uuid: ""
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论