Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
9cde4885
authored
May 09, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
form-create: 完善 select 远程搜索
parent
40fe8792
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
124 additions
and
86 deletions
+124
-86
src/components/FormCreate/src/components/useApiSelect.tsx
+90
-18
src/components/FormCreate/src/config/selectRule.ts
+28
-6
src/components/FormCreate/src/config/useDictSelectRule.ts
+3
-1
src/components/FormCreate/src/config/useSelectRule.ts
+3
-1
src/components/FormCreate/src/utils/index.ts
+0
-60
No files found.
src/components/FormCreate/src/components/useApiSelect.tsx
View file @
9cde4885
...
@@ -46,43 +46,88 @@ export const useApiSelect = (option: ApiSelectProps) => {
...
@@ -46,43 +46,88 @@ export const useApiSelect = (option: ApiSelectProps) => {
multiple
:
{
multiple
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
false
default
:
false
},
// 是否远程搜索
remote
:
{
type
:
Boolean
,
default
:
false
},
// 远程搜索时携带的参数
remoteField
:
{
type
:
String
,
default
:
'label'
}
}
},
},
setup
(
props
)
{
setup
(
props
)
{
const
attrs
=
useAttrs
()
const
attrs
=
useAttrs
()
const
options
=
ref
<
any
[]
>
([])
// 下拉数据
const
options
=
ref
<
any
[]
>
([])
// 下拉数据
const
loading
=
ref
(
false
)
// 是否正在从远程获取数据
const
queryParam
=
ref
<
any
>
()
// 当前输入的值
const
getOptions
=
async
()
=>
{
const
getOptions
=
async
()
=>
{
options
.
value
=
[]
options
.
value
=
[]
// 接口选择器
// 接口选择器
if
(
isEmpty
(
props
.
url
))
{
if
(
isEmpty
(
props
.
url
))
{
return
return
}
}
let
data
=
[]
switch
(
props
.
method
)
{
switch
(
props
.
method
)
{
case
'GET'
:
case
'GET'
:
data
=
await
request
.
get
({
url
:
props
.
url
})
let
url
:
string
=
props
.
url
if
(
props
.
remote
)
{
url
=
`
${
url
}
?
${
props
.
remoteField
}
=
${
queryParam
.
value
}
`
}
parseOptions
(
await
request
.
get
({
url
:
url
}))
break
break
case
'POST'
:
case
'POST'
:
data
=
await
request
.
post
({
url
:
props
.
url
,
data
:
jsonParse
(
props
.
data
)
})
const
data
:
any
=
jsonParse
(
props
.
data
)
if
(
props
.
remote
)
{
data
[
props
.
remoteField
]
=
queryParam
.
value
}
parseOptions
(
await
request
.
post
({
url
:
props
.
url
,
data
:
data
}))
break
break
}
}
}
function
parseOptions
(
data
:
any
)
{
// 情况一:如果有自定义解析函数优先使用自定义解析
if
(
!
isEmpty
(
props
.
parseFunc
))
{
options
.
value
=
parseFunc
()?.(
data
)
return
}
// 情况二:返回的直接是一个列表
if
(
Array
.
isArray
(
data
))
{
if
(
Array
.
isArray
(
data
))
{
let
parse
:
any
=
null
parseOptions0
(
data
)
if
(
!!
props
.
parseFunc
)
{
return
// 解析字符串函数
}
parse
=
new
Function
(
`return
${
props
.
parseFunc
}
`
)()
// 情况二:返回的是分页数据,尝试读取 list
}
data
=
data
.
list
options
.
value
=
data
.
map
(
if
(
!!
data
&&
Array
.
isArray
(
data
))
{
(
item
:
any
)
=>
parseOptions0
(
data
)
parse
?.(
item
)
??
{
return
label
:
parseExpression
(
item
,
props
.
labelField
),
}
value
:
parseExpression
(
item
,
props
.
valueField
)
// 情况三:不是 yudao-vue-pro 标准返回
}
console
.
warn
(
)
`接口[
${
props
.
url
}
] 返回结果不是 yudao-vue-pro 标准返回建议采用自定义解析函数处理`
)
}
function
parseOptions0
(
data
:
any
[])
{
if
(
Array
.
isArray
(
data
))
{
options
.
value
=
data
.
map
((
item
:
any
)
=>
({
label
:
parseExpression
(
item
,
props
.
labelField
),
value
:
parseExpression
(
item
,
props
.
valueField
)
}))
return
return
}
}
console
.
log
(
`接口[
${
props
.
url
}
] 返回结果不是一个数组`
)
console
.
warn
(
`接口[
${
props
.
url
}
] 返回结果不是一个数组`
)
}
function
parseFunc
()
{
let
parse
:
any
=
null
if
(
!!
props
.
parseFunc
)
{
// 解析字符串函数
parse
=
new
Function
(
`return
${
props
.
parseFunc
}
`
)()
}
return
parse
}
}
function
parseExpression
(
data
:
any
,
template
:
string
)
{
function
parseExpression
(
data
:
any
,
template
:
string
)
{
...
@@ -105,6 +150,19 @@ export const useApiSelect = (option: ApiSelectProps) => {
...
@@ -105,6 +150,19 @@ export const useApiSelect = (option: ApiSelectProps) => {
})
})
}
}
const
remoteMethod
=
async
(
query
:
any
)
=>
{
if
(
!
query
)
{
return
}
loading
.
value
=
true
try
{
queryParam
.
value
=
query
await
getOptions
()
}
finally
{
loading
.
value
=
false
}
}
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
await
getOptions
()
await
getOptions
()
})
})
...
@@ -113,15 +171,29 @@ export const useApiSelect = (option: ApiSelectProps) => {
...
@@ -113,15 +171,29 @@ export const useApiSelect = (option: ApiSelectProps) => {
if
(
props
.
multiple
)
{
if
(
props
.
multiple
)
{
// fix:多写此步是为了解决 multiple 属性问题
// fix:多写此步是为了解决 multiple 属性问题
return
(
return
(
<
el
-
select
class=
"w-1/1"
{
...
attrs
}
multiple
>
<
el
-
select
class=
"w-1/1"
multiple
loading=
{
loading
.
value
}
{
...
attrs
}
remote=
{
props
.
remote
}
{
...
(
props
.
remote
&&
{
remoteMethod
:
remoteMethod
})}
>
{
options
.
value
.
map
((
item
,
index
)
=>
(
{
options
.
value
.
map
((
item
,
index
)
=>
(
<
el
-
option
key=
{
index
}
label=
{
item
.
label
}
value=
{
item
.
value
}
/>
<
el
-
option
key=
{
index
}
label=
{
item
.
label
}
value=
{
item
.
value
}
/>
))
}
))
}
</
el
-
select
>
</
el
-
select
>
)
)
}
}
debugger
return
(
return
(
<
el
-
select
class=
"w-1/1"
{
...
attrs
}
>
<
el
-
select
class=
"w-1/1"
loading=
{
loading
.
value
}
{
...
attrs
}
remote=
{
props
.
remote
}
{
...
(
props
.
remote
&&
{
remoteMethod
:
remoteMethod
})}
>
{
options
.
value
.
map
((
item
,
index
)
=>
(
{
options
.
value
.
map
((
item
,
index
)
=>
(
<
el
-
option
key=
{
index
}
label=
{
item
.
label
}
value=
{
item
.
value
}
/>
<
el
-
option
key=
{
index
}
label=
{
item
.
label
}
value=
{
item
.
value
}
/>
))
}
))
}
...
...
src/components/FormCreate/src/config/selectRule.ts
View file @
9cde4885
...
@@ -15,7 +15,20 @@ const selectRule = [
...
@@ -15,7 +15,20 @@ const selectRule = [
value
:
'select'
,
value
:
'select'
,
condition
:
'=='
,
condition
:
'=='
,
method
:
'hidden'
,
method
:
'hidden'
,
rule
:
[
'multiple'
]
rule
:
[
'multiple'
,
'clearable'
,
'collapseTags'
,
'multipleLimit'
,
'allowCreate'
,
'filterable'
,
'noMatchText'
,
'remote'
,
'remoteMethod'
,
'reserveKeyword'
,
'defaultFirstOption'
,
'automaticDropdown'
]
}
}
]
]
},
},
...
@@ -60,9 +73,10 @@ const selectRule = [
...
@@ -60,9 +73,10 @@ const selectRule = [
title
:
'其中的选项是否从服务器远程加载'
title
:
'其中的选项是否从服务器远程加载'
},
},
{
{
type
:
'Struct'
,
type
:
'input'
,
field
:
'remoteMethod'
,
field
:
'remoteField'
,
title
:
'自定义远程搜索方法'
title
:
'请求参数'
,
info
:
'远程请求时请求携带的参数名称,如:name'
},
},
{
type
:
'input'
,
field
:
'noDataText'
,
title
:
'选项为空时显示的文字'
},
{
type
:
'input'
,
field
:
'noDataText'
,
title
:
'选项为空时显示的文字'
},
{
{
...
@@ -130,6 +144,7 @@ const apiSelectRule = [
...
@@ -130,6 +144,7 @@ const apiSelectRule = [
type
:
'input'
,
type
:
'input'
,
field
:
'labelField'
,
field
:
'labelField'
,
title
:
'label 属性'
,
title
:
'label 属性'
,
info
:
'可以使用 el 表达式:${属性},来实现复杂数据组合。如:${nickname}-${id}'
,
props
:
{
props
:
{
placeholder
:
'nickname'
placeholder
:
'nickname'
}
}
...
@@ -138,6 +153,7 @@ const apiSelectRule = [
...
@@ -138,6 +153,7 @@ const apiSelectRule = [
type
:
'input'
,
type
:
'input'
,
field
:
'valueField'
,
field
:
'valueField'
,
title
:
'value 属性'
,
title
:
'value 属性'
,
info
:
'可以使用 el 表达式:${属性},来实现复杂数据组合。如:${nickname}-${id}'
,
props
:
{
props
:
{
placeholder
:
'id'
placeholder
:
'id'
}
}
...
@@ -146,11 +162,17 @@ const apiSelectRule = [
...
@@ -146,11 +162,17 @@ const apiSelectRule = [
type
:
'input'
,
type
:
'input'
,
field
:
'parseFunc'
,
field
:
'parseFunc'
,
title
:
'选项解析函数'
,
title
:
'选项解析函数'
,
info
:
'(data: any)=>{ label: string; value: any }'
,
info
:
`data 为接口返回值,需要写一个匿名函数解析返回值为选择器 options 列表
(data: any)=>{ label: string; value: any }[]`
,
props
:
{
props
:
{
autosize
:
true
,
autosize
:
true
,
rows
:
{
minRows
:
2
,
maxRows
:
6
},
rows
:
{
minRows
:
2
,
maxRows
:
6
},
type
:
'textarea'
type
:
'textarea'
,
placeholder
:
`
function (data) {
console.log(data)
return data.list.map(item=> ({label: item.nickname,value: item.id}))
}`
}
}
}
}
]
]
...
...
src/components/FormCreate/src/config/useDictSelectRule.ts
View file @
9cde4885
...
@@ -2,6 +2,7 @@ import { generateUUID } from '@/utils'
...
@@ -2,6 +2,7 @@ import { generateUUID } from '@/utils'
import
*
as
DictDataApi
from
'@/api/system/dict/dict.type'
import
*
as
DictDataApi
from
'@/api/system/dict/dict.type'
import
{
localeProps
,
makeRequiredRule
}
from
'@/components/FormCreate/src/utils'
import
{
localeProps
,
makeRequiredRule
}
from
'@/components/FormCreate/src/utils'
import
{
selectRule
}
from
'@/components/FormCreate/src/config/selectRule'
import
{
selectRule
}
from
'@/components/FormCreate/src/config/selectRule'
import
{
cloneDeep
}
from
'lodash-es'
/**
/**
* 字典选择器规则,如果规则使用到动态数据则需要单独配置不能使用 useSelectRule
* 字典选择器规则,如果规则使用到动态数据则需要单独配置不能使用 useSelectRule
...
@@ -9,6 +10,7 @@ import { selectRule } from '@/components/FormCreate/src/config/selectRule'
...
@@ -9,6 +10,7 @@ import { selectRule } from '@/components/FormCreate/src/config/selectRule'
export
const
useDictSelectRule
=
()
=>
{
export
const
useDictSelectRule
=
()
=>
{
const
label
=
'字典选择器'
const
label
=
'字典选择器'
const
name
=
'DictSelect'
const
name
=
'DictSelect'
const
rules
=
cloneDeep
(
selectRule
)
const
dictOptions
=
ref
<
{
label
:
string
;
value
:
string
}[]
>
([])
// 字典类型下拉数据
const
dictOptions
=
ref
<
{
label
:
string
;
value
:
string
}[]
>
([])
// 字典类型下拉数据
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
const
data
=
await
DictDataApi
.
getSimpleDictTypeList
()
const
data
=
await
DictDataApi
.
getSimpleDictTypeList
()
...
@@ -55,7 +57,7 @@ export const useDictSelectRule = () => {
...
@@ -55,7 +57,7 @@ export const useDictSelectRule = () => {
{
label
:
'布尔值'
,
value
:
'bool'
}
{
label
:
'布尔值'
,
value
:
'bool'
}
]
]
},
},
...
selectRule
...
rules
])
])
}
}
}
}
...
...
src/components/FormCreate/src/config/useSelectRule.ts
View file @
9cde4885
...
@@ -2,6 +2,7 @@ import { generateUUID } from '@/utils'
...
@@ -2,6 +2,7 @@ import { generateUUID } from '@/utils'
import
{
localeProps
,
makeRequiredRule
}
from
'@/components/FormCreate/src/utils'
import
{
localeProps
,
makeRequiredRule
}
from
'@/components/FormCreate/src/utils'
import
{
selectRule
}
from
'@/components/FormCreate/src/config/selectRule'
import
{
selectRule
}
from
'@/components/FormCreate/src/config/selectRule'
import
{
SelectRuleOption
}
from
'@/components/FormCreate/src/type'
import
{
SelectRuleOption
}
from
'@/components/FormCreate/src/type'
import
{
cloneDeep
}
from
'lodash-es'
/**
/**
* 通用选择器规则 hook
* 通用选择器规则 hook
...
@@ -10,6 +11,7 @@ import { SelectRuleOption } from '@/components/FormCreate/src/type'
...
@@ -10,6 +11,7 @@ import { SelectRuleOption } from '@/components/FormCreate/src/type'
export
const
useSelectRule
=
(
option
:
SelectRuleOption
)
=>
{
export
const
useSelectRule
=
(
option
:
SelectRuleOption
)
=>
{
const
label
=
option
.
label
const
label
=
option
.
label
const
name
=
option
.
name
const
name
=
option
.
name
const
rules
=
cloneDeep
(
selectRule
)
return
{
return
{
icon
:
option
.
icon
,
icon
:
option
.
icon
,
label
,
label
,
...
@@ -27,7 +29,7 @@ export const useSelectRule = (option: SelectRuleOption) => {
...
@@ -27,7 +29,7 @@ export const useSelectRule = (option: SelectRuleOption) => {
if
(
!
option
.
props
)
{
if
(
!
option
.
props
)
{
option
.
props
=
[]
option
.
props
=
[]
}
}
return
localeProps
(
t
,
name
+
'.props'
,
[
makeRequiredRule
(),
...
option
.
props
,
...
selectRule
])
return
localeProps
(
t
,
name
+
'.props'
,
[
makeRequiredRule
(),
...
option
.
props
,
...
rules
])
}
}
}
}
}
}
src/components/FormCreate/src/utils/index.ts
View file @
9cde4885
...
@@ -16,63 +16,3 @@ export const localeProps = (t, prefix, rules) => {
...
@@ -16,63 +16,3 @@ export const localeProps = (t, prefix, rules) => {
return
rule
return
rule
})
})
}
}
export
function
upper
(
str
)
{
return
str
.
replace
(
str
[
0
],
str
[
0
].
toLocaleUpperCase
())
}
export
function
makeOptionsRule
(
t
,
to
,
userOptions
)
{
console
.
log
(
userOptions
[
0
])
const
options
=
[
{
label
:
t
(
'props.optionsType.struct'
),
value
:
0
},
{
label
:
t
(
'props.optionsType.json'
),
value
:
1
},
{
label
:
'用户数据'
,
value
:
2
}
]
const
control
=
[
{
value
:
0
,
rule
:
[
{
type
:
'TableOptions'
,
field
:
'formCreate'
+
upper
(
to
).
replace
(
'.'
,
'>'
),
props
:
{
defaultValue
:
[]
}
}
]
},
{
value
:
1
,
rule
:
[
{
type
:
'Struct'
,
field
:
'formCreate'
+
upper
(
to
).
replace
(
'.'
,
'>'
),
props
:
{
defaultValue
:
[]
}
}
]
},
{
value
:
2
,
rule
:
[
{
type
:
'TableOptions'
,
field
:
'formCreate'
+
upper
(
to
).
replace
(
'.'
,
'>'
),
props
:
{
modelValue
:
[]
}
}
]
}
]
options
.
splice
(
0
,
0
)
control
.
push
()
return
{
type
:
'radio'
,
title
:
t
(
'props.options'
),
field
:
'_optionType'
,
value
:
0
,
options
,
props
:
{
type
:
'button'
},
control
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment