Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
N
nse-ui
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
吴超
nse-ui
Commits
61503b50
Commit
61503b50
authored
Aug 20, 2025
by
ningjihai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
加密设置
parent
7c2c59e0
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
1106 行增加
和
1 行删除
+1106
-1
src/router/index.js
+5
-0
src/views/Classification/index.vue
+246
-0
src/views/Classification/modules/BasicInfoTab.vue
+49
-0
src/views/Classification/modules/EncryptionRuleDialog.vue
+300
-0
src/views/Classification/modules/EncryptionTab.vue
+239
-0
src/views/Classification/modules/StructureTab.vue
+56
-0
src/views/Classification/modules/TableInfoTab.vue
+51
-0
src/views/Classification/modules/TreeFilter.vue
+159
-0
src/views/projectManage/list.vue
+1
-1
没有找到文件。
src/router/index.js
View file @
61503b50
...
...
@@ -73,6 +73,11 @@ export const constantRoutes = [
hidden
:
true
},
{
path
:
'/classification'
,
component
:
()
=>
import
(
'@/views/Classification/index'
),
hidden
:
true
},
{
path
:
''
,
component
:
Layout
,
redirect
:
'/index'
,
...
...
src/views/Classification/index.vue
0 → 100644
View file @
61503b50
<
script
setup
name=
"Classification"
>
import
{
ref
,
toRefs
,
reactive
,
getCurrentInstance
,
proxyRefs
,
onMounted
}
from
'vue'
import
TreeFilter
from
'./modules/TreeFilter.vue'
import
BasicInfoTab
from
'./modules/BasicInfoTab.vue'
import
TableInfoTab
from
'./modules/TableInfoTab.vue'
import
StructureTab
from
'./modules/StructureTab.vue'
import
EncryptionTab
from
'./modules/EncryptionTab.vue'
import
{
useDict
}
from
'@/utils/dict'
import
{
useRouter
}
from
'vue-router'
const
router
=
useRouter
()
const
{
proxy
}
=
getCurrentInstance
()
const
projectId
=
ref
(
''
)
onMounted
(()
=>
{
projectId
.
value
=
proxy
.
$route
.
query
.
projectId
console
.
log
(
'projectId'
,
projectId
.
value
)
})
// const props = defineProps({
// projectId: String, // 主键
// })
// 树形数据
const
treeData
=
ref
([
{
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
currentNodeData
=
ref
(
null
)
const
currentNodeLevel
=
computed
(()
=>
{
if
(
!
currentNodeData
.
value
)
return
0
if
(
currentNodeData
.
value
.
type
===
'system'
)
return
1
if
(
currentNodeData
.
value
.
type
===
'database'
)
return
2
if
(
currentNodeData
.
value
.
type
===
'category'
)
return
3
if
(
currentNodeData
.
value
.
type
===
'table'
)
return
4
return
0
})
// 是否启用解密插件
const
enableDecryptionPlugin
=
ref
(
false
)
// 当前激活的Tab
const
activeTab
=
ref
(
'basic'
)
// 当前表结构数据 (匹配图片中的gen_table结构)
const
currentTableStructure
=
ref
([
{
pk
:
''
,
fieldName
:
'business_name'
,
comment
:
'生成业务名'
,
fieldType
:
'VARCHAR'
,
length
:
'30'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'business_name_...'
,
comment
:
''
,
fieldType
:
'TEXT'
,
length
:
'65535'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'class_name'
,
comment
:
'实体类名称'
,
fieldType
:
'VARCHAR'
,
length
:
'100'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'create_by'
,
comment
:
'创建者'
,
fieldType
:
'VARCHAR'
,
length
:
'64'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'create_time'
,
comment
:
'创建时间'
,
fieldType
:
'DATETIME'
,
length
:
'19'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'function_author'
,
comment
:
'生成功能作者'
,
fieldType
:
'VARCHAR'
,
length
:
'50'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'function_name'
,
comment
:
'生成功能名'
,
fieldType
:
'VARCHAR'
,
length
:
'50'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'gen_path'
,
comment
:
'生成路径(不填...'
,
fieldType
:
'VARCHAR'
,
length
:
'200'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'gen_type'
,
comment
:
'生成代码方式(0...'
,
fieldType
:
'CHAR'
,
length
:
'1'
,
precision
:
''
,
algorithm
:
''
},
{
pk
:
''
,
fieldName
:
'module_name'
,
comment
:
'生成模块名'
,
fieldType
:
'VARCHAR'
,
length
:
'30'
,
precision
:
''
,
algorithm
:
''
}
])
// 树节点点击处理
const
handleNodeClick
=
(
data
)
=>
{
currentNodeData
.
value
=
data
activeTab
.
value
=
'basic'
}
// 批量加密
const
handleBatchEncrypt
=
()
=>
{
console
.
log
(
'批量加密'
,
currentNodeData
.
value
)
}
// 批量解密
const
handleBatchDecrypt
=
()
=>
{
console
.
log
(
'批量解密'
,
currentNodeData
.
value
)
}
// 删除多余列
const
handleDeleteColumns
=
()
=>
{
console
.
log
(
'删除多余列'
,
currentNodeData
.
value
)
}
// 编辑字段
const
handleEditField
=
(
field
)
=>
{
console
.
log
(
'编辑字段'
,
field
)
}
defineExpose
({
// handleRedInk,
// handleVoid
})
</
script
>
<
template
>
<div
class=
"app-container scroller"
>
<PageTitle
:back=
"true"
@
back=
"pageProjectManage"
>
<template
#
title
>
返回项目管理
</
template
>
</PageTitle>
<div
class=
"app-container__body"
>
<div
class=
"flex-container content-container"
>
<div
class=
"left"
>
<el-card
class=
"image-card tree-container"
>
<TreeFilter
:tree-data=
"treeData"
@
node-click=
"handleNodeClick"
/>
</el-card>
</div>
<div
class=
"right flex1"
>
<el-card
class=
"image-card"
>
<div
class=
"header-section"
>
<div
class=
"breadcrumb"
>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item>
若依配测系统
</el-breadcrumb-item>
<el-breadcrumb-item
v-if=
"currentNodeLevel >= 2"
>
ry
</el-breadcrumb-item>
<el-breadcrumb-item
v-if=
"currentNodeLevel >= 3"
>
表
</el-breadcrumb-item>
<el-breadcrumb-item
v-if=
"currentNodeLevel >= 4"
>
{{ currentNodeData?.label }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div
class=
"radio-group"
v-if=
"currentNodeLevel === 4"
>
<el-radio-group
v-model=
"enableDecryptionPlugin"
>
<el-radio
:label=
"true"
>
启用解密插件
</el-radio>
<el-radio
:label=
"false"
>
不启用解密插件
</el-radio>
</el-radio-group>
</div>
</div>
<!-- Tab区域 -->
<div
class=
"tab-section"
>
<el-tabs
v-model=
"activeTab"
>
<!-- 基本信息Tab -->
<el-tab-pane
label=
"基本信息"
name=
"basic"
>
<BasicInfoTab
:node-data=
"currentNodeData"
v-if=
"activeTab === 'basic' && currentNodeLevel === 1"
/>
<TableInfoTab
:node-data=
"currentNodeData"
v-if=
"activeTab === 'basic' && currentNodeLevel === 4"
/>
</el-tab-pane>
<!-- 数据结构Tab (仅4级节点显示) -->
<el-tab-pane
label=
"数据结构"
name=
"structure"
v-if=
"currentNodeLevel === 4"
>
<StructureTab
:table-data=
"currentTableStructure"
v-if=
"activeTab === 'structure'"
/>
</el-tab-pane>
<!-- 字段加密配置Tab (仅4级节点显示) -->
<el-tab-pane
label=
"字段加密配置"
name=
"encryption"
v-if=
"currentNodeLevel === 4"
>
<EncryptionTab
:table-data=
"currentTableStructure"
@
batch-encrypt=
"handleBatchEncrypt"
@
batch-decrypt=
"handleBatchDecrypt"
@
delete-columns=
"handleDeleteColumns"
@
edit-field=
"handleEditField"
v-if=
"activeTab === 'encryption'"
/>
</el-tab-pane>
</el-tabs>
</div>
</el-card>
</div>
</div>
</div>
</div>
</template>
<
style
lang=
"scss"
scoped
>
.flex-container
{
display
:
flex
;
}
.align-center
{
align-items
:
center
;
}
.justify-between
{
justify-content
:
space-between
;
}
.flex1
{
flex
:
1
;
}
.content-container
{
.left
{
.tree-container
{
width
:
300px
;
}
}
.right
{
margin-left
:
var
(
--container-pd
);
overflow
:
hidden
;
}
}
</
style
>
src/views/Classification/modules/BasicInfoTab.vue
0 → 100644
View file @
61503b50
<
template
>
<div
class=
"basic-info-tab"
>
<el-descriptions
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>
</div>
</
template
>
<
script
setup
>
// 可以留空,因为数据是静态的
</
script
>
<
style
scoped
>
.basic-info-tab
{
padding
:
20px
;
background-color
:
white
;
}
:deep
(
.el-descriptions__title
)
{
font-size
:
16px
;
font-weight
:
bold
;
margin-bottom
:
16px
;
}
:deep
(
.el-descriptions__header
)
{
margin-bottom
:
16px
;
}
:deep
(
.el-descriptions__label
)
{
width
:
180px
;
background-color
:
#f5f7fa
;
font-weight
:
bold
;
color
:
#333
;
}
:deep
(
.el-descriptions__content
)
{
background-color
:
white
;
}
</
style
>
\ No newline at end of file
src/views/Classification/modules/EncryptionRuleDialog.vue
0 → 100644
View file @
61503b50
<
template
>
<el-dialog
title=
"设置加密规则"
v-model=
"dialogVisible"
width=
"800px"
:before-close=
"handleClose"
>
<div
class=
"encryption-rule-dialog"
>
<!-- 上部:规则和密钥选择 -->
<div
class=
"selection-section"
>
<!-- 左侧加密规则选择 -->
<div
class=
"rule-selection"
>
<div
class=
"section-title"
>
选择加密规则
</div>
<el-radio-group
v-model=
"selectedRule"
class=
"rule-radio-group"
>
<el-radio
v-for=
"rule in encryptionRules"
:key=
"rule.id"
:label=
"rule.id"
class=
"rule-radio"
>
{{
rule
.
name
}}
</el-radio>
</el-radio-group>
</div>
<!-- 右侧加密密钥选择 -->
<div
class=
"key-selection"
>
<div
class=
"section-title"
>
选择加密密钥
</div>
<el-radio-group
v-model=
"selectedKey"
class=
"key-radio-group"
>
<el-radio
v-for=
"key in currentKeys"
:key=
"key.id"
:label=
"key.id"
class=
"key-radio"
>
{{
key
.
name
}}
</el-radio>
</el-radio-group>
</div>
</div>
<!-- 下部:配置区域 -->
<div
class=
"config-section"
>
<div
class=
"config-row"
>
<!-- 加密位置 -->
<div
class=
"config-item"
>
<span
class=
"required-label"
>
*加密位置:
</span>
<el-select
v-model=
"ruleConfig.positionType"
style=
"width: 120px"
>
<el-option
label=
"保留前"
value=
"prefix"
/>
<el-option
label=
"保留后"
value=
"suffix"
/>
</el-select>
<el-input-number
v-model=
"ruleConfig.position"
:min=
"0"
:max=
"100"
controls-position=
"right"
style=
"width: 100px; margin-left: 10px;"
/>
<span
class=
"unit"
>
位
</span>
</div>
</div>
<div
class=
"config-row"
>
<!-- 源长度 -->
<div
class=
"config-item"
>
<span
class=
"label"
>
源长度:
</span>
<el-input-number
v-model=
"ruleConfig.sourceLength"
:min=
"0"
:max=
"1000"
controls-position=
"right"
style=
"width: 100px;"
/>
<el-button
type=
"primary"
size=
"small"
style=
"margin-left: 10px;"
@
click=
"calculateLength"
>
计算
</el-button>
</div>
<!-- 加密后长度 -->
<div
class=
"config-item"
>
<span
class=
"label"
>
加密后长度:
</span>
<span
class=
"value"
>
{{
encryptedLength
||
'--'
}}
</span>
</div>
</div>
<div
class=
"action-row"
>
<el-checkbox
v-model=
"supportFuzzy"
>
支持模糊
</el-checkbox>
<div
class=
"action-buttons"
>
<el-button
@
click=
"resetRules"
>
重置规则
</el-button>
<el-button
type=
"primary"
@
click=
"confirmRules"
>
确定规则
</el-button>
</div>
</div>
</div>
</div>
</el-dialog>
</
template
>
<
script
setup
>
import
{
ref
,
computed
,
watch
}
from
'vue'
const
props
=
defineProps
({
visible
:
{
type
:
Boolean
,
default
:
false
},
fieldData
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
const
emit
=
defineEmits
([
'update:visible'
,
'confirm'
])
// 控制弹窗显示
const
dialogVisible
=
computed
({
get
:
()
=>
props
.
visible
,
set
:
(
value
)
=>
emit
(
'update:visible'
,
value
)
})
// 加密规则数据
const
encryptionRules
=
ref
([
{
id
:
'name'
,
name
:
'姓名加密规则'
},
{
id
:
'gender'
,
name
:
'性别加密规则'
}
])
// 加密密钥数据
const
encryptionKeys
=
ref
({
name
:
[
{
id
:
'name_key1'
,
name
:
'姓名加密密钥1'
},
{
id
:
'name_key2'
,
name
:
'姓名加密密钥2'
}
],
gender
:
[
{
id
:
'gender_key1'
,
name
:
'性别加密密钥1'
},
{
id
:
'gender_key2'
,
name
:
'性别加密密钥2'
}
]
})
// 当前选中的规则
const
selectedRule
=
ref
(
''
)
// 当前选中的密钥
const
selectedKey
=
ref
(
''
)
// 当前显示的密钥列表
const
currentKeys
=
computed
(()
=>
{
return
encryptionKeys
.
value
[
selectedRule
.
value
]
||
[]
})
// 加密配置
const
ruleConfig
=
ref
({
positionType
:
'prefix'
,
position
:
0
,
sourceLength
:
100
})
// 加密后长度
const
encryptedLength
=
ref
(
''
)
// 是否支持模糊
const
supportFuzzy
=
ref
(
false
)
// 监听规则变化,自动选择第一个密钥
watch
(
selectedRule
,
(
newVal
)
=>
{
if
(
currentKeys
.
value
.
length
>
0
)
{
selectedKey
.
value
=
currentKeys
.
value
[
0
].
id
}
},
{
immediate
:
true
})
// 计算加密后长度
const
calculateLength
=
()
=>
{
// 这里应该是实际的加密长度计算逻辑
encryptedLength
.
value
=
Math
.
floor
(
ruleConfig
.
value
.
sourceLength
*
0.8
)
}
// 重置规则
const
resetRules
=
()
=>
{
selectedRule
.
value
=
'name'
ruleConfig
.
value
=
{
positionType
:
'prefix'
,
position
:
0
,
sourceLength
:
100
}
encryptedLength
.
value
=
''
supportFuzzy
.
value
=
false
}
// 确认规则
const
confirmRules
=
()
=>
{
emit
(
'confirm'
,
{
rule
:
selectedRule
.
value
,
key
:
selectedKey
.
value
,
config
:
ruleConfig
.
value
,
supportFuzzy
:
supportFuzzy
.
value
,
encryptedLength
:
encryptedLength
.
value
})
dialogVisible
.
value
=
false
}
// 关闭弹窗前处理
const
handleClose
=
(
done
)
=>
{
done
()
}
</
script
>
<
style
scoped
>
.encryption-rule-dialog
{
padding
:
10px
;
}
.selection-section
{
display
:
flex
;
margin-bottom
:
20px
;
padding-bottom
:
15px
;
border-bottom
:
1px
solid
#eee
;
}
.rule-selection
,
.key-selection
{
flex
:
1
;
padding
:
0
15px
;
}
.section-title
{
margin-bottom
:
15px
;
font-size
:
14px
;
font-weight
:
bold
;
color
:
#333
;
}
.rule-radio-group
,
.key-radio-group
{
display
:
flex
;
flex-direction
:
column
;
}
.rule-radio
,
.key-radio
{
margin
:
5px
0
;
}
.config-section
{
padding
:
0
15px
;
}
.config-row
{
display
:
flex
;
align-items
:
center
;
margin-bottom
:
15px
;
flex-wrap
:
wrap
;
}
.config-item
{
display
:
flex
;
align-items
:
center
;
margin-right
:
20px
;
}
.required-label
{
width
:
80px
;
text-align
:
right
;
margin-right
:
10px
;
font-size
:
14px
;
color
:
#f56c6c
;
}
.label
{
/* width: 60px; */
text-align
:
right
;
margin-right
:
10px
;
font-size
:
14px
;
color
:
#666
;
}
.unit
{
margin-left
:
5px
;
font-size
:
14px
;
color
:
#666
;
}
.value
{
font-size
:
14px
;
color
:
#333
;
font-weight
:
bold
;
}
.action-row
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-top
:
20px
;
}
.action-buttons
{
display
:
flex
;
gap
:
10px
;
}
</
style
>
\ No newline at end of file
src/views/Classification/modules/EncryptionTab.vue
0 → 100644
View file @
61503b50
<
template
>
<div
class=
"encryption-tab"
>
<!-- 搜索区域 -->
<div
class=
"filter-section"
>
<el-form
:inline=
"true"
:model=
"filterForm"
class=
"filter-form"
>
<el-form-item
label=
"字段名过滤:"
>
<el-input
v-model=
"filterForm.fieldName"
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>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"handleSearch"
>
搜索
</el-button>
</el-form-item>
</el-form>
</div>
<!-- 表格区域 -->
<el-table
:data=
"filteredTableData"
border
style=
"width: 100%; margin-top: 15px;"
: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=
"120"
align=
"center"
>
<template
#
default=
"
{ row }">
<el-button
type=
"text"
@
click=
"openEncryptionDialog(row)"
>
设置
</el-button>
</
template
>
</el-table-column>
<el-table-column
prop=
"status"
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>
</
template
>
</el-table-column>
<!-- 右浮动列 -->
<el-table-column
prop=
"comment"
label=
"注释"
align=
"left"
min-width=
"200"
/>
<el-table-column
label=
"描述信息"
align=
"left"
fixed=
"right"
>
<
template
#
default=
"{ row }"
>
<el-input
v-model=
"row.description"
size=
"small"
:disabled=
"!isEditing"
@
change=
"handleDescriptionChange(row)"
/>
</
template
>
</el-table-column>
<el-table-column
prop=
"plaintextProcess"
label=
"明文处理"
align=
"left"
fixed=
"right"
/>
</el-table>
<!-- 操作按钮区域 -->
<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>
</div>
<EncryptionRuleDialog
v-model:visible=
"showEncryptionDialog"
:field-data=
"currentField"
@
confirm=
"handleRuleConfirm"
/>
</div>
</template>
<
script
setup
>
import
{
ref
,
computed
,
reactive
}
from
'vue'
import
EncryptionRuleDialog
from
'./EncryptionRuleDialog.vue'
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
:
''
},
// 其他数据行...
]
}
})
const
emit
=
defineEmits
([
'batch-encrypt'
,
'batch-decrypt'
,
'delete-columns'
,
'edit-field'
,
'update-field'
])
// 搜索表单
const
filterForm
=
reactive
({
fieldName
:
''
,
status
:
''
})
// 编辑模式
const
isEditing
=
ref
(
false
)
// 表格行样式
const
tableRowClassName
=
({
row
,
rowIndex
})
=>
{
return
row
.
status
===
'encrypted'
?
'encrypted-row'
:
''
}
// 处理搜索
const
handleSearch
=
()
=>
{
// 搜索逻辑已在计算属性中实现
}
// 切换编辑模式
const
toggleEditMode
=
()
=>
{
isEditing
.
value
=
!
isEditing
.
value
}
// 处理描述信息变更
const
handleDescriptionChange
=
(
row
)
=>
{
emit
(
'update-field'
,
row
)
}
// 批量加密
const
handleBatchEncrypt
=
()
=>
{
emit
(
'batch-encrypt'
)
}
// 批量解密
const
handleBatchDecrypt
=
()
=>
{
emit
(
'batch-decrypt'
)
}
// 删除多余列
const
handleDeleteColumns
=
()
=>
{
emit
(
'delete-columns'
)
}
// 过滤表格数据
const
filteredTableData
=
computed
(()
=>
{
return
props
.
tableData
.
filter
(
item
=>
{
const
matchesName
=
filterForm
.
fieldName
?
item
.
fieldName
.
includes
(
filterForm
.
fieldName
)
:
true
const
matchesStatus
=
filterForm
.
status
?
item
.
status
===
filterForm
.
status
:
true
return
matchesName
&&
matchesStatus
})
})
const
showEncryptionDialog
=
ref
(
false
)
const
currentField
=
ref
({})
// 处理设置密钥
const
openEncryptionDialog
=
(
row
)
=>
{
if
(
!
isEditing
.
value
)
return
currentField
.
value
=
row
showEncryptionDialog
.
value
=
true
}
const
handleRuleConfirm
=
(
ruleData
)
=>
{
console
.
log
(
'确认加密规则:'
,
ruleData
)
// 更新表格数据或调用API
}
</
script
>
<
style
scoped
>
.encryption-tab
{
padding
:
15px
;
background-color
:
white
;
}
.filter-section
{
margin-bottom
:
15px
;
}
.filter-form
{
display
:
flex
;
align-items
:
center
;
}
.action-buttons
{
margin-top
:
20px
;
text-align
:
center
;
}
:deep
(
.el-table
.encrypted-row
)
{
background-color
:
#f0f9eb
;
}
:deep
(
.el-table
td
)
{
padding
:
8px
0
;
}
:deep
(
.el-table
th
)
{
background-color
:
#f5f7fa
;
}
:deep
(
.el-form-item
)
{
margin-bottom
:
0
;
}
:deep
(
.el-form-item__label
)
{
color
:
#333
;
font-weight
:
normal
;
}
</
style
>
\ No newline at end of file
src/views/Classification/modules/StructureTab.vue
0 → 100644
View file @
61503b50
<
template
>
<div
class=
"structure-tab"
>
<el-table
:data=
"tableData"
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>
</div>
</
template
>
<
script
setup
>
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
:
''
}
]
}
})
</
script
>
<
style
scoped
>
.structure-tab
{
padding
:
10px
;
background-color
:
white
;
}
:deep
(
.el-table
)
{
font-size
:
14px
;
}
:deep
(
.el-table--striped
.el-table__body
tr
.el-table__row--striped
td
)
{
background-color
:
#fafafa
;
}
</
style
>
\ No newline at end of file
src/views/Classification/modules/TableInfoTab.vue
0 → 100644
View file @
61503b50
<
template
>
<div
class=
"table-info-tab"
>
<el-descriptions
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>
</div>
</
template
>
<
script
setup
>
// 可以留空,因为数据是静态的
</
script
>
<
style
scoped
>
.table-info-tab
{
padding
:
20px
;
background-color
:
white
;
}
:deep
(
.el-descriptions__title
)
{
font-size
:
16px
;
font-weight
:
bold
;
margin-bottom
:
16px
;
}
:deep
(
.el-descriptions__header
)
{
margin-bottom
:
16px
;
}
:deep
(
.el-descriptions__label
)
{
width
:
180px
;
background-color
:
#f5f7fa
;
font-weight
:
bold
;
color
:
#333
;
}
:deep
(
.el-descriptions__content
)
{
background-color
:
white
;
}
</
style
>
\ No newline at end of file
src/views/Classification/modules/TreeFilter.vue
0 → 100644
View file @
61503b50
<
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>
</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
{
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
;
}
:deep
(
.el-tree-node__content
)
{
height
:
36px
;
}
</
style
>
\ No newline at end of file
src/views/projectManage/list.vue
View file @
61503b50
...
...
@@ -117,7 +117,7 @@ const handleEnterProject = (project) => {
console
.
log
(
'进入项目:'
,
project
)
// // ElMessage.success(`进入项目 ${project.projectName}`)
// emit('page', 'detail', { projectId: project.id})
router
.
push
({
path
:
'/project'
,
query
:
{
projectId
:
project
.
id
}
})
router
.
push
({
path
:
'/project
Home
'
,
query
:
{
projectId
:
project
.
id
}
})
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论