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
f36a8ad9
Commit
f36a8ad9
authored
Sep 19, 2025
by
wanglizhen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
脱敏算法模块上传
parent
aba361d4
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
417 行增加
和
581 行删除
+417
-581
src/assets/images/assetLibrary/default.png
+0
-0
src/assets/images/ruleConfig/algorithmPage.png
+0
-0
src/components/EditPop/ExpressionEditor.vue
+47
-49
src/components/collapseView/index.vue
+178
-113
src/views/assetLibrary/addEdit11.vue
+0
-321
src/views/ruleConfig/Algorithm/index.vue
+147
-65
src/views/ruleConfig/Algorithm/modules/formModule.vue
+45
-33
没有找到文件。
src/assets/images/assetLibrary/default.png
View replaced file @
aba361d4
View file @
f36a8ad9
3.16 KB
|
W:
|
H:
958 Bytes
|
W:
|
H:
2-up
Swipe
Onion skin
src/assets/images/ruleConfig/algorithmPage.png
0 → 100644
View file @
f36a8ad9
641 Bytes
src/components/EditPop/ExpressionEditor.vue
View file @
f36a8ad9
...
@@ -27,8 +27,8 @@ const confirm = () => {
...
@@ -27,8 +27,8 @@ const confirm = () => {
};
};
const
cancel
=
()
=>
{
const
cancel
=
()
=>
{
editorName
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
rulename
))
;
editorName
.
value
=
props
.
editor
.
rulename
?
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
rulename
))
:
''
;
editorValue
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
expression
))
;
editorValue
.
value
=
props
.
editor
.
expression
?
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
expression
))
:
''
;
emit
(
"cancel"
);
emit
(
"cancel"
);
};
};
...
@@ -56,11 +56,11 @@ const executeTest = () => {
...
@@ -56,11 +56,11 @@ const executeTest = () => {
});
});
};
};
// 测试关闭
// 测试关闭
const
testCancel
=
()
=>
{
const
testCancel
=
()
=>
{
testVisible
.
value
=
false
;
testVisible
.
value
=
false
;
testData
.
param
=
''
testData
.
param
=
""
;
testResult
.
value
=
""
;
testResult
.
value
=
""
;
}
}
;
watch
(
watch
(
()
=>
props
.
modelValue
,
()
=>
props
.
modelValue
,
...
@@ -75,8 +75,8 @@ watch(
...
@@ -75,8 +75,8 @@ watch(
watch
(
watch
(
()
=>
props
.
editor
,
()
=>
props
.
editor
,
(
newVal
)
=>
{
(
newVal
)
=>
{
editorName
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
rulename
))
;
editorName
.
value
=
props
.
editor
.
rulename
?
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
rulename
))
:
''
;
editorValue
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
expression
))
;
editorValue
.
value
=
props
.
editor
.
expression
?
JSON
.
parse
(
JSON
.
stringify
(
props
.
editor
.
expression
))
:
''
;
},
},
{
deep
:
true
,
immediate
:
true
}
{
deep
:
true
,
immediate
:
true
}
);
);
...
@@ -84,59 +84,57 @@ watch(
...
@@ -84,59 +84,57 @@ watch(
<
template
>
<
template
>
<div>
<div>
<ModalPop
v-model=
"props.modelValue"
title=
"编辑器"
@
cancel=
"cancel"
>
<el-dialog
title=
"编辑器"
v-model=
"props.modelValue"
:before-close=
"cancel"
width=
"1100"
>
<template
#
content
>
<div
class=
"title"
>
算法名称:
<span
style=
"color: rgba(33, 103, 217, 1);"
>
{{
editorName
}}
</span></div>
<div
class=
"title"
>
算法名称 :
{{
editorName
}}
</div>
<div
class=
"content"
>
<div
class=
"content"
>
<div
class=
"content_left"
>
<div
class=
"content_left"
>
<div
class=
"content_left_tap"
>
函数
</div>
<div
class=
"content_left_tap"
>
函数
</div>
<div
class=
"content_left_list"
>
<div
class=
"content_left_list"
>
<el-scrollbar
height=
"362px"
>
<el-scrollbar
height=
"362px"
>
<div
class=
"function__item"
@
mouseover=
"hoverFunc(item)"
v-for=
"(item,index) in listData"
:key=
"index"
>
<div
class=
"function__item"
@
mouseover=
"hoverFunc(item)"
v-for=
"(item,index) in listData"
:key=
"index"
>
{{
item
.
name
}}
</div>
{{
item
.
name
}}
</div>
</el-scrollbar>
</el-scrollbar>
</div>
</div>
<div
class=
"content_right"
>
<div
class=
"content_right_info"
>
<div
class=
"content_right_info_title"
>
说明
</div>
<div
class=
"content_right_info_content"
>
定义:
{{
infoText
}}
</div>
</div>
<div
class=
"content_right_editor"
>
<el-input
type=
"textarea"
placeholder=
"请输入内容"
v-model=
"editorValue"
/>
</div>
</div>
</div>
</div>
</div>
<div
style=
"display: flex; justify-content: center; padding-top: 20px;"
>
<div
class=
"content_right"
>
<el-button
type=
"primary"
style=
"width: 150px;"
@
click=
"testVisible = true"
>
测试
</el-button>
<div
class=
"content_right_info"
>
<el-button
type=
"info"
style=
"width: 150px;"
@
click=
"cancel"
>
取消
</el-button>
<div
class=
"content_right_info_title"
>
说明
</div>
<el-button
type=
"primary"
style=
"width: 150px;"
@
click=
"confirm"
>
确认
</el-button>
<div
class=
"content_right_info_content"
>
定义:
{{
infoText
}}
</div>
</div>
<div
class=
"content_right_editor"
>
<el-input
type=
"textarea"
placeholder=
"请输入内容"
v-model=
"editorValue"
/>
</div>
</div>
</div>
</
template
>
</div>
</ModalPop>
<div
style=
"display: flex; justify-content: center; padding: 60px 0 30px 0;"
>
<el-button
type=
"primary"
style=
"width: 80px;"
@
click=
"testVisible = true"
>
测试
</el-button>
<el-button
style=
"width: 80px;"
@
click=
"cancel"
>
取消
</el-button>
<el-button
type=
"primary"
style=
"width: 80px;"
@
click=
"confirm"
>
确认
</el-button>
</div>
</el-dialog>
<!-- 测试 -->
<!-- 测试 -->
<ModalPop
v-model=
"testVisible"
width=
"800px"
title=
"测试"
@
cancel=
"testCancel"
>
<el-dialog
title=
"测试"
v-model=
"testVisible"
:before-close=
"testCancel"
width=
"1100"
>
<
template
#
content
>
<el-form-item
label=
"输入参数$value的值:"
label-width=
"180px"
prop=
"expression"
>
<el-form-item
label=
"输入参数$value的值:"
label-width=
"180px"
prop=
"expression"
>
<div
style=
"width: 100%;display: flex; justify-content: center;"
>
<div
style=
"width: 100%;display: flex; justify-content: center;"
>
<el-input
placeholder=
"输入参数$value的值"
v-model=
"testData.param"
/>
<el-input
placeholder=
"输入参数$value的值"
v-model=
"testData.param"
/>
<el-button
type=
"primary"
style=
"margin-left: 10px;"
@
click=
"executeTest"
>
执行
</el-button>
<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>
</div>
</
template
>
</el-form-item>
</ModalPop>
<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>
</el-dialog>
</div>
</div>
</
template
>
</
template
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.title
{
.title
{
margin-bottom
:
20px
;
padding-left
:
22px
;
height
:
32px
;
height
:
32px
;
line-height
:
32px
;
line-height
:
32px
;
}
}
...
...
src/components/collapseView/index.vue
View file @
f36a8ad9
<
script
setup
lang=
"ts"
name=
"collapseView"
>
<
script
setup
lang=
"ts"
name=
"collapseView"
>
import
{
ref
,
computed
}
from
'vue'
import
{
ref
,
computed
}
from
"vue"
;
import
{
Collapse
,
Panel
}
from
'view-ui-plus'
;
import
{
Collapse
,
Panel
}
from
"view-ui-plus"
;
const
emit
=
defineEmits
([
"add"
,
"view"
,
"mainDeletion"
,
"default"
,
"childDelete"
,
"change"
]);
const
emit
=
defineEmits
([
"add"
,
"view"
,
"mainDeletion"
,
"default"
,
"childDelete"
,
"change"
,
]);
const
props
=
defineProps
<
{
const
props
=
defineProps
<
{
list
:
Array
<
any
>
;
list
:
Array
<
any
>
;
fatherIndex
:
Array
<
any
>
;
currentId
:
Array
<
any
>
;
}
>
();
}
>
();
const
listData
=
computed
(()
=>
props
.
list
)
const
listData
=
computed
(()
=>
props
.
list
);
const
activeId
=
computed
(()
=>
props
.
currentId
);
const
fatherIndex
=
computed
(()
=>
props
.
fatherIndex
);
const
childIndex
=
ref
(
null
);
// 新增
// 新增
const
addClick
=
(
item
)
=>
{
const
addClick
=
(
item
)
=>
{
emit
(
"add"
,
item
);
emit
(
"add"
,
item
);
}
}
;
// 查看
// 查看
const
viewClick
=
(
item
)
=>
{
const
viewClick
=
(
item
,
index
)
=>
{
emit
(
"view"
,
item
);
const
{
isView
,
list
}
=
item
}
if
(
isView
)
{
emit
(
"view"
,
item
);
}
else
{
if
(
list
.
length
<=
0
)
return
emit
(
"view"
,
index
);
}
};
// 主删除
// 主删除
const
mainDeletion
=
(
item
)
=>
{
const
mainDeletion
=
(
item
)
=>
{
emit
(
"mainDeletion"
,
item
);
emit
(
"mainDeletion"
,
item
);
}
}
;
// 子级监听
// 子级监听
const
itemClick
=
(
item1
,
item2
)
=>
{
const
itemClick
=
(
item
,
index
)
=>
{
childIndex
.
value
=
index
const
parentItem
=
listData
.
value
[
fatherIndex
.
value
]
const
data
=
{
const
data
=
{
parentItem
:
item1
,
parentItem
:
parentItem
,
item
:
item
2
item
:
item
,
}
}
;
emit
(
"change"
,
data
);
emit
(
"change"
,
data
);
}
}
;
// 默认项
// 默认项
const
defaultClick
=
(
item
)
=>
{
const
defaultClick
=
(
item
)
=>
{
emit
(
"default"
,
item
);
emit
(
"default"
,
item
);
}
}
;
// 子删除
// 子删除
const
childDelete
=
(
item
)
=>
{
const
childDelete
=
(
item
)
=>
{
emit
(
"childDelete"
,
item
);
emit
(
"childDelete"
,
item
);
}
};
</
script
>
</
script
>
<
template
>
<
template
>
<Collapse
simple
>
<div
class=
"collapse"
>
<Panel
:name=
"item.name"
v-for=
"(item, index) in listData"
:key=
"index"
>
<div
class=
"fatherLevel"
>
{{
item
.
dataarea
}}
<el-scrollbar
style=
"width: 100%;height: 100%;"
>
<span
class=
"collapse-item__btns--box"
>
<div
class=
"panel"
:class=
"fatherIndex === index ? 'active' : ''"
v-for=
"(item, index) in listData"
:key=
"index"
@
click
.
stop=
"viewClick(item,index)"
>
<el-icon
color=
"rgb(253, 84, 81)"
:size=
"16"
v-if=
"item.isAdd"
@
click
.
stop=
"addClick(item)"
>
<div
class=
"add"
v-if=
"item.isAdd"
@
click
.
stop=
"addClick(item)"
>
<circle-plus-filled
/>
<el-icon
:size=
"10"
color=
"#fff"
>
</el-icon>
<plus
/>
<el-icon
color=
"#2c9ef7"
:size=
"16"
v-if=
"item.isView"
@
click
.
stop=
"viewClick(item)"
style=
"margin-left: 8px;"
>
</el-icon>
<View
/>
</div>
</el-icon>
<div
class=
"name"
>
{{
item
.
dataarea
}}
</div>
<el-icon
color=
"rgb(13, 215, 141)"
:size=
"16"
v-if=
"item.isDelete"
@
click
.
stop=
"mainDeletion(item)"
style=
"margin-left: 8px;"
>
<el-icon
color=
"rgba(212, 48, 48, 1)"
:size=
"16"
v-if=
"item.isDelete"
@
click
.
stop=
"mainDeletion(item)"
<delete
/>
style=
"margin-right: 17px;"
>
</el-icon>
<circle-close-filled
/>
</span>
</el-icon>
<template
#
content
>
<el-icon
:size=
"14"
color=
"rgba(53, 64, 79, 1)"
v-if=
"item.list && item.list.length > 0"
>
<div>
<arrow-right
/>
<div
class=
"rule__item"
v-for=
"(itemTwo, i) in item.list"
:key=
"i"
@
click=
"itemClick(item,itemTwo)"
>
</el-icon>
<span>
{{
itemTwo
.
name
}}
</span>
</div>
<div
class=
"default"
v-if=
"itemTwo.defaulttype === '1'"
></div>
</el-scrollbar>
<div
class=
"rule__item__btns"
>
</div>
<el-icon
color=
"#2c9ef7"
:size=
"15"
v-if=
"itemTwo.isCheck && itemTwo.defaulttype !== '1'"
@
click
.
stop=
"defaultClick(itemTwo)"
style=
"margin-right: 8px;"
>
<div
class=
"childLevel"
v-if=
"listData[fatherIndex] && listData[fatherIndex].list.length > 0"
>
<circle-check
/>
<el-scrollbar
style=
"width: 100%;height: 100%;padding: 0 9px;"
>
</el-icon>
<div
class=
"panel"
:class=
"activeId === item.id ? 'active' : ''"
v-for=
"(item, index) in listData[fatherIndex].list"
:key=
"index"
@
click
.
stop=
"itemClick(item,index)"
>
<el-icon
color=
"rgb(13, 215, 141)"
:size=
"15"
v-if=
"itemTwo.isDelete"
@
click
.
stop=
"childDelete(itemTwo)"
>
<div
class=
"line"
></div>
<delete
/>
<div
class=
"name"
>
{{
item
.
name
}}
</div>
</el-icon>
<div
class=
"default"
v-if=
"item.defaulttype === '1'"
></div>
</div>
<div
class=
"btns"
:style=
"item.defaulttype === '1' ? 'margin-right: 30px;':''"
>
<el-icon
color=
"rgba(33, 103, 217, 1)"
v-if=
"item.isCheck && item.defaulttype !== '1'"
:size=
"16"
@
click
.
stop=
"defaultClick(item)"
style=
"margin-right: 10px;"
>
<circle-check-filled
/>
</el-icon>
<el-icon
color=
"rgba(212, 48, 48, 1)"
v-if=
"item.isDelete"
:size=
"16"
@
click
.
stop=
"childDelete(item)"
>
<circle-close-filled
/>
</el-icon>
</div>
</div>
</div>
</div>
</
template
>
</
el-scrollbar
>
</
Panel
>
</
div
>
</
Collapse
>
</
div
>
</
template
>
</
template
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
:deep
(
.ivu-collapse-content
)
{
.collapse
{
padding
:
0
0
0
14px
;
width
:
100%
;
}
height
:
100%
;
:deep
(
.ivu-collapse-content-box
)
{
display
:
flex
;
padding-bottom
:
0
;
.fatherLevel
{
}
width
:
282px
;
.ivu-collapse-header
{
height
:
100%
;
padding-left
:
0
;
.panel
{
}
.ivu-collapse-simple
{
border
:
none
!important
;
.ivu-collapse-item
{
position
:
relative
;
border
:
none
!important
;
}
.ivu-collapse-item
:before
{
content
:
" "
;
width
:
calc
(
100%
-
14px
);
height
:
1px
;
background
:
#f3f5fa
;
position
:
absolute
;
top
:
0
;
left
:
14px
;
}
.ivu-collapse-item
:first-child:before
{
height
:
0
;
}
}
.collapse-item__btns--box
{
position
:
absolute
;
right
:
4px
;
}
.rule__item
{
position
:
relative
;
padding-left
:
20px
;
cursor
:
pointer
;
border-bottom
:
1px
solid
#f3f5fa
;
height
:
30px
;
line-height
:
30px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
&__btns
{
padding-top
:
7px
;
padding-right
:
28px
;
padding-right
:
28px
;
display
:
none
;
width
:
100%
;
line-height
:
30px
;
height
:
50px
;
border-bottom
:
1px
dashed
rgba
(
186
,
193
,
204
,
1
);
display
:
flex
;
align-items
:
center
;
cursor
:
pointer
;
.add
{
margin-left
:
18px
;
width
:
16px
;
height
:
16px
;
border-radius
:
4px
;
background
:
rgba
(
133
,
147
,
167
,
1
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.name
{
flex
:
1
;
margin-left
:
12px
;
font-size
:
14px
;
line-height
:
22px
;
color
:
rgba
(
53
,
64
,
79
,
1
);
}
}
}
.default
{
.active
{
position
:
absolute
;
background
:
rgba
(
235
,
242
,
255
,
1
);
top
:
0
;
right
:
0
;
width
:
28px
;
height
:
30px
;
background
:
url("@/assets/images/assetLibrary/default.png")
no-repeat
center
center
;
background-size
:
100%
100%
;
pointer-events
:
none
;
}
}
}
}
.rule__item
:hover
{
.childLevel
{
color
:
#21333f
;
padding
:
1px
0
;
background
:
#f3f5fa
;
flex
:
1
;
.rule__item__btns
{
height
:
100%
;
display
:
block
;
border-radius
:
8px
;
background
:
rgba
(
235
,
242
,
255
,
1
);
overflow
:
hidden
;
.panel
{
position
:
relative
;
width
:
100%
;
height
:
50px
;
border-bottom
:
1px
dashed
rgba
(
186
,
193
,
204
,
1
);
display
:
flex
;
align-items
:
center
;
font-size
:
14px
;
line-height
:
22px
;
color
:
rgba
(
53
,
64
,
79
,
1
);
border-radius
:
8px
;
cursor
:
pointer
;
.line
{
width
:
2.26px
;
height
:
20px
;
border-radius
:
8px
;
background
:
rgba
(
33
,
103
,
217
,
1
);
opacity
:
0
;
}
.name
{
flex
:
1
;
margin-left
:
19px
;
font-size
:
14px
;
font-weight
:
400
;
letter-spacing
:
0px
;
line-height
:
22px
;
color
:
rgba
(
53
,
64
,
79
,
1
);
}
.btns
{
margin-right
:
14px
;
line-height
:
14px
;
display
:
none
;
}
.default
{
position
:
absolute
;
top
:
7px
;
right
:
4px
;
width
:
21.93px
;
height
:
22.24px
;
background
:
url("@/assets/images/assetLibrary/default.png")
no-repeat
center
center
;
background-size
:
100%
100%
;
pointer-events
:
none
;
}
}
.active
{
background
:
#fff
;
.line{
opacity
:
1
;
}
.name
{
color
:
rgba
(
33
,
103
,
217
,
1
);
}
.btns
{
display
:
block
;
}
}
}
}
}
}
</
style
>
</
style
>
\ No newline at end of file
src/views/assetLibrary/addEdit11.vue
deleted
100644 → 0
View file @
aba361d4
<
script
setup
lang=
"ts"
name=
"AddEdit"
>
import
{
ref
,
toRefs
,
reactive
,
getCurrentInstance
}
from
'vue'
import
FormGroup
from
'./modules/formGroup.vue'
import
img
from
'@/assets/images/assetLibrary/index.js'
const
emit
=
defineEmits
([
"update:modelValue"
,
"confirm"
,
"cancel"
])
const
props
=
defineProps
<
{
modelValue
:
boolean
;
}
>
();
const
step
=
ref
(
'edit'
)
// select edit
const
selectData
=
reactive
({
name
:
''
,
type
:
''
})
const
listData
=
ref
([
{
title
:
'关系型数据库'
,
type
:
1
,
list
:
[
{
name
:
'MYSQL'
,
icon
:
img
.
MYSQL
,
},
{
name
:
'ORACLE'
,
icon
:
img
.
ORACLE
,
},
{
name
:
'POSTGRESQL'
,
icon
:
img
.
POSTGRESQL
,
},
// {
// name: 'DB2',
// icon: img.DB2,
// },
{
name
:
'MSSQLSERVER'
,
icon
:
img
.
MSSQLSERVER
,
},
// {
// name: 'MARIADB',
// icon: img.MARIADB,
// },
// {
// name: 'GBASE8S',
// icon: img.GBASE8S,
// },
{
name
:
'KINGBASE'
,
icon
:
img
.
KINGBASE
,
},
{
name
:
'DM'
,
icon
:
img
.
DM
,
},
// {
// name: 'GREENPLUM',
// icon: img.GREENPLUM,
// },
// {
// name: 'GAUSS',
// icon: img.GAUSS,
// },
// {
// name: 'OCEANBASE',
// icon: img.OCEANBASE,
// },
// {
// name: 'GAUSSDB',
// icon: img.GAUSSDB,
// }
]
},
// {
// title: 'NoSQL',
// type: 2,
// list: [
// {
// name: 'ES',
// icon: img.ES,
// },
// {
// name: 'MONGODB',
// icon: img.MONGODB,
// }
// ]
// },
// {
// title: '消息队列',
// type: 3,
// list: [
// {
// name: 'KAFKA',
// icon: img.KAFKA,
// }
// ]
// }
])
const
hadoopData
=
reactive
({
index
:
null
,
list
:
[
{
name
:
'Apache'
,
icon1
:
img
.
apache1
,
icon2
:
img
.
apache2
,
list
:
[
{
name
:
'HIVE'
,
icon
:
img
.
HIVE
,
type
:
4
,
}
]
},
{
name
:
'CLOUDERA'
,
icon1
:
img
.
cloudera1
,
icon2
:
img
.
cloudera2
,
list
:
[
{
name
:
'HIVE'
,
icon
:
img
.
HIVE
,
type
:
4
,
}
]
},
{
name
:
'星环'
,
icon1
:
img
.
star1
,
icon2
:
img
.
star2
,
list
:
[
{
name
:
'HIVE_TDH'
,
icon
:
img
.
HIVE
,
type
:
4
,
}
]
}
]
})
// hadoop事件
const
hadoopClick
=
(
index
)
=>
{
hadoopData
.
index
=
index
}
// 新增
const
editTo
=
(
item
,
type
)
=>
{
// selectData.name = item.name
// selectData.type = type
// step.value = 'edit'
}
// 新增回调
const
modalConfirm
=
()
=>
{
console
.
log
(
'modalConfirm'
)
}
</
script
>
<
template
>
<el-dialog
title=
"提示"
v-model=
"modelValue"
width=
"1100"
>
</el-dialog>
<div
class=
"app-container scroller"
>
<PageTitle
back
@
back=
"emit('page', 'list')"
>
<template
#
title
>
<span
id=
"badDebt"
class=
"title-icon"
>
新增数据源
<PageTour
tourType=
"badDebt"
/>
</span>
</
template
>
</PageTitle>
<div
class=
"app-container__body"
>
<div
v-if=
"step === 'select'"
>
<div
class=
"listBox"
v-for=
"(item,index) in listData"
:key=
"index"
>
<div
class=
"title"
>
{{ item.title }}
</div>
<div
class=
"img-warpper"
>
<img
class=
"img"
:src=
"liItem.icon"
:alt=
"liItem.name"
@
click=
"editTo(liItem, item.type)"
v-for=
"(liItem, i) in item.list"
:key=
"i"
>
</div>
</div>
<!-- <div class="title">Hadoop品牌:<span class="data-base-name">{{ hadoopData.index !== null ? hadoopData.list[hadoopData.index].name : '' }}</span></div>
<div style="display: inline-block;">
<div class="hadoop-list-box">
<div class="hadoop-item-box" :class="hadoopData.index === index ? 'hadoop-item-box-active' : ''" v-for="(item,index) in hadoopData.list" :key="index" @click="hadoopClick(index)">
<img :src="item.icon1" alt="">
<img :src="item.icon2" alt="" class="hidden-img">
<div class="name">
<span>{{ item.name }}</span>
<div class="bar"></div>
</div>
</div>
</div>
</div>
<div style="padding-top: 10px;color: #7a8495;">*点击图标切换Hadoop品牌</div>
<div v-if="hadoopData.index !== null" style="color: rgb(102, 102, 102); font-size: 16px; font-weight: bold; padding: 10px 0px;">Hadoop</div>
<div class="img-warpper" v-if="hadoopData.index !== null">
<img class="img" :src="item.icon" :alt="item.name" @click="editTo(item, item.type)" v-for="(item, index) in hadoopData.list[hadoopData.index].list" :key="index">
</div> -->
</div>
<div
v-if=
"step === 'edit'"
style=
"padding: 30px 150px;"
>
<div
style=
"padding-bottom: 20px;"
>
<span
style=
"color: rgb(102, 102, 102);"
>
数据源类型:
</span>
<span
class=
"source-title"
>
{{ selectData.name }}
</span>
</div>
<FormGroup
page=
"add"
:title=
"selectData.name"
:type=
"selectData.type"
@
cancel=
"step = 'select'"
@
confirm=
"modalConfirm"
/>
</div>
</div>
</div>
</template>
<
style
lang=
"scss"
scoped
>
.title
{
color
:
#21333f
;
font-size
:
16px
;
line-height
:
20px
;
font-weight
:
700
;
padding
:
10px
0
10px
12px
;
.data-base-name{
color
:
#2c9ef7
;
font-size
:
20px
;
font-weight
:
400
;
}
}
.img-warpper
{
background-color
:
#f3f5fa
;
padding
:
7.5px
;
margin-top
:
24px
;
margin-bottom
:
50px
;
margin-left
:
12px
;
line-height
:
1
;
.img
{
width
:
132px
;
font-size
:
0
;
margin
:
0
10px
10px
0
;
cursor
:
pointer
;
}
}
.hadoop-list-box
{
display
:
-webkit-box
;
display
:
-ms-flexbox
;
display
:
flex
;
-ms-flex-wrap
:
nowrap
;
flex-wrap
:
nowrap
;
-ms-flex-pack
:
distribute
;
justify-content
:
space-around
;
background
:
#f1f3f5
;
padding
:
10px
;
.hadoop-item-box
{
padding
:
8px
;
background
:
#fff
;
cursor
:
pointer
;
position
:
relative
;
-webkit-transition
:
-webkit-box-shadow
0.3s
;
transition
:
-webkit-box-shadow
0.3s
;
transition
:
box-shadow
0.3s
;
transition
:
box-shadow
0.3s
,
-webkit-box-shadow
0.3s
;
margin-right
:
16px
;
img
{
font-size
:
0
;
vertical-align
:
bottom
;
width
:
132px
;
}
.hidden-img
{
position
:
absolute
;
left
:
8px
;
opacity
:
0
;
-webkit-transition
:
opacity
0.5s
;
transition
:
opacity
0.5s
;
}
.name
{
height
:
20px
;
line-height
:
20px
;
text-align
:
center
;
margin-top
:
8px
;
position
:
relative
;
.bar
{
position
:
absolute
;
opacity
:
0
;
background-color
:
#1f85df
;
height
:
2px
;
width
:
0
;
-webkit-transition
:
all
0.2s
;
transition
:
all
0.2s
;
left
:
0
;
bottom
:
-4px
;
}
}
}
.hadoop-item-box-active
{
-webkit-box-shadow
:
0
0
10px
#888
;
box-shadow
:
0
0
10px
#888
;
.hidden-img{
opacity
:
1
;
}
.name
{
.bar{
opacity
:
1
;
width
:
132px
;
left
:
0
;
}
}
}
.hadoop-item-box
:hover
{
-webkit-box-shadow
:
0
0
10px
#888
;
box-shadow
:
0
0
10px
#888
;
.hidden-img
{
opacity
:
1
;
}
}
}
.source-title
{
font-size
:
18px
;
font-weight
:
700
;
color
:
#1f85df
;
}
</
style
>
\ No newline at end of file
src/views/ruleConfig/Algorithm/index.vue
View file @
f36a8ad9
...
@@ -9,9 +9,9 @@ import ModalPop from "@/components/EditPop/ModalPop.vue"
...
@@ -9,9 +9,9 @@ import ModalPop from "@/components/EditPop/ModalPop.vue"
import
{
query
,
del
}
from
'@/api/ruleConfig/algorithm.js'
import
{
query
,
del
}
from
'@/api/ruleConfig/algorithm.js'
const
splitNum
=
ref
(
0.31
)
// 左右分割比例
const
collapseList
=
ref
([])
const
collapseList
=
ref
([])
const
rulenameList
=
ref
([])
// 规则名称列表
const
rulenameList
=
ref
([])
// 规则名称列表
const
fatherIndex
=
ref
(
0
)
// 父级索引
const
searchValue
=
ref
(
''
)
const
searchValue
=
ref
(
''
)
const
data
=
reactive
({
const
data
=
reactive
({
...
@@ -58,14 +58,15 @@ const getCollapse = (type) => {
...
@@ -58,14 +58,15 @@ const getCollapse = (type) => {
if
(
type
===
'edit'
)
return
if
(
type
===
'edit'
)
return
if
(
collapseList
.
value
.
length
<=
0
)
return
if
(
collapseList
.
value
.
length
<=
0
)
return
if
(
collapseList
.
value
[
0
].
ruleList
.
length
>
0
)
{
if
(
collapseList
.
value
[
0
].
ruleList
.
length
>
0
)
{
fatherIndex
.
value
=
0
editForm
.
value
=
collapseList
.
value
[
0
].
ruleList
[
0
]
editForm
.
value
=
collapseList
.
value
[
0
].
ruleList
[
0
]
}
else
{
}
else
{
fatherIndex
.
value
=
null
const
{
id
}
=
collapseList
.
value
[
0
]
const
{
id
}
=
collapseList
.
value
[
0
]
editForm
.
value
=
{
editForm
.
value
=
{
dataarea_id
:
id
dataarea_id
:
id
}
}
}
}
})
})
}
}
...
@@ -74,6 +75,12 @@ const modalPopCancel = () => {
...
@@ -74,6 +75,12 @@ const modalPopCancel = () => {
modalPopShow
.
value
=
false
modalPopShow
.
value
=
false
}
}
// 一级点击
const
collapseView
=
(
index
)
=>
{
console
.
log
(
index
)
fatherIndex
.
value
=
index
}
// 新增算法
// 新增算法
const
collapseAdd
=
(
item
)
=>
{
const
collapseAdd
=
(
item
)
=>
{
// console.log('添加事件', item)
// console.log('添加事件', item)
...
@@ -139,88 +146,163 @@ onMounted(() => {
...
@@ -139,88 +146,163 @@ onMounted(() => {
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"app-container scroller"
>
<div
class=
"app-container scroller"
>
<PageTitle>
<template
#
title
>
脱敏算法
</
template
>
</PageTitle>
<div
class=
"app-container__body"
>
<div
class=
"app-container__body"
>
<Split
v-model=
"splitNum"
>
<div
class=
"pageTitle"
>
<
template
#
left
>
<img
class=
"icon"
src=
"@/assets/images/ruleConfig/algorithmPage.png"
alt=
""
>
<div
class=
"demo-split-pane"
style=
"padding: 0 38px 10px 0;width: 100%;overflow: auto;height: 100%;display: flex;flex-direction: column;"
>
<span>
脱敏算法
</span>
<el-input
class=
"mb20"
v-model=
"searchValue"
placeholder=
"脱敏规则搜索"
>
</div>
<template
#
suffix
>
<div
class=
"box"
>
<el-icon
style=
"vertical-align: middle;cursor: pointer;"
@
click=
"getCollapse"
>
<div
class=
"left"
>
<search
/>
<el-input
v-model=
"searchValue"
placeholder=
"脱敏规则搜索"
style=
"width: 369px;margin-bottom: 15px;"
>
</el-icon>
<template
#
prefix
>
</
template
>
<el-icon>
</el-input>
<search
/>
<el-scrollbar
style=
"width: 100%;flex: 1;padding-right: 38px;"
>
</el-icon>
<CollapseView
:list=
"collapseList"
@
add=
"collapseAdd"
@
childDelete=
"collapseDelete"
</
template
>
@
change=
"collapseChange"
/>
<
template
#
append
>
</el-scrollbar>
<el-button
icon=
"search"
class=
"searchBut"
@
click=
"getCollapse"
>
搜索
</el-button>
</
template
>
</el-input>
<div
class=
"collapseView"
>
<CollapseView
:list=
"collapseList"
:fatherIndex=
"fatherIndex"
:currentId=
"editForm.id"
@
add=
"collapseAdd"
@
childDelete=
"collapseDelete"
@
view=
"collapseView"
@
change=
"collapseChange"
/>
</div>
</div>
</template>
</div>
<
template
#
right
>
<div
class=
"right"
>
<div
class=
"demo-split-pane"
>
<div
class=
"line"
></div>
<div
class=
"right"
>
<div
style=
"padding: 26px 28px 0 28px;"
>
<div
class=
"right-title"
>
<DividerTitle
title-name=
"脱敏规则"
/>
<el-icon>
<div
class=
"right-content"
>
<info-filled
/>
<formModule
:itemData=
"editForm"
:nameList=
"rulenameList"
type=
"edit"
@
confirm=
"formModuleConfirm"
/>
</el-icon>
<span
style=
"margin-left: 5px;"
>
脱敏规则
</span>
</div>
<div
class=
"right-content"
>
<formModule
:itemData=
"editForm"
:nameList=
"rulenameList"
type=
"edit"
@
confirm=
"formModuleConfirm"
/>
</div>
</div>
</div>
</div>
</div>
</
template
>
</
div
>
</
Split
>
</
div
>
</div>
</div>
<!-- 提示框 -->
<!-- 提示框 -->
<Modal
v-model=
"modalData.show"
:icon=
"modalData.icon"
:cancel=
"modalData.cancel"
:text=
"modalData.text"
<Modal
v-model=
"modalData.show"
:icon=
"modalData.icon"
:cancel=
"modalData.cancel"
:text=
"modalData.text"
@
confirm=
"modalConfirm"
></Modal>
@
confirm=
"modalConfirm"
></Modal>
<!-- 新增算法 -->
<!-- 新增算法 -->
<
ModalPop
v-model=
"modalPopShow"
title=
"新增算法"
@
cancel=
"modalPopCancel
"
>
<
el-dialog
title=
"新增算法"
v-model=
"modalPopShow"
:before-close=
"modalPopCancel"
width=
"900
"
>
<
template
#
content
>
<
div
style=
"padding: 30px 120px;"
>
<formModule
v-if=
"modalPopShow"
:itemData=
"addForm"
:nameList=
"rulenameList"
type=
"add"
@
cancel=
"modalPopCancel"
<formModule
v-if=
"modalPopShow"
:itemData=
"addForm"
:nameList=
"rulenameList"
type=
"add"
@
cancel=
"modalPopCancel"
@
confirm=
"formModuleConfirm"
/>
@
confirm=
"formModuleConfirm"
/>
</
template
>
</
div
>
</
ModalPop
>
</
el-dialog
>
</div>
</div>
</template>
</template>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.app-container__body
{
.app-container__body
{
height
:
calc
(
padding
:
20px
0
0
0
;
100vh
-
var
(
--navbar-height
)
-
var
(
--container-pd
)
-
var
(
--container-pd
)
.pageTitle
{
)
!important
;
margin-bottom
:
20px
;
.right
{
display
:
flex
;
padding
:
6px
10px
10px
;
align-items
:
center
;
height
:
100%
;
font-size
:
16px
;
&-title
{
font-weight
:
500
;
padding
:
0px
0px
10px
10px
;
letter-spacing
:
0px
;
display
:
flex
;
line-height
:
22px
;
align-items
:
center
;
color
:
rgba
(
53
,
64
,
79
,
1
);
font-weight
:
700
;
color
:
#515a6e
;
.icon
{
margin-right
:
6px
;
width
:
16px
;
height
:
16px
;
}
}
&
-content
{
}
padding
:
10px
0px
;
.box
{
width
:
80%
;
display
:
flex
;
margin
:
20px
auto
;
flex
:
1
;
.openEditor
{
overflow
:
hidden
;
position
:
absolute
;
.left
{
bottom
:
0
;
margin-right
:
30px
;
right
:
0
;
width
:
565px
;
overflow
:
auto
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
.searchBut
{
height
:
40px
;
background
:
var
(
--el-color-primary
);
color
:
var
(
--el-color-white
);
border-radius
:
0px
5px
5px
0px
;
}
.collapseView
{
width
:
100%
;
flex
:
1
;
overflow
:
hidden
;
}
}
}
}
&
-btn
{
.right
{
padding
:
20px
20px
20px
100px
;
flex
:
1
;
display
:
flex
;
height
:
100%
;
justify-content
:
center
;
background
:
rgba
(
255
,
255
,
255
,
1
);
.line
{
width
:
100%
;
height
:
2px
;
border-radius
:
5px
5px
0px
0px
;
background
:
linear-gradient
(
90deg
,
rgba
(
33
,
103
,
217
,
1
)
0%
,
rgba
(
17
,
200
,
250
,
1
)
34.03%
,
rgba
(
33
,
103
,
217
,
1
)
64.58%
,
rgba
(
48
,
128
,
255
,
1
)
100%
);
}
&
-content
{
width
:
100%
;
.openEditor
{
position
:
absolute
;
bottom
:
0
;
right
:
0
;
}
:deep
(
.formBox
)
{
border-radius
:
5px
;
background
:
#ebebeb
;
border
:
1px
solid
rgba
(
29
,
178
,
245
,
1
);
overflow
:
hidden
;
.el-form-item__content
{
margin-left
:
1px
;
background
:
#f5fcff
;
}
.el-form-item__label
{
height
:
40px
;
line-height
:
40px
;
background
:
#f5fcff
;
color
:
rgba
(
148
,
148
,
148
,
1
);
}
.el-form-item
{
margin-bottom
:
1px
;
}
.el-input
{
height
:
40px
;
line-height
:
40px
;
}
.is-disabled
{
background
:
#f5fcff
;
.el-input__wrapper
{
background
:
#f5fcff
;
box-shadow
:
none
;
border-radius
:
0
;
}
.el-input__inner
{
-webkit-text-fill-color
:
rgba
(
53
,
64
,
79
,
1
);
}
}
.el-form-item__error
{
top
:
30%
!important
;
left
:
auto
!important
;
right
:
89px
!important
;
}
}
}
&
-btn
{
padding
:
20px
20px
20px
100px
;
display
:
flex
;
justify-content
:
center
;
}
}
}
}
}
}
}
...
...
src/views/ruleConfig/Algorithm/modules/formModule.vue
View file @
f36a8ad9
...
@@ -39,10 +39,10 @@ const { form, rules } = toRefs(data);
...
@@ -39,10 +39,10 @@ const { form, rules } = toRefs(data);
const
editorShow
=
ref
(
false
);
const
editorShow
=
ref
(
false
);
const
readOnly
=
ref
(
true
);
const
readOnly
=
ref
(
true
);
const
editor
=
ref
({
const
editor
=
ref
({
rulename
:
''
,
rulename
:
""
,
expression
:
''
expression
:
""
,
});
});
const
rulenameList
=
ref
([])
const
rulenameList
=
ref
([])
;
const
formRef
=
ref
<
FormInstance
>
();
const
formRef
=
ref
<
FormInstance
>
();
// 重置
// 重置
...
@@ -61,7 +61,7 @@ const openEditor = () => {
...
@@ -61,7 +61,7 @@ const openEditor = () => {
editorShow
.
value
=
true
;
editorShow
.
value
=
true
;
editor
.
value
=
{
editor
.
value
=
{
rulename
:
form
.
value
.
rulename
,
rulename
:
form
.
value
.
rulename
,
expression
:
form
.
value
.
expression
expression
:
form
.
value
.
expression
,
};
};
};
};
...
@@ -109,7 +109,7 @@ const saveFunc = () => {
...
@@ -109,7 +109,7 @@ const saveFunc = () => {
const
validateRulename
=
(
rule
,
value
,
callback
)
=>
{
const
validateRulename
=
(
rule
,
value
,
callback
)
=>
{
const
state
=
rulenameList
.
value
.
includes
(
value
);
const
state
=
rulenameList
.
value
.
includes
(
value
);
if
(
state
)
{
if
(
state
)
{
callback
(
new
Error
(
'算法名称已存在'
));
callback
(
new
Error
(
"算法名称已存在"
));
}
else
{
}
else
{
callback
();
callback
();
}
}
...
@@ -138,8 +138,10 @@ watch(
...
@@ -138,8 +138,10 @@ watch(
if
(
props
.
itemData
)
{
if
(
props
.
itemData
)
{
const
data
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
itemData
));
const
data
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
itemData
));
form
.
value
=
{
...
form
.
value
,
...
data
};
form
.
value
=
{
...
form
.
value
,
...
data
};
if
(
props
.
type
===
'edit'
)
{
if
(
props
.
type
===
"edit"
)
{
rulenameList
.
value
=
rulenameList
.
value
.
filter
(
item
=>
item
!==
data
.
rulename
)
rulenameList
.
value
=
rulenameList
.
value
.
filter
(
(
item
)
=>
item
!==
data
.
rulename
);
}
}
}
}
},
},
...
@@ -151,8 +153,10 @@ watch(
...
@@ -151,8 +153,10 @@ watch(
(
newVal
)
=>
{
(
newVal
)
=>
{
rulenameList
.
value
=
props
.
nameList
;
rulenameList
.
value
=
props
.
nameList
;
const
data
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
itemData
));
const
data
=
JSON
.
parse
(
JSON
.
stringify
(
props
.
itemData
));
if
(
props
.
type
===
'edit'
&&
data
)
{
if
(
props
.
type
===
"edit"
&&
data
)
{
rulenameList
.
value
=
rulenameList
.
value
.
filter
(
item
=>
item
!==
data
.
rulename
)
rulenameList
.
value
=
rulenameList
.
value
.
filter
(
(
item
)
=>
item
!==
data
.
rulename
);
}
}
},
},
{
deep
:
true
,
immediate
:
true
}
{
deep
:
true
,
immediate
:
true
}
...
@@ -161,30 +165,31 @@ watch(
...
@@ -161,30 +165,31 @@ watch(
<
template
>
<
template
>
<div>
<div>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-width=
"100px"
:disabled=
"readOnly"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-width=
"110px"
:disabled=
"readOnly"
>
<el-form-item
label=
"算法名称"
prop=
"rulename"
required
<div
class=
"formBox"
>
:rules=
"[
{ required: true, message: '请输入算法名称', trigger:'blur' },{ required: true, validator: validateRulename, trigger:'blur' }]">
<el-form-item
label=
"算法名称"
prop=
"rulename"
required
<el-input
v-model=
"form.rulename"
></el-input>
:rules=
"[
{ required: true, message: '请输入算法名称', trigger:'blur' },{ required: true, validator: validateRulename, trigger:'blur' }]">
</el-form-item>
<el-input
v-model=
"form.rulename"
></el-input>
<el-form-item
label=
"表达式"
prop=
"expression"
required
>
</el-form-item>
<el-input
type=
"textarea"
rows=
"8"
v-model=
"form.expression"
></el-input>
<el-form-item
label=
"表达式"
prop=
"expression"
required
>
<el-button
class=
"openEditor"
type=
"primary"
@
click=
"openEditor"
>
打开编辑器
</el-button>
<el-input
v-model=
"form.expression"
></el-input>
</el-form-item>
<el-button
class=
"openEditor"
type=
"text"
@
click=
"openEditor"
v-if=
"!readOnly"
>
打开编辑器
</el-button>
<el-form-item
label=
"默认规则"
>
</el-form-item>
<Switch
true-value=
"1"
false-value=
"0"
v-model=
"form.defaluttype"
:disabled=
"readOnly"
>
<el-form-item
label=
"默认规则"
>
<template
#
open
>
<div
class=
"is-disabled"
v-if=
"readOnly"
style=
"width: 100%;height: 100%;"
>
<span>
是
</span>
<div
class=
"el-input__wrapper"
style=
"height: 100%;"
>
{{
form
.
defaluttype
===
'1'
?
'是'
:
'否'
}}
</div>
</
template
>
</div>
<
template
#
close
>
<el-radio-group
v-model=
"form.defaluttype"
v-if=
"!readOnly"
style=
"margin-left: 10px;"
>
<span>
否
</span>
<el-radio
label=
"0"
>
否
</el-radio>
</
template
>
<el-radio
label=
"1"
>
是
</el-radio>
</Switch>
</el-radio-group>
</el-form-item>
</el-form-item>
</div>
</el-form>
</el-form>
<div
class=
"btn"
>
<div
class=
"btn"
>
<el-button
type=
"primary"
style=
"width:
15
0px;"
@
click=
"readOnly = false"
v-if=
"readOnly"
>
编辑
</el-button>
<el-button
type=
"primary"
style=
"width:
8
0px;"
@
click=
"readOnly = false"
v-if=
"readOnly"
>
编辑
</el-button>
<el-button
type=
"
info"
style=
"width: 150px;"
@
click=
"cancel"
v-if=
"!readOnly"
>
取消
</el-button>
<el-button
type=
"
primary"
style=
"width: 80px;"
@
click=
"confirm"
v-if=
"!readOnly"
>
确认
</el-button>
<el-button
type=
"primary"
style=
"width: 150px;"
@
click=
"confirm"
v-if=
"!readOnly"
>
确认
</el-button>
<el-button
style=
"width: 80px;"
@
click=
"cancel"
v-if=
"!readOnly"
>
取消
</el-button>
</div>
</div>
<ExpressionEditor
v-model=
"editorShow"
:editor=
"editor"
@
cancel=
" editorShow = false"
@
confirm=
"formConfirm"
/>
<ExpressionEditor
v-model=
"editorShow"
:editor=
"editor"
@
cancel=
" editorShow = false"
@
confirm=
"formConfirm"
/>
...
@@ -195,11 +200,17 @@ watch(
...
@@ -195,11 +200,17 @@ watch(
.openEditor
{
.openEditor
{
position
:
absolute
;
position
:
absolute
;
bottom
:
0
;
bottom
:
0
;
right
:
0
;
top
:
0
;
right
:
10px
;
margin
:
auto
;
text-decoration
:
underline
;
}
}
.btn
{
.btn
{
padding
:
20px
;
padding
:
40px
20px
20px
20px
;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
}
}
:deep
(
.el-input__inner
)
{
height
:
34px
;
}
</
style
>
</
style
>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论