Commit b0fcf7e3 by 周海峰

加密设置

parent 6568eb5f
...@@ -1241,8 +1241,62 @@ export function checkSingleEncOrDecColumn(data) { ...@@ -1241,8 +1241,62 @@ export function checkSingleEncOrDecColumn(data) {
*/ */
export function loadingColumn(data) { export function loadingColumn(data) {
return request({ return request({
url: '/core/encryption/loadingColumn', url: '/core/encryption/loadingColumn',
method: 'POST', method: 'POST',
data: data data: data
}) })
}
export function removeLoadingColumn(data) {
return request({
url: '/core/encryption/removeLoadingColumn',
method: 'POST',
data: data
})
}
/**
* 是否有明文数据处理
* @param {*} data
* @returns
*/
export function checkCanReload(data) {
return request({
url: '/core/encryption/checkCanReload',
method: 'POST',
data: data
})
}
/**
* 检查表字段是否有加密或解密配置
* @param {Object} data
* dataSystemId: "ff8081819882f3cd019883210d130015"
* flag: 0
* projectId: "fda50ea9-b7fa-4fe4-b368-eebeffded6b6"
* schema: "ry"
* tableName: "sys_dept"
* @returns {"code":"POP_00014","msg":"成功。","totalCount":0,"flag":true,"data":null}
*/
export function checkTableEncOrDecColumn(data) {
return request({
url: '/core/encryption/checkTableEncOrDecColumn',
method: 'POST',
data: data
})
}
/**
* 批量加密
* @param {Object} data
* @returns
*/
export function loadingTableParams(data) {
return request({
url: '/core/encryption/loadingTableParams',
method: 'POST',
data: data
})
} }
\ No newline at end of file
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
class="rule-radio" class="rule-radio"
> >
{{ rule.name }} {{ rule.name }}
<span style="color: aqua;">{{ rule.list.length || 0 }}</span> <span style="color: #409eff;">{{ rule.list.length || 0 }}</span>
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</div> </div>
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
<el-option v-for="item in encryptFlag" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in encryptFlag" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item> <span>
<el-button type="primary" @click="handleSearch">搜索</el-button> <el-button type="primary" :icon="Refresh" @click="handleSearch">刷新</el-button>
</el-form-item> --> </span>
</el-form> </el-form>
</div> </div>
<!-- 表格区域 --> <!-- 表格区域 -->
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
style="width: 100%; margin-top: 15px;" style="width: 100%; margin-top: 15px;"
max-height="500px" max-height="500px"
:row-class-name="tableRowClassName" :row-class-name="tableRowClassName"
@cell-click="handleCellClick"
:class="{ 'non-editing': !isEditing }"
> >
<!-- 左浮动列 --> <!-- 左浮动列 -->
<el-table-column label="主键" width="60" align="left" fixed > <el-table-column label="主键" width="60" align="left" fixed >
...@@ -53,10 +55,10 @@ ...@@ -53,10 +55,10 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 操作 --> <!-- 操作 -->
<el-table-column label="操作" width="100" align="center"> <el-table-column label="操作" width="100" align="center" class-name="operation-column">
<template #default="{ row }"> <template #default="{ row }">
<el-button v-if="row.secretkeyName && ['1', '5', '44', '10', '11'].includes(row.flag)" type="primary" size="small" @click="handleUnEncryptField(row)">解密</el-button> <el-button :disabled="isEditing" v-if="row.secretkeyName && ['1', '5', '44', '10', '11'].includes(row.flag)" type="primary" size="small" @click="handleDecryptField(row)">解密</el-button>
<el-button v-if="row.secretkeyName && ['0','4', '6', '7', '9', '12'].includes(row.flag)" type="primary" size="small" @click="handleEncryptField(row)">加密</el-button> <el-button :disabled="isEditing" v-if="row.secretkeyName && ['0','4', '6', '7', '9', '12'].includes(row.flag)" type="primary" size="small" @click="handleEncryptField(row)">加密</el-button>
</template> </template>
</el-table-column> </el-table-column>
<!-- 源长度 --> <!-- 源长度 -->
...@@ -77,19 +79,17 @@ ...@@ -77,19 +79,17 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="plaintextProcess" label="明文处理" align="left" fixed="right"/> <el-table-column prop="plaintextProcess" label="明文处理" align="left" fixed="right" class-name="plaintext-column">
<template #default="{ row }">
<el-button :disabled="isEditing" v-if="['1', '5'].includes(row.flag)" type="primary" size="small" @click="handlePlaintext(row)">处理</el-button>
</template>
</el-table-column>
</el-table> </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>
<!-- 操作按钮区域 --> <!-- 操作按钮区域 -->
<div class="action-buttons"> <div class="action-buttons">
<el-button v-if="!isEditing" type="primary" @click="handleBatchEncrypt">批量加密</el-button> <el-button v-if="!isEditing" type="primary" :loading="isBatchEncrypting" @click="handleBatchEncrypt">批量加密</el-button>
<el-button v-if="!isEditing" type="primary" @click="handleBatchDecrypt">批量解密</el-button> <el-button v-if="!isEditing" type="primary" :loading="isBatchDecrypting" @click="handleBatchDecrypt">批量解密</el-button>
<el-button v-if="!isEditing" type="primary" @click="handleDeleteColumns">删除多余列</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="primary" @click="toggleEditMode">编辑</el-button>
<el-button v-if="isEditing" type="info" @click="toggleEditMode">取消</el-button> <el-button v-if="isEditing" type="info" @click="toggleEditMode">取消</el-button>
...@@ -108,10 +108,15 @@ ...@@ -108,10 +108,15 @@
</template> </template>
<script setup> <script setup>
import { Refresh } from '@element-plus/icons-vue'
import { ref, computed, reactive, inject, nextTick} from 'vue' import { ref, computed, reactive, inject, nextTick} from 'vue'
import EncryptionRuleDialog from './EncryptionRuleDialog.vue' import EncryptionRuleDialog from './EncryptionRuleDialog.vue'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import { queryOriginalList, queryEncryptionList, hasRedundanceColumns, queryIsLike, queryEncDigit, save, delTableColumn, checkSingleEncOrDecColumn, loadingColumn } from '@/api/classification/classification.js' import { queryOriginalList, queryEncryptionList, hasRedundanceColumns,
queryIsLike, queryEncDigit, save, delTableColumn, checkSingleEncOrDecColumn,
loadingColumn, checkCanReload ,removeLoadingColumn, checkTableEncOrDecColumn,
loadingTableParams
} from '@/api/classification/classification.js'
const props = defineProps({ const props = defineProps({
// tableData: { // tableData: {
// type: Array, // type: Array,
...@@ -227,43 +232,23 @@ const toggleEditMode = () => { ...@@ -227,43 +232,23 @@ const toggleEditMode = () => {
* @param row * @param row
*/ */
const handleEncryptField = async (row) => { const handleEncryptField = async (row) => {
// 添加个确认
const ok = await ElMessageBox.confirm('确认要加密该字段吗?', '确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
if (!ok) return
// 处理加密逻辑 // 处理加密逻辑
const schema = currentNodeData.value.parent?.parent?.label const params = buildEncryptionParams(row, 0)
const tableName = currentNodeData.value.label
const key = `${schema}.${tableName}.${row.columnname}`
const params = {
columnName: row.columnname,
columnSize: String(row.columnsize),
columnType: row.typename,
dataSystemId: currentNodeData.value.parent?.parent?.tid,
flag: 0,
map: {
dataSystemId: currentNodeData.value.parent?.parent?.tid,
projectId: currentNodeData.value.parent?.parent?.parent?.project_id,
map: {
[key]: {
columnType: row.typename,
columnSize: String(row.columnsize),
describe_info: row.description || '',
encryptionSecretKeyId: row.secretkeyId,
flag: row.flag || '1'
}
}
},
primaryKeys: tableData.value.filter(item => item.primarykey === '1').map(item => item.columnname),
projectId: currentNodeData.value.parent?.parent?.parent?.project_id,
schema: schema,
secretKeyId: row.secretkeyId,
tableName: tableName
}
const result = await checkSingleEncOrDecColumn(params) const result = await checkSingleEncOrDecColumn(params)
if (result && result.code === 'POP_00014' && result.flag) { if (result && result.code === 'POP_00014' && result.flag) {
const loadingResult = await loadingColumn(params) const loadingResult = await loadingColumn(params)
if (loadingResult && loadingResult.code === 'POP_00014' && loadingResult.flag) { if (loadingResult && loadingResult.code === 'POP_00014' && loadingResult.flag) {
// 重新获取表格数据 // 重新获取表格数据
await getTableData() setTimeout(async () => {
await getTableData()
}, 2000)
// 退出编辑模式 // 退出编辑模式
isEditing.value = false isEditing.value = false
} else { } else {
...@@ -282,45 +267,183 @@ const handleEncryptField = async (row) => { ...@@ -282,45 +267,183 @@ const handleEncryptField = async (row) => {
/** /**
* 处理单个字段解密 * 处理单个字段解密
* @param row * @param row
*/ */
const handleUnEncryptField = (row) => { const handleDecryptField = (row) => {
// 处理解密逻辑 ElMessageBox.confirm('确认要解密该字段吗?', '确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
// 处理解密逻辑
const params = buildEncryptionParams(row, 1)
const result = await checkSingleEncOrDecColumn(params)
if (result && result.code === 'POP_00014' && result.flag) {
const loadingResult = await removeLoadingColumn(params)
if (loadingResult && loadingResult.code === 'POP_00014' && loadingResult.flag) {
// 重新获取表格数据
setTimeout(async () => {
await getTableData()
}, 2000)
// 退出编辑模式
isEditing.value = false
} else {
ElMessageBox.alert(loadingResult ? loadingResult.message : '解密失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
}
} else {
ElMessageBox.alert(result ? result.message : '解密失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
}
})
} }
// 批量加密 // 批量加密
const handleBatchEncrypt = () => { const isBatchEncrypting = ref(false);
emit('batch-encrypt') const handleBatchEncrypt = async() => {
} isBatchEncrypting.value = true;
try {
const params = buildBatchEncryptionParams(0);
// 验证是否有多余列
const checkResult = await checkTableEncOrDecColumn(params)
if (!checkResult) {
ElMessageBox.alert('加密失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
return
}
if (checkResult && checkResult.code === '9983') {
ElMessageBox.alert(checkResult.msg || '存在多余列,请先删除多余列', '提示', {
confirmButtonText: '确定',
type: 'info'
})
return
}
// 批量解密 await ElMessageBox.confirm('确认要批量加密选中的字段吗?', '确认', {
const handleBatchDecrypt = () => { confirmButtonText: '确定',
emit('batch-decrypt') cancelButtonText: '取消',
type: 'warning'
})
const loadingResult = await loadingTableParams(params)
if (loadingResult && loadingResult.code === 'POP_00014' && loadingResult.flag) {
setTimeout(async () => {
await getTableData()
}, 2000)
} else {
ElMessageBox.alert(loadingResult ? loadingResult.message : '加密失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
}
} catch (error) {
} finally {
isBatchEncrypting.value = false;
}
} }
// 删除多余列 /**
const handleDeleteColumns = async () => { * 构建批量加密请求参数
const res = await delTableColumn({ * @param flag
*/
const buildBatchEncryptionParams = (flag) => {
return {
projectId: currentNodeData.value.parent?.parent?.parent?.project_id, projectId: currentNodeData.value.parent?.parent?.parent?.project_id,
dataSystemId: currentNodeData.value.parent?.parent?.tid, dataSystemId: currentNodeData.value.parent?.parent?.tid,
schema: currentNodeData.value.parent?.parent?.label, schema: currentNodeData.value.parent?.parent?.label,
tableName: currentNodeData.value.label tableName: currentNodeData.value.label,
}) flag: flag
if (res && res.code === 'POP_00014' && res.flag) { }
ElMessageBox.alert('删除成功', '成功', { }
confirmButtonText: '确定',
type: 'success' /**
}) * 批量解密
// 重新获取表格数据 */
await getTableData() const isBatchDecrypting = ref(false);
} else { const handleBatchDecrypt = async () => {
ElMessageBox.alert(res ? res.message : '删除失败,请重试', '错误', { isBatchDecrypting.value = true;
try {
const params = buildBatchEncryptionParams(1);
const checkResult = await checkTableEncOrDecColumn(params);
if (!checkResult) {
ElMessageBox.alert('解密失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
});
return;
}
if (checkResult && checkResult.code === '9983') {
ElMessageBox.alert(checkResult.msg || '存在多余列,请先删除多余列', '提示', {
confirmButtonText: '确定',
type: 'info'
});
return;
}
await ElMessageBox.confirm('确认要批量解密选中的字段吗?', '确认', {
confirmButtonText: '确定', confirmButtonText: '确定',
type: 'error' cancelButtonText: '取消',
}) type: 'warning'
});
const loadingResult = await loadingTableParams(params);
if (loadingResult && loadingResult.code === 'POP_00014' && loadingResult.flag) {
setTimeout(async () => {
await getTableData();
}, 2000);
} else {
ElMessageBox.alert(loadingResult ? loadingResult.message : '解密失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
});
}
} catch (error) {
console.error(error);
} finally {
isBatchDecrypting.value = false;
} }
} }
// 删除多余列
const handleDeleteColumns = async () => {
ElMessageBox.confirm('确认删除多余列吗?', '提示', {
type: 'warning'
}).then(async () => {
// 调用删除接口
const res = await delTableColumn({
projectId: currentNodeData.value.parent?.parent?.parent?.project_id,
dataSystemId: currentNodeData.value.parent?.parent?.tid,
schema: currentNodeData.value.parent?.parent?.label,
tableName: currentNodeData.value.label
})
if (res && res.code === 'POP_00014' && res.flag) {
ElMessageBox.alert('删除成功', '成功', {
confirmButtonText: '确定',
type: 'success'
})
// 重新获取表格数据
await getTableData()
} else {
ElMessageBox.alert(res ? res.message : '删除失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
}
}).catch(() => {})
}
/** /**
* 保存修改 * 保存修改
*/ */
...@@ -409,8 +532,6 @@ const filteredTableData = computed(() => { ...@@ -409,8 +532,6 @@ const filteredTableData = computed(() => {
}) })
}) })
const showEncryptionDialog = ref(false) const showEncryptionDialog = ref(false)
const currentField = ref({}) const currentField = ref({})
...@@ -515,11 +636,103 @@ const handleRuleReset = () => { ...@@ -515,11 +636,103 @@ const handleRuleReset = () => {
} }
} }
const handleTableMaskClick = () => { /**
ElMessageBox.alert('当前是只读状态,编辑可点击编辑按钮进行编辑!') * 明文处理
* @param row
*/
const handlePlaintext = async (row) => {
console.log('处理明文', row)
ElMessageBox.confirm('确认处理明文吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
// 处理明文逻辑
const params = buildEncryptionParams(row, 0)
const checkCanReloadRes = await checkCanReload(params)
if(!checkCanReloadRes ){
ElMessageBox.alert('验证失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
return
}
if(checkCanReloadRes && checkCanReloadRes.code === '-1'){
ElMessageBox.alert(checkCanReloadRes.msg || '处理明文失败,请重试', '错误', {
confirmButtonText: '确定',
type: 'error'
})
return
}
//处理逻辑
}).catch(() => {
// 取消处理
})
} }
/** /**
* 处理单元格点击
*/
const handleCellClick = (row, column) => {
// 当不是编辑状态时
if (!isEditing.value) {
// 如果点击的不是"操作"列和"明文处理"列,则提示
if (column.label !== '操作' && column.label !== '明文处理') {
ElMessageBox.alert('非编辑状态,请点击编辑按钮后进行编辑', '提示', {
confirmButtonText: '确定',
type: 'info'
})
}
} else {
// 当是编辑状态时,如果点击的是"操作"列或"明文处理"列,则不响应
if (column.label === '操作' || column.label === '明文处理') {
return
}
}
}
/**
* 构建解密/加密参数
* @param {Object} row - 当前行数据
* @returns {Object} params - 构建的参数对象
*/
const buildEncryptionParams = (row, isEncrypt) => {
const schema = currentNodeData.value.parent?.parent?.label;
const tableName = currentNodeData.value.label;
const key = `${schema}.${tableName}.${row.columnname}`;
return {
columnName: row.columnname,
columnSize: String(row.columnsize),
columnType: row.typename,
dataSystemId: currentNodeData.value.parent?.parent?.tid,
flag: isEncrypt, // 加密是0,解密是1
map: {
dataSystemId: currentNodeData.value.parent?.parent?.tid,
projectId: currentNodeData.value.parent?.parent?.parent?.project_id,
map: {
[key]: {
columnType: row.typename,
columnSize: String(row.columnsize),
describe_info: row.description || '',
encryptionSecretKeyId: row.secretkeyId,
},
},
},
primaryKeys: tableData.value.filter((item) => item.primarykey === '1').map((item) => item.columnname),
projectId: currentNodeData.value.parent?.parent?.parent?.project_id,
schema: schema,
secretKeyId: row.secretkeyId,
tableName: tableName,
};
};
/**
* 暴露给父组件的数据 * 暴露给父组件的数据
*/ */
defineExpose({ defineExpose({
...@@ -540,7 +753,11 @@ defineExpose({ ...@@ -540,7 +753,11 @@ defineExpose({
.filter-form { .filter-form {
display: flex; display: flex;
align-items: center; justify-content: space-between; /* Align the refresh button to the right */
}
.filter-form span {
margin-left: auto; /* Push the refresh button to the right */
} }
.action-buttons { .action-buttons {
...@@ -548,6 +765,10 @@ defineExpose({ ...@@ -548,6 +765,10 @@ defineExpose({
text-align: center; text-align: center;
} }
.action-buttons .el-button {
width: 120px; /* 设置统一宽度 */
}
:deep(.el-table .encrypted-row) { :deep(.el-table .encrypted-row) {
background-color: #f0f9eb; background-color: #f0f9eb;
} }
...@@ -569,8 +790,26 @@ defineExpose({ ...@@ -569,8 +790,26 @@ defineExpose({
font-weight: normal; font-weight: normal;
} }
.table-mask-click { /* 非编辑状态下的表格样式 */
/* 只拦截点击事件,不影响滚动和悬浮 */ .non-editing {
pointer-events: auto; :deep(.el-button) {
&[disabled] {
cursor: not-allowed;
}
}
:deep(.el-table__cell) {
&:not(.operation-column):not(.plaintext-column) {
cursor: not-allowed;
}
}
} }
/* 编辑状态下的表格样式 */
:deep(.el-table__cell) {
&.operation-column, &.plaintext-column {
cursor: not-allowed;
}
}
</style> </style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论