Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-vue-admin
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-vue-admin
Commits
e331c308
提交
e331c308
authored
2月 26, 2023
作者:
方治民
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 完成数据源管理模块静态界面开发
上级
ab45b098
显示空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
344 行增加
和
8 行删除
+344
-8
FormItem.vue
src/components/Form/src/components/FormItem.vue
+16
-2
index.less
src/components/Modal/src/index.less
+1
-0
BasicTable.vue
src/components/Table/src/BasicTable.vue
+7
-2
useTableScroll.ts
src/components/Table/src/hooks/useTableScroll.ts
+2
-2
Modal.vue
src/views/demo/tools/database/Modal.vue
+91
-0
data.ts
src/views/demo/tools/database/data.ts
+132
-0
index.vue
src/views/demo/tools/database/index.vue
+95
-2
没有找到文件。
src/components/Form/src/components/FormItem.vue
浏览文件 @
e331c308
...
@@ -56,6 +56,7 @@
...
@@ -56,6 +56,7 @@
const
itemLabelWidthProp
=
useItemLabelWidth
(
schema
,
formProps
)
const
itemLabelWidthProp
=
useItemLabelWidth
(
schema
,
formProps
)
const
getValues
=
computed
(()
=>
{
const
getValues
=
computed
(()
=>
{
const
{
allDefaultValues
,
formModel
,
schema
}
=
props
const
{
allDefaultValues
,
formModel
,
schema
}
=
props
// @ts-ignore
const
{
mergeDynamicData
}
=
props
.
formProps
const
{
mergeDynamicData
}
=
props
.
formProps
return
{
return
{
field
:
schema
.
field
,
field
:
schema
.
field
,
...
@@ -83,6 +84,7 @@
...
@@ -83,6 +84,7 @@
return
componentProps
as
Recordable
return
componentProps
as
Recordable
})
})
const
getDisable
=
computed
(()
=>
{
const
getDisable
=
computed
(()
=>
{
// @ts-ignore
const
{
disabled
:
globDisabled
}
=
props
.
formProps
const
{
disabled
:
globDisabled
}
=
props
.
formProps
const
{
dynamicDisabled
}
=
props
.
schema
const
{
dynamicDisabled
}
=
props
.
schema
const
{
disabled
:
itemDisabled
=
false
}
=
unref
(
getComponentsProps
)
const
{
disabled
:
itemDisabled
=
false
}
=
unref
(
getComponentsProps
)
...
@@ -97,6 +99,7 @@
...
@@ -97,6 +99,7 @@
})
})
function
getShow
():
{
isShow
:
boolean
;
isIfShow
:
boolean
}
{
function
getShow
():
{
isShow
:
boolean
;
isIfShow
:
boolean
}
{
const
{
show
,
ifShow
}
=
props
.
schema
const
{
show
,
ifShow
}
=
props
.
schema
// @ts-ignore
const
{
showAdvancedButton
}
=
props
.
formProps
const
{
showAdvancedButton
}
=
props
.
formProps
const
itemIsAdvanced
=
showAdvancedButton
const
itemIsAdvanced
=
showAdvancedButton
?
isBoolean
(
props
.
isAdvanced
)
?
isBoolean
(
props
.
isAdvanced
)
...
@@ -133,6 +136,7 @@
...
@@ -133,6 +136,7 @@
return
dynamicRules
(
unref
(
getValues
))
as
ValidationRule
[]
return
dynamicRules
(
unref
(
getValues
))
as
ValidationRule
[]
}
}
let
rules
:
ValidationRule
[]
=
cloneDeep
(
defRules
)
as
ValidationRule
[]
let
rules
:
ValidationRule
[]
=
cloneDeep
(
defRules
)
as
ValidationRule
[]
// @ts-ignore
const
{
rulesMessageJoinLabel
:
globalRulesMessageJoinLabel
}
=
props
.
formProps
const
{
rulesMessageJoinLabel
:
globalRulesMessageJoinLabel
}
=
props
.
formProps
const
joinLabel
=
Reflect
.
has
(
props
.
schema
,
'rulesMessageJoinLabel'
)
const
joinLabel
=
Reflect
.
has
(
props
.
schema
,
'rulesMessageJoinLabel'
)
?
rulesMessageJoinLabel
?
rulesMessageJoinLabel
...
@@ -210,7 +214,14 @@
...
@@ -210,7 +214,14 @@
return
rules
return
rules
}
}
function
renderComponent
()
{
function
renderComponent
()
{
const
{
renderComponentContent
,
component
,
field
,
changeEvent
=
'change'
,
valueField
}
=
props
.
schema
const
{
renderComponentContent
,
component
,
field
,
changeEvent
=
'change'
,
valueField
,
label
,
}
=
props
.
schema
const
isCheck
=
component
&&
[
'Switch'
,
'Checkbox'
].
includes
(
component
)
const
isCheck
=
component
&&
[
'Switch'
,
'Checkbox'
].
includes
(
component
)
const
eventKey
=
`on
${
upperFirst
(
changeEvent
)}
`
const
eventKey
=
`on
${
upperFirst
(
changeEvent
)}
`
const
on
=
{
const
on
=
{
...
@@ -225,6 +236,7 @@
...
@@ -225,6 +236,7 @@
},
},
}
}
const
Comp
=
componentMap
.
get
(
component
)
as
ReturnType
<
typeof
defineComponent
>
const
Comp
=
componentMap
.
get
(
component
)
as
ReturnType
<
typeof
defineComponent
>
// @ts-ignore
const
{
autoSetPlaceHolder
,
size
}
=
props
.
formProps
const
{
autoSetPlaceHolder
,
size
}
=
props
.
formProps
const
propsData
:
Recordable
=
{
const
propsData
:
Recordable
=
{
allowClear
:
true
,
allowClear
:
true
,
...
@@ -237,7 +249,7 @@
...
@@ -237,7 +249,7 @@
// RangePicker place is an array
// RangePicker place is an array
if
(
isCreatePlaceholder
&&
component
!==
'RangePicker'
&&
component
)
{
if
(
isCreatePlaceholder
&&
component
!==
'RangePicker'
&&
component
)
{
propsData
.
placeholder
=
propsData
.
placeholder
=
unref
(
getComponentsProps
)?.
placeholder
||
createPlaceholderMessage
(
component
)
unref
(
getComponentsProps
)?.
placeholder
||
createPlaceholderMessage
(
component
)
+
label
}
}
propsData
.
codeField
=
field
propsData
.
codeField
=
field
propsData
.
formValues
=
unref
(
getValues
)
propsData
.
formValues
=
unref
(
getValues
)
...
@@ -282,6 +294,7 @@
...
@@ -282,6 +294,7 @@
function
renderItem
()
{
function
renderItem
()
{
const
{
itemProps
,
slot
,
render
,
field
,
suffix
,
component
}
=
props
.
schema
const
{
itemProps
,
slot
,
render
,
field
,
suffix
,
component
}
=
props
.
schema
const
{
labelCol
,
wrapperCol
}
=
unref
(
itemLabelWidthProp
)
const
{
labelCol
,
wrapperCol
}
=
unref
(
itemLabelWidthProp
)
// @ts-ignore
const
{
colon
}
=
props
.
formProps
const
{
colon
}
=
props
.
formProps
if
(
component
===
'Divider'
)
{
if
(
component
===
'Divider'
)
{
return
(
return
(
...
@@ -323,6 +336,7 @@
...
@@ -323,6 +336,7 @@
if
(
!
componentMap
.
has
(
component
))
{
if
(
!
componentMap
.
has
(
component
))
{
return
null
return
null
}
}
// @ts-ignore
const
{
baseColProps
=
{}
}
=
props
.
formProps
const
{
baseColProps
=
{}
}
=
props
.
formProps
const
realColProps
=
{
...
baseColProps
,
...
colProps
}
const
realColProps
=
{
...
baseColProps
,
...
colProps
}
const
{
isIfShow
,
isShow
}
=
getShow
()
const
{
isIfShow
,
isShow
}
=
getShow
()
...
...
src/components/Modal/src/index.less
浏览文件 @
e331c308
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
left: 0 !important;
left: 0 !important;
width: 100% !important;
width: 100% !important;
height: 100%;
height: 100%;
max-width: 100vw !important;
&-content {
&-content {
height: 100%;
height: 100%;
...
...
src/components/Table/src/BasicTable.vue
浏览文件 @
e331c308
...
@@ -324,11 +324,16 @@
...
@@ -324,11 +324,16 @@
.ant-form
{
.ant-form
{
width
:
100%
;
width
:
100%
;
padding
:
12px
1
0
px
6px
;
padding
:
12px
1
2
px
6px
;
margin-bottom
:
16px
;
margin-bottom
:
16px
;
background-color
:
@
component-background
;
background-color
:
@
component-background
;
border-radius
:
2px
;
border-radius
:
2px
;
}
}
.ant-form-inline
.ant-form-item-control-input-content
{
display
:
flex
;
flex-direction
:
row
;
}
}
}
.ant-tag
{
.ant-tag
{
...
@@ -336,7 +341,7 @@
...
@@ -336,7 +341,7 @@
}
}
.ant-table-wrapper
{
.ant-table-wrapper
{
padding
:
6
px
;
padding
:
12
px
;
background-color
:
@
component-background
;
background-color
:
@
component-background
;
border-radius
:
2px
;
border-radius
:
2px
;
...
...
src/components/Table/src/hooks/useTableScroll.ts
浏览文件 @
e331c308
...
@@ -97,7 +97,7 @@ export function useTableScroll(
...
@@ -97,7 +97,7 @@ export function useTableScroll(
if
(
!
headEl
)
return
if
(
!
headEl
)
return
// Table height from bottom height-custom offset
// Table height from bottom height-custom offset
let
paddingHeight
=
3
2
let
paddingHeight
=
3
8
// Pager height
// Pager height
let
paginationHeight
=
2
let
paginationHeight
=
2
if
(
!
isBoolean
(
pagination
))
{
if
(
!
isBoolean
(
pagination
))
{
...
@@ -130,7 +130,7 @@ export function useTableScroll(
...
@@ -130,7 +130,7 @@ export function useTableScroll(
let
bottomIncludeBody
=
0
let
bottomIncludeBody
=
0
if
(
unref
(
wrapRef
)
&&
isCanResizeParent
)
{
if
(
unref
(
wrapRef
)
&&
isCanResizeParent
)
{
const
tablePadding
=
12
const
tablePadding
=
24
const
formMargin
=
16
const
formMargin
=
16
let
paginationMargin
=
10
let
paginationMargin
=
10
const
wrapHeight
=
unref
(
wrapRef
)?.
offsetHeight
??
0
const
wrapHeight
=
unref
(
wrapRef
)?.
offsetHeight
??
0
...
...
src/views/demo/tools/database/Modal.vue
0 → 100644
浏览文件 @
e331c308
<
script
lang=
"ts"
setup
>
import
{
Button
}
from
'ant-design-vue'
import
{
Icon
}
from
'/@/components/Icon'
import
{
BasicForm
,
useForm
}
from
'/@/components/Form'
import
{
BasicModal
,
useModalInner
}
from
'/@/components/Modal'
import
{
options
}
from
'./data'
const
[
registerModal
]
=
useModalInner
((
data
)
=>
{
console
.
log
(
data
)
})
const
[
registerEditForm
]
=
useForm
({
colon
:
true
,
labelWidth
:
120
,
showActionButtonGroup
:
false
,
schemas
:
[
{
field
:
'name'
,
label
:
'数据源名称'
,
required
:
true
,
component
:
'Input'
,
colProps
:
{
span
:
24
},
},
{
field
:
'type'
,
label
:
'数据库类型'
,
required
:
true
,
component
:
'Select'
,
componentProps
:
{
options
,
},
colProps
:
{
span
:
24
},
},
{
field
:
'driver'
,
label
:
'驱动类'
,
required
:
true
,
component
:
'Input'
,
colProps
:
{
span
:
24
},
},
{
field
:
'url'
,
label
:
'数据源地址'
,
required
:
true
,
component
:
'Input'
,
colProps
:
{
span
:
24
},
},
{
field
:
'username'
,
label
:
'用户名'
,
required
:
true
,
component
:
'Input'
,
colProps
:
{
span
:
24
},
},
{
field
:
'password'
,
label
:
'密码'
,
required
:
true
,
component
:
'InputPassword'
,
colProps
:
{
span
:
24
},
},
{
field
:
'remark'
,
label
:
'备注'
,
component
:
'InputTextArea'
,
colProps
:
{
span
:
24
},
},
],
})
const
testing
=
ref
<
boolean
>
(
false
)
const
test
=
()
=>
{}
</
script
>
<
template
>
<BasicModal
v-bind=
"$attrs"
@
register=
"registerModal"
destroyOnClose
:maskClosable=
"false"
>
<div
class=
"pr-20px"
>
<BasicForm
@
register=
"registerEditForm"
/>
</div>
<template
#
insertFooter
>
<Button
type=
"dashed"
danger
@
click=
"test"
:disabled=
"testing"
>
<Icon
icon=
"fluent-emoji-high-contrast:test-tube"
/>
测试连接
</Button>
</
template
>
</BasicModal>
</template>
<
style
lang=
"less"
scoped
>
/** ... */
</
style
>
src/views/demo/tools/database/data.ts
0 → 100644
浏览文件 @
e331c308
import
{
BasicColumn
,
FormProps
}
from
'@/components/Table'
interface
Option
{
label
:
string
value
:
string
property
?:
{
driver
?:
string
url
?:
string
}
disabled
?:
boolean
}
/**
* 支持的数据源类型
*/
export
const
options
:
Option
[]
=
[
{
label
:
'PostgreSQL'
,
value
:
'PostgreSQL'
,
property
:
{
driver
:
'org.postgresql.Driver'
,
url
:
'jdbc:postgresql://127.0.0.1:5432/basic-boot'
,
},
},
{
label
:
'H2'
,
value
:
'H2'
,
property
:
{
driver
:
'org.h2.Driver'
,
url
:
'jdbc:h2:file:~/h2_basic;DB_CLOSE_ON_EXIT=FALSE'
,
},
},
{
label
:
'MySQL 8.x'
,
value
:
'MySQL'
,
property
:
{
driver
:
'com.mysql.cj.jdbc.Driver'
,
url
:
'jdbc:mysql://127.0.0.1:3306/basic-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai'
,
},
disabled
:
true
,
},
{
label
:
'其他数据库'
,
value
:
'custom'
,
property
:
{
driver
:
''
,
url
:
''
,
},
},
]
// ================================
export
function
getColumns
():
BasicColumn
[]
{
return
[
{
title
:
'数据源名称'
,
dataIndex
:
'name'
,
width
:
180
,
},
{
title
:
'数据库类型'
,
dataIndex
:
'type'
,
width
:
150
,
},
{
title
:
'驱动类'
,
dataIndex
:
'driver'
,
},
{
title
:
'数据源地址'
,
dataIndex
:
'url'
,
},
{
title
:
'用户名'
,
dataIndex
:
'username'
,
width
:
150
,
},
{
title
:
'创建时间'
,
dataIndex
:
'createTime'
,
defaultHidden
:
true
,
width
:
180
,
},
]
}
export
function
getDataSource
()
{
return
(()
=>
{
const
data
=
[]
data
.
push
({
id
:
'1'
,
name
:
'PostgreSQL 14'
,
type
:
'PostgreSQL'
,
driver
:
'org.postgresql.Driver'
,
url
:
'jdbc:postgresql://127.0.0.1:5432/basic-boot'
,
username
:
'postgres'
,
password
:
'postgres'
,
createTime
:
'2023-02-26 15:36:01'
,
})
return
data
})()
}
export
function
getFormConfig
():
Partial
<
FormProps
>
{
return
{
layout
:
'inline'
,
colon
:
true
,
compact
:
true
,
schemas
:
[
{
field
:
`name`
,
label
:
`数据源名称`
,
component
:
'Input'
,
},
{
field
:
`type`
,
label
:
`数据库类型`
,
component
:
'Select'
,
componentProps
:
{
options
,
style
:
{
width
:
'180px'
,
},
},
},
],
showAdvancedButton
:
false
,
submitButtonOptions
:
{
preIcon
:
'material-symbols:search'
,
},
}
}
src/views/demo/tools/database/index.vue
浏览文件 @
e331c308
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
PageComing
}
from
'/@/components/Page'
import
{
Button
,
Space
}
from
'ant-design-vue'
import
{
Icon
}
from
'/@/components/Icon'
import
{
useModal
}
from
'/@/components/Modal'
import
{
ActionItem
,
BasicColumn
,
BasicTable
,
EditRecordRow
,
useTable
,
TableAction
}
from
'/@/components/Table'
import
Modal
from
'./Modal.vue'
import
{
getColumns
,
getDataSource
,
getFormConfig
}
from
'./data'
const
[
registerTable
]
=
useTable
({
size
:
'small'
,
bordered
:
true
,
canResize
:
true
,
columns
:
getColumns
(),
dataSource
:
getDataSource
(),
rowKey
:
(
record
)
=>
record
.
id
,
useSearchForm
:
true
,
formConfig
:
getFormConfig
(),
showTableSetting
:
true
,
tableSetting
:
{
fullScreen
:
true
},
actionColumn
:
{
width
:
160
,
title
:
'操作'
,
dataIndex
:
'action'
,
},
})
function
createActions
(
record
:
EditRecordRow
,
column
:
BasicColumn
):
ActionItem
[]
{
return
[
{
label
:
'编辑'
,
onClick
:
()
=>
editHandler
(
'编辑'
,
record
),
},
{
label
:
'删除'
,
popConfirm
:
{
title
:
'是否删除'
,
confirm
:
()
=>
console
.
log
(
record
,
column
),
},
},
]
}
const
[
registerModal
,
{
openModal
,
setModalProps
}]
=
useModal
()
// 新增/编辑打开窗口
const
editHandler
=
(
type
:
'新增'
|
'编辑'
,
data
?:
Recordable
)
=>
{
setModalProps
({
title
:
type
+
'数据源'
})
openModal
(
true
,
data
)
}
// 导入
const
importHandler
=
()
=>
{}
// 下载导入模板
const
importTemplateHandler
=
()
=>
{}
// 导出
const
exportHandler
=
()
=>
{}
</
script
>
</
script
>
<
template
>
<
template
>
<PageComing
/>
<!-- 数据表格 -->
<BasicTable
@
register=
"registerTable"
>
<template
#
form-custom
>
custom-slot
</
template
>
<
template
#
tableTitle
>
<Space>
<Button
type=
"primary"
@
click=
"editHandler('新增')"
>
<template
#
icon
>
<Icon
icon=
"ant-design:plus-outlined"
/>
</
template
>
新增
</Button>
<Button
type=
"dashed"
danger
@
click=
"exportHandler"
>
<
template
#
icon
>
<Icon
icon=
"ant-design:export-outlined"
/>
</
template
>
导出
</Button>
<Button
type=
"dashed"
@
click=
"importHandler"
>
<
template
#
icon
>
<Icon
icon=
"ant-design:import-outlined"
/>
</
template
>
导入
</Button>
<Button
type=
"default"
@
click=
"importTemplateHandler"
>
<
template
#
icon
>
<Icon
icon=
"material-symbols:cloud-download"
/>
</
template
>
导入模板下载
</Button>
</Space>
</template>
<
template
#
bodyCell=
"{ column, record }"
>
<template
v-if=
"column.key === 'action'"
>
<TableAction
:actions=
"createActions(record, column)"
/>
</
template
>
</template>
</BasicTable>
<!-- 新增/编辑弹窗 -->
<Modal
@
register=
"registerModal"
/>
</template>
</template>
<
style
lang=
"less"
scoped
>
<
style
lang=
"less"
scoped
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论