Commit 5897447f by ningjihai

脱敏策略添加

parent c0126dce
import request from '@/utils/request' import request from '@/utils/request'
/** /**
* 资产库 - 查询用户列表 * 脱敏策略 - 列表查询
* @param {*} query * @param {*} query
* @returns * @returns
*/ */
export function queryUser(query) { export function getTableList(data) {
return request({ return request({
url: '/console/user/queryAll', url: '/core/desensitizationStrategy/loadDesensitizationStrategy',
method: 'get', method: 'post',
params: query data: data
}) })
} }
/**
* 资产库 - 查询列表
* @param {*} query
* @returns
*/
export function queryAll(query) { export function queryAll(query) {
return request({ return request({
url: '/core/datasystem/queryAll', url: '/console/role/queryAll',
method: 'get', method: 'get',
params: query params: query
}) })
} }
/**
* 资产库 - 数据源明细 export function desensitizationruleQuery(query) {
* @param {*} query
* @returns
*/
export function initEdit(query) {
return request({ return request({
url: '/core/datasystem/initEdit', url: '/core/desensitizationrule/query?dataarea=',
method: 'get', method: 'get',
params: query params: query
}) })
} }
export function queryversion(data) {
return request({
url: '/core/fieldscopedata/queryversion',
method: 'post',
data: data
})
}
export function queryTask(data) {
return request({
url: '/core/fieldscopedata/queryTask',
method: 'post',
data: data
})
}
/**
* 资产库 - 查询数据库版本 export function queryProVersion(data) {
* @param {*} query return request({
* @returns url: '/core/fieldscopedata/queryProVersion',
*/ method: 'post',
export function queryDatadis(query) { data: data
})
}
export function queryTaskVersion(query) {
return request({ return request({
url: '/core/datadis/queryAll', url: '/core/fieldscopedata/queryTaskVersion',
method: 'get', method: 'get',
params: query params: query
}) })
} }
/** export function tdatasourceQuery(data) {
* 资产库 - 数据库版本检测
* @param {*} data
* @returns
*/
export function checkVersion(data) {
return request({ return request({
url: '/core/datasystem/checkVersion', url: '/core/tdatasource/query',
method: 'post', method: 'post',
data: data data: data
}) })
} }
export function queryShemas(data) {
/**
* 资产库 - 测试数据源名称是否重复
* @param {*} data
* @returns
*/
export function checkRepeatName(data) {
return request({ return request({
url: '/core/datasystem/checkRepeatName', url: '/core/modifysubsettask/queryShemas',
method: 'post', method: 'post',
data: data data: data
}) })
} }
/** export function rowsensitivelevel(tableName,data) {
* 资产库 - 测试连接
* @param {*} data
* @returns
*/
export function testConnect(data) {
return request({ return request({
url: '/core/datasystem/testConnect', url: '/core/rowsensitivelevel/' + tableName,
method: 'post', method: 'post',
data: data data: data
}) })
} }
/** export function queryDesensitizationTables(data) {
* 资产库 - 新增修改接口
* @param {*} data
* @returns
*/
export function add(data) {
return request({ return request({
url: '/core/datasystem/add', url: '/core/rowsensitivelevel/queryDesensitizationTables',
method: 'post', method: 'post',
data: data data: data
}) })
} }
/** export function queryOriginalList(data) {
* 资产库 - 关联检测
* @param {*} data
* @returns
*/
export function checkDatasystemUsed(data) {
return request({ return request({
url: '/core/datasystem/checkDatasystemUsed', url: '/core/encryptionconfig/queryOriginalList',
method: 'post', method: 'post',
data: data data: data
}) })
} }
/** export function desensitizationStrategyDetails(data) {
* 资产库 - 删除数据源
* @param {*} data
* @returns
*/
export function del(data) {
return request({ return request({
url: '/core/datasystem/del', url: '/core/desensitizationStrategy/desensitizationStrategyDetails',
method: 'post', method: 'post',
data: data data: data
}) })
} }
/**
* 资产库 - 查询字符编码
* @param {*} query
* @returns
*/
export function queryCharset(query) {
return request({
url: '/core/datasystem/queryCharset',
method: 'get',
params: query
})
}
\ No newline at end of file
...@@ -87,7 +87,7 @@ watch([currentNodeLevel, currentNodeData, activeTab], async ([level, node, tab]) ...@@ -87,7 +87,7 @@ watch([currentNodeLevel, currentNodeData, activeTab], async ([level, node, tab])
}) })
onMounted(async () => { onMounted(async () => {
projectId.value = route.query.projectId || 'df345570-d044-47b3-a2c6-0ff265f89b80' projectId.value = route.query.projectId || sessionStorage.getItem('projectId') || 'df345570-d044-47b3-a2c6-0ff265f89b80'
if (projectId.value) { if (projectId.value) {
// 1. 查询数据源列表 // 1. 查询数据源列表
const res = await query({ project_id: projectId.value }) const res = await query({ project_id: projectId.value })
......
...@@ -34,9 +34,9 @@ function onSearch() { ...@@ -34,9 +34,9 @@ function onSearch() {
// 重置 // 重置
function onReset(formRef: FormInstance) { function onReset(formRef: FormInstance) {
queryForm.value.title = '' queryForm.value.strategyName = ''
queryForm.value.remark = '' queryForm.value.remarks = ''
queryForm.value.status = '' queryForm.value.state = ''
emit('reset', formRef) emit('reset', formRef)
} }
...@@ -49,9 +49,9 @@ function onReset(formRef: FormInstance) { ...@@ -49,9 +49,9 @@ function onReset(formRef: FormInstance) {
:model="queryForm" :model="queryForm"
@search="onSearch" @search="onSearch"
@reset="onReset"> @reset="onReset">
<el-form-item label="策略名" prop="title"> <el-form-item label="策略名" prop="strategyName">
<el-input <el-input
v-model="queryForm.title" v-model="queryForm.strategyName"
placeholder="请输入策略名" placeholder="请输入策略名"
clearable clearable
/> />
...@@ -59,23 +59,23 @@ function onReset(formRef: FormInstance) { ...@@ -59,23 +59,23 @@ function onReset(formRef: FormInstance) {
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remarks">
<el-input <el-input
v-model="queryForm.remark" v-model="queryForm.remarks"
placeholder="请输入备注" placeholder="请输入备注"
clearable clearable
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="state">
<el-select <el-select
v-model="queryForm.status" v-model="queryForm.state"
placeholder="请选择状态" placeholder="请选择状态"
clearable clearable
> >
<el-option label="全部" value="" />
<el-option label="已启用" value="active" /> <el-option label="已启用" value="1" />
<el-option label="未启用" value="inactive" /> <el-option label="未启用" value="0" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</page-wrapper-search> </page-wrapper-search>
......
<script setup name="ProjectManageList"> <script setup name="ProjectManageList">
import { getCurrentInstance, reactive, ref, toRefs } from 'vue' import { getCurrentInstance, reactive, ref, toRefs, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import useAppStore from '@/store/modules/app' import useAppStore from '@/store/modules/app'
import usePermissionStore from '@/store/modules/permission'
import { changeRoute } from '@/utils/switchRoute' import { changeRoute } from '@/utils/switchRoute'
import QueryForm from './QueryForm.vue' import QueryForm from './QueryForm.vue'
import AddStrategyDialog from './modules/AddStrategyDialog.vue' import StrategyAddDialog from './modules/StrategyAddDialog.vue' // 统一对话框组件
import StrategyDetailDialog from './modules/StrategyDetailDialog.vue' // 引入详情组件
import EditStrategyDialog from './modules/EditStrategyDialog.vue' // 引入编辑策略组件 import {
getTableList,
queryAll
} from '@/api/desensitizationStrategy'
const appStore = useAppStore() const appStore = useAppStore()
const permissionStore = usePermissionStore()
const router = useRouter() const router = useRouter()
const emit = defineEmits(['page']) const emit = defineEmits(['page'])
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
// 新增策略弹窗引用 const strategyDialogRef = ref()
const addStrategyDialogRef = ref()
onMounted(() => {
handleQuery()
queryAll().then(res => {
if (res.flag) {
roleList.value = res.data
} else {
ElMessage.error(res.msg)
}
}).catch(err => {
ElMessage.error(err.msg)
})
})
function onReset(formQuery) { function onReset(formQuery) {
console.log('onReset')
formQuery.resetFields() formQuery.resetFields()
handleQuery() handleQuery()
} }
const roleList = ref([])
function onQuery() { function onQuery() {
handleQuery() handleQuery()
} }
// 搜索按钮操作 // 搜索按钮操作
function handleQuery() { function handleQuery() {
console.log('queryParams',queryParams.value) queryParams.value.pageno = 1
queryParams.value.pageNum = 1
getList() getList()
} }
const data = reactive({ const data = reactive({
queryParams: { queryParams: {
pageNum: 1, pageno: 1,
pageSize: 8 pagesize: 8,
remarks: '',
state: '',
strategyName: ''
} }
}) })
// 表格数据 // 表格数据
const { queryParams } = toRefs(data) const { queryParams } = toRefs(data)
const total = ref(3) const total = ref(0)
const loading = ref(false) const loading = ref(false)
const projectId = ref(sessionStorage.getItem('projectId'))
// 查询列表 // 查询列表
function getList() { function getList() {
loading.value = true loading.value = true
setTimeout(() => { getTableList({
loading.value = false pageno: queryParams.value.pageno,
}, 3000) pagesize: queryParams.value.pagesize,
projectid: projectId.value,
remarks: queryParams.value.remarks,
roleGroup: '',
state: queryParams.value.state,
strategyName: queryParams.value.strategyName
}).then(res => {
if (res.flag) {
tableData.value = res.data.list
total.value = res.data.total
}
loading.value = false
})
} }
function pageProjectManage() { function pageProjectManage() {
changeRoute() changeRoute()
router.push({ router.push({
path: '/project/Project' path: '/project/Project'
}) })
} }
const strategyAddDialogRef = ref()
/** /**
* 新增策略 * 新增策略
*/ */
function handleAdd(){ function handleAdd() {
addStrategyDialogRef.value.openDialog()
} dialog.value.title = '添加策略'
const tableData = ref([ dialog.value.type = 'addtactics'
{
index: 1, strategyAddDialogRef.value.openDialog('addtactics')
id: '1', }
name: '测试',
remark: '123', const tableData = ref([])
createTime: '2025-08-21 16:55:30', const dialog = ref({
creator: 'admin', title: '',
status: '1' type: ''
} })
]) /**
const strategyDetailDialogRef = ref() * 查看策略详情
*/
const showDetail = (row) => { const showDetail = (row) => {
strategyDetailDialogRef.value.openDialog(row)
dialog.value.title = '详情'
dialog.value.type = 'info'
strategyDialogRef.value.openDialog('detail', row)
} }
// 编辑策略弹窗引用
const editStrategyDialogRef = ref() /**
* 编辑策略
*/
const editStrategy = (row) => { const editStrategy = (row) => {
console.log('编辑策略:', row)
editStrategyDialogRef.value.openDialog(row)
dialog.value.title = '编辑策略'
dialog.value.type = 'edit'
strategyAddDialogRef.value.openDialog('edit', row)
} }
/**
* 删除策略
*/
const deleteStrategy = (row) => { const deleteStrategy = (row) => {
ElMessageBox.confirm( ElMessageBox.confirm(
`确定删除【${row.name}】策略吗?`, `确定删除【${row.strategyName}】策略吗?`,
'删除确认', '删除确认',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning'
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
instance.confirmButtonLoading = true
// 这里调用实际删除API
setTimeout(() => {
done()
// 删除成功后刷新数据或从tableData中移除
tableData.value = tableData.value.filter(item => item.index !== row.index)
}, 1000)
} else {
done()
}
}
} }
).then(() => { ).then(() => {
ElMessage({ deleteStrategyApi(row.id).then(res => {
type: 'success', if (res.flag) {
message: '删除成功', ElMessage.success('删除成功')
getList() // 刷新列表
} else {
ElMessage.error(res.msg)
}
}).catch(err => {
ElMessage.error('删除失败')
}) })
}).catch(() => { }).catch(() => {
// 用户取消删除 // 用户取消删除
}) })
} }
/**
* 启用/禁用策略
*/
const toggleStatus = (row) => { const toggleStatus = (row) => {
console.log('启用/禁用:', row) const newStatus = row.status === '1' ? '0' : '1'
// changeRoleStatus(row.roleId, row.status).then(() => { const action = newStatus === '1' ? '启用' : '禁用'
// ElMessage({
// type: 'success', ElMessageBox.confirm(
// message: '操作成功', `确定要${action}${row.strategyName}】策略吗?`,
// }) `${action}确认`,
// }) {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
// 调用启用/禁用API
// changeStrategyStatus(row.id, newStatus).then(res => {
// if (res.flag) {
// ElMessage.success(`${action}成功`)
// getList() // 刷新列表
// } else {
// ElMessage.error(res.msg)
// }
// }).catch(err => {
// ElMessage.error(`${action}失败`)
// })
ElMessage.info(`${action}功能待实现`)
}).catch(() => {
// 用户取消操作
})
} }
</script> </script>
...@@ -162,18 +224,20 @@ const toggleStatus = (row) => { ...@@ -162,18 +224,20 @@ const toggleStatus = (row) => {
v-model="queryParams" v-model="queryParams"
@query="onQuery" @query="onQuery"
@reset="onReset"/> @reset="onReset"/>
<el-table
<el-table
:data="tableData" :data="tableData"
border border
style="width: 100%" style="width: 100%"
:header-cell-style="{ background: '#f5f7fa', color: '#606266' }" :header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
v-loading="loading"
> >
<el-table-column prop="index" label="序号" width="80" align="center" /> <el-table-column prop="index" label="序号" width="80" align="center" />
<el-table-column prop="name" label="策略名称" min-width="120" /> <el-table-column prop="strategyName" label="策略名称" min-width="120" />
<el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip /> <el-table-column prop="remarks" label="备注" min-width="120" show-overflow-tooltip />
<el-table-column prop="createTime" label="创建时间" min-width="180" /> <el-table-column prop="createtime" label="创建时间" min-width="180" />
<el-table-column prop="creator" label="创建人" width="120" /> <el-table-column prop="createuser" label="创建人" width="120" />
<el-table-column prop="status" label="状态" width="100" align="center"> <el-table-column prop="statezh" label="状态" width="100" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-tag :type="row.status === '1' ? 'success' : 'info'"> <el-tag :type="row.status === '1' ? 'success' : 'info'">
{{ row.status === '1' ? '已启用' : '未启用' }} {{ row.status === '1' ? '已启用' : '未启用' }}
...@@ -198,20 +262,15 @@ const toggleStatus = (row) => { ...@@ -198,20 +262,15 @@ const toggleStatus = (row) => {
<pagination <pagination
v-show="total > 0" v-show="total > 0"
:total="total" :total="total"
v-model:page="queryParams.pageNum" v-model:page="queryParams.pageno"
v-model:limit="queryParams.pageSize" v-model:limit="queryParams.pagesize"
@pagination="getList" @pagination="getList"
/> />
</div> </div>
</div> </div>
<!-- 新增策略弹窗 --> <!-- 统一策略对话框组件 -->
<AddStrategyDialog ref="addStrategyDialogRef" /> <StrategyAddDialog :title="dialog.title" ref="strategyAddDialogRef" @refresh="getList" />
<!-- 详情弹窗 -->
<StrategyDetailDialog ref="strategyDetailDialogRef" />
<!-- 编辑策略弹窗 -->
<EditStrategyDialog ref="editStrategyDialogRef" />
</div> </div>
</template> </template>
......
<template>
<el-dialog
v-model="dialogVisible"
:title="currentStep === 1 ? '添加策略 - 步骤1/2' : '添加策略 - 步骤2/2'"
width="80%"
:before-close="handleClose"
>
<!-- 步骤1:基本信息 -->
<div v-if="currentStep === 1" class="step-content">
<el-form :model="formData" :rules="rules" ref="step1Form" label-width="120px">
<el-form-item label="策略名称" prop="name">
<el-input
v-model="formData.name"
placeholder="请输入策略名称"
clearable
/>
</el-form-item>
<el-form-item label="备注">
<el-input
v-model="formData.remark"
type="textarea"
:rows="4"
placeholder="请输入策略备注信息"
maxlength="200"
show-word-limit
/>
</el-form-item>
</el-form>
</div>
<!-- 步骤2:字段设置 -->
<div v-else class="step-content">
<div class="version-select">
<span>根据发现版本设置脱敏:</span>
<div class="flex-container align-center">
<div>
选择发现版本
</div>
<el-select class="version-select-content flex1" v-model="selectedVersion" placeholder="选择发现版本">
<el-option label="无版本" value="" />
<el-option
v-for="version in versions"
:key="version"
:label="version"
:value="version"
/>
</el-select>
</div>
</div>
<div class="field-selection">
<div class="tree-container">
<el-tree
:data="treeData"
:props="treeProps"
@node-click="handleNodeClick"
highlight-current
/>
</div>
<el-divider direction="vertical" />
<div class="table-container">
<el-table :data="tableFields" border style="width: 100%" height="400px">
<el-table-column prop="isPk" label="主键" width="80" align="center" fixed>
<template #default="{ row }">
<span v-if="row.isPk">PK</span>
</template>
</el-table-column>
<el-table-column prop="name" label="字段名" min-widthwidth="150" />
<el-table-column prop="comment" label="注释" min-width="150" />
<el-table-column prop="dataType" label="数据域" min-width="120" />
<el-table-column prop="algorithm" label="脱敏算法" min-width="180" />
<el-table-column label="操作" width="80" align="center" fixed="right">
<template #default="{ row }">
<el-button type="text" size="small" @click="handleSet(row)"
>设置</el-button
>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button
v-if="currentStep === 1"
type="primary"
@click="handleNextStep"
>下一步</el-button
>
<el-button
v-else
type="primary"
@click="handlePrevStep"
>上一步</el-button
>
<el-button
v-if="currentStep === 2"
type="primary"
@click="handleConfirm"
>确定</el-button
>
</div>
</template>
</el-dialog>
<!-- 脱敏规则设置弹窗 -->
<DesensitizationRuleDialog
v-model="desensitizationDialogVisible"
:current-field="currentField"
@confirm="handleRuleConfirm"
/>
</template>
<script setup>
import DesensitizationRuleDialog from './DesensitizationRuleDialog.vue';
import { ref, reactive } from 'vue';
import { ElMessage } from 'element-plus';
const dialogVisible = ref(false);
const currentStep = ref(1);
const desensitizationDialogVisible = ref(false);
const currentField = ref({});
// 表单数据
const formData = reactive({
name: '',
remark: '',
});
// 表单验证规则
const rules = reactive({
name: [
{ required: true, message: '请填写策略名称', trigger: 'blur' },
],
});
// 步骤2数据
const selectedVersion = ref('');
const versions = ref(['v1.0', 'v2.0']);
const treeData = ref([
{
id: 'system1',
label: '若依测试系统1',
children: [
{
id: 'ry',
label: 'ry',
children: [
{
id: 'tables',
label: '表',
children: [
{
id: 'gen_table',
label: 'gen_table',
type: 'table'
},
{
id: 'gen_table_column',
label: 'gen_table_column',
type: 'table'
},
{
id: 'sys_config',
label: 'sys_config',
type: 'table'
},
{
id: 'sys_dept',
label: 'sys_dept',
type: 'table'
},
{
id: 'sys_dict_data',
label: 'sys_dict_data',
type: 'table'
},
{
id: 'sys_dict_type',
label: 'sys_dict_type',
type: 'table'
},
{
id: 'sys_job',
label: 'sys_job',
type: 'table'
},
{
id: 'sys_job_log',
label: 'sys_job_log',
type: 'table'
},
{
id: 'sys_logininfor',
label: 'sys_logininfor',
type: 'table'
},
{
id: 'sys_menu',
label: 'sys_menu',
type: 'table'
},
{
id: 'sys_notice',
label: 'sys_notice',
type: 'table'
},
{
id: 'sys_oper_log',
label: 'sys_oper_log',
type: 'table'
}
]
}
]
}
]
}
]);
const treeProps = {
children: 'children',
label: 'label',
};
const tableFields = ref([]);
const algorithms = ref([
{ value: 'mask', label: '掩码处理' },
{ value: 'encrypt', label: '加密处理' },
{ value: 'hash', label: '哈希处理' },
]);
// 打开弹窗
const openDialog = () => {
dialogVisible.value = true;
currentStep.value = 1;
resetForm();
};
// 重置表单
const resetForm = () => {
formData.name = '';
formData.remark = '';
selectedVersion.value = '';
tableFields.value = [];
};
// 关闭弹窗
const handleClose = () => {
dialogVisible.value = false;
};
// 取消
const handleCancel = () => {
dialogVisible.value = false;
};
// 下一步
const handleNextStep = () => {
if (!formData.name) {
ElMessage.error('请填写策略名称');
return;
}
currentStep.value = 2;
};
// 上一步
const handlePrevStep = () => {
currentStep.value = 1;
};
// 确定
const handleConfirm = () => {
// 这里调用API提交数据
console.log('提交数据:', {
...formData,
version: selectedVersion.value,
fields: tableFields.value,
});
dialogVisible.value = false;
ElMessage.success('策略添加成功');
};
// 树节点点击
const handleNodeClick = (node) => {
if (node.type === 'table') {
// 模拟根据表名获取字段
fetchTableFields(node.label);
}
};
// 获取表字段
const fetchTableFields = (tableName) => {
// 这里应该是API调用,根据表名获取字段
// 模拟数据
if (tableName === 'gen_table_column') {
tableFields.value = [
{
isPk: true,
name: 'column_id',
comment: '编号',
dataType: 'bigint',
algorithm: '',
},
{
isPk: false,
name: 'table_id',
comment: '归属表编号',
dataType: 'bigint',
algorithm: '',
},
// 其他字段...
];
} else {
tableFields.value = [];
}
};
// 设置字段
const handleSet = (row) => {
currentField.value = row;
desensitizationDialogVisible.value = true;
};
// 处理规则确认
const handleRuleConfirm = (ruleData) => {
// 更新表格中的算法字段
const fieldIndex = tableFields.value.findIndex(field => field.name === ruleData.fieldName);
if (fieldIndex !== -1) {
tableFields.value[fieldIndex].algorithm = ruleData.algorithm;
ElMessage.success(`字段 ${ruleData.fieldName} 的脱敏规则已更新`);
}
};
defineExpose({
openDialog,
});
</script>
<style scoped lang="scss">
.step-content {
min-height: 400px;
}
.version-select {
margin-bottom: 20px;
}
.field-selection {
display: flex;
height: 400px;
}
.tree-container {
width: 250px;
height: 400px;
overflow-y: auto;
padding-right: 10px;
}
.table-container {
flex: 1;
height: 100%;
overflow-y: auto;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
}
.el-divider {
height: 100%;
margin: 0 10px;
}
.flex-container {
display: flex;
}
.align-center {
align-items: center;
}
.justify-between {
justify-content: space-between;
}
.flex1 {
flex: 1;
}
.version-select-content {
margin-left: 15px;
}
</style>
\ No newline at end of file
<template>
<div class="tree-filter-container">
<!-- 搜索框 -->
<div class="search-box">
<el-input
v-model="filterText"
placeholder="输入关键字过滤"
clearable
prefix-icon="el-icon-search"
/>
</div>
<!-- 树形结构 -->
<el-tree
ref="treeRef"
class="filter-tree"
:data="treeData"
:props="defaultProps"
:filter-node-method="filterNode"
:expand-on-click-node="false"
node-key="id"
highlight-current
default-expand-all
@node-click="handleNodeClick"
>
<template #default="{ node, data }">
<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>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
const emit = defineEmits(['node-click'])
const props = defineProps({
treeData: {
type: Array,
default: () => [
{
id: 'system',
label: '若依配测系统',
type: 'system',
children: [
{
id: 'database',
label: 'ry',
type: 'database',
children: [
{
id: 'tables',
label: '表',
type: 'category',
children: [
{ id: 'gen_table', label: 'gen_table', type: 'table' },
{ id: 'gen_table_column', label: 'gen_table_column', type: 'table' },
{ id: 'sys_config', label: 'sys_config', type: 'table' },
{ id: 'sys_dept', label: 'sys_dept', type: 'table' },
{ id: 'sys_dict_data', label: 'sys_dict_data', type: 'table' },
{ id: 'sys_dict_type', label: 'sys_dict_type', type: 'table' },
{ id: 'sys_job', label: 'sys_job', type: 'table' },
{ id: 'sys_job_log', label: 'sys_job_log', type: 'table' },
{ id: 'sys_logininfor', label: 'sys_logininfor', type: 'table' },
{ id: 'sys_menu', label: 'sys_menu', type: 'table' },
{ id: 'sys_notice', label: 'sys_notice', type: 'table' },
{ id: 'sys_oper_log', label: 'sys_oper_log', type: 'table' },
{ id: 'sys_post', label: 'sys_post', type: 'table' },
{ id: 'sys_role', label: 'sys_role', type: 'table' },
{ id: 'sys_role_dept', label: 'sys_role_dept', type: 'table' },
{ id: 'sys_role_menu', label: 'sys_role_menu', type: 'table' },
{ id: 'sys_user', label: 'sys_user', type: 'table' },
{ id: 'sys_user_online', label: 'sys_user_online', type: 'table' },
{ id: 'sys_user_post', label: 'sys_user_post', type: 'table' },
{ id: 'sys_user_role', label: 'sys_user_role', type: 'table' }
]
}
]
}
]
}
]
}
})
const filterText = ref('')
const treeRef = ref(null)
const defaultProps = {
children: 'children',
label: 'label'
}
// 根据节点类型获取图标
const getNodeIcon = (type) => {
const iconMap = {
system: 'el-icon-s-platform',
database: 'el-icon-s-data',
category: 'el-icon-folder-opened',
table: 'el-icon-s-grid'
}
return iconMap[type] || 'el-icon-document'
}
// 过滤树节点
const filterNode = (value, data) => {
if (!value) return true
return data.label.toLowerCase().includes(value.toLowerCase())
}
// 监听过滤文本变化
watch(filterText, (val) => {
treeRef.value.filter(val)
})
// 节点点击事件
const handleNodeClick = (data) => {
emit('node-click', data)
}
</script>
<style scoped>
.tree-filter-container {
max-height: 700px;
overflow-y: auto;
width: 100%;
height: 100%;
/* background-color: #f5f5f5; */
padding: 10px;
border-right: 1px solid #e6e6e6;
}
.search-box {
margin-bottom: 10px;
}
.filter-tree {
background-color: transparent;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
font-size: 14px;
}
.node-icon {
margin-right: 6px;
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;
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论