Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
xiaojuan huang
Ccms
Commits
c2581279
Commit
c2581279
authored
3 years ago
by
wangailin
Browse files
Options
Download
Email Patches
Plain Diff
feat: 新增树行选项; 长文本的验证与接口数据获取的比对
parent
917ecea9
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
package.json
+1
-1
package.json
src/components/formFields/index.tsx
+5
-1
src/components/formFields/index.tsx
src/components/formFields/longtext/index.tsx
+2
-2
src/components/formFields/longtext/index.tsx
src/components/formFields/treeSelect/index.tsx
+260
-0
src/components/formFields/treeSelect/index.tsx
src/index.tsx
+1
-0
src/index.tsx
src/util/request.ts
+1
-1
src/util/request.ts
with
270 additions
and
5 deletions
+270
-5
package.json
+
1
-
1
View file @
c2581279
{
"name"
:
"ccms"
,
"version"
:
"1.0.
4
"
,
"version"
:
"1.0.
5
"
,
"description"
:
"ConfigableCMS"
,
"main"
:
"lib/index.js"
,
"module"
:
"dist/index.js"
,
...
...
This diff is collapsed.
Click to expand it.
src/components/formFields/index.tsx
+
5
-
1
View file @
c2581279
...
...
@@ -2,6 +2,7 @@
import
FormField
,
{
FormFieldConfig
}
from
'
./form
'
import
TextField
,
{
TextFieldConfig
}
from
'
./text
'
import
RadioField
,
{
RadioFieldConfig
}
from
'
./radio
'
import
TreeSelectField
,
{
TreeSelectFieldConfig
}
from
'
./treeSelect
'
import
LongtextField
,
{
LongtextFieldConfig
}
from
'
./longtext
'
import
NumberField
,
{
NumberFieldConfig
}
from
'
./number
'
import
DatetimeField
,
{
DatetimeFieldConfig
}
from
'
./datetime
'
...
...
@@ -29,6 +30,7 @@ export type FieldConfigs = TextFieldConfig
|
SelectMultipleFieldConfig
|
HiddenFieldConfig
|
DescFieldConfig
|
TreeSelectFieldConfig
export
interface
componentType
{
type
:
'
text
'
...
...
@@ -43,6 +45,7 @@ export interface componentType {
|
'
hidden
'
|
'
none
'
|
'
desc
'
|
'
tree_select
'
}
export
default
{
...
...
@@ -55,5 +58,6 @@ export default {
datetimeRange
:
DatetimeRangeField
,
select_single
:
SelectSingleField
,
select_multiple
:
SelectMultipleField
,
desc
:
DescField
desc
:
DescField
,
tree_select
:
TreeSelectField
}
This diff is collapsed.
Click to expand it.
src/components/formFields/longtext/index.tsx
+
2
-
2
View file @
c2581279
...
...
@@ -96,7 +96,7 @@ export default class LongTextField extends Field<LongtextFieldConfig, ILongtextF
}
valueMaxLength
=
valueMaxLength
.
replace
(
/
[\u
4e00-
\u
9fa5
]
/g
,
valueMaxCJKLength
)
}
if
(
valueMaxLength
&&
valueMaxLength
.
length
>
maxLength
)
{
if
(
valueMaxLength
&&
maxLength
>=
0
&&
valueMaxLength
.
length
>
maxLength
)
{
errors
.
push
(
new
FieldError
(
`最长可输入
${
maxLength
}
个字符。`
))
}
}
...
...
@@ -110,7 +110,7 @@ export default class LongTextField extends Field<LongtextFieldConfig, ILongtextF
}
valueMinLength
=
valueMinLength
.
replace
(
/
[\u
4e00-
\u
9fa5
]
/g
,
valueMinCJKLength
)
}
if
(
valueMinLength
&&
valueMinLength
.
length
<
minLength
)
{
if
(
valueMinLength
&&
minLength
>=
0
&&
valueMinLength
.
length
<
minLength
)
{
errors
.
push
(
new
FieldError
(
`最短需输入
${
minLength
}
个字符。`
))
}
}
...
...
This diff is collapsed.
Click to expand it.
src/components/formFields/treeSelect/index.tsx
0 → 100644
+
260
-
0
View file @
c2581279
import
React
from
'
react
'
import
{
ReactNode
}
from
'
react
'
import
{
APIConfig
,
ParamConfig
}
from
'
../../../interface
'
import
{
request
}
from
'
../../../util/request
'
import
{
getParam
,
getValue
,
setValue
}
from
'
../../../util/value
'
import
{
Field
,
FieldConfig
,
IField
}
from
'
../common
'
import
{
FieldError
}
from
'
../common
'
export
interface
TreeSelectFieldConfig
extends
FieldConfig
{
type
:
'
tree_select
'
treeData
?:
ManualOptionsConfig
|
InterfaceOptionsConfig
}
export
interface
ManualOptionsConfig
{
from
:
'
manual
'
defaultIndex
?:
string
|
number
data
?:
Array
<
{
value
:
string
|
number
title
:
string
[
extra
:
string
]:
any
}
>
}
export
interface
InterfaceOptionsConfig
{
from
:
'
interface
'
api
?:
APIConfig
defaultIndex
?:
string
|
number
request
?:
{
data
?:
{
[
key
:
string
]:
ParamConfig
}
}
response
:
{
root
?:
string
data
?:
InterfaceOptionsKVConfig
|
InterfaceOptionsListConfig
}
}
export
interface
InterfaceOptionsKVConfig
{
type
:
'
kv
'
}
export
interface
InterfaceOptionsListConfig
{
type
:
'
list
'
keyField
:
string
titleField
:
string
}
export
interface
ISelectFieldOption
{
value
:
string
|
number
,
title
:
ReactNode
,
children
?:
Array
<
ISelectFieldOption
>
}
interface
SelectSingleFieldState
{
interfaceOptionsData
:
Array
<
{
value
:
string
|
number
title
:
string
[
extra
:
string
]:
any
}
>
}
export
interface
ITreeSelectField
{
value
?:
string
,
treeData
:
Array
<
ISelectFieldOption
>
onChange
:
(
value
:
string
)
=>
Promise
<
void
>
}
export
default
class
TreeSelectField
extends
Field
<
TreeSelectFieldConfig
,
ITreeSelectField
,
string
>
implements
IField
<
string
>
{
interfaceOptionsConfig
:
string
=
''
state
:
SelectSingleFieldState
=
{
interfaceOptionsData
:
[]
}
formatTree
=
(
treeList
:
any
,
value
:
string
,
title
:
string
)
=>
{
let
rsMenu
:
any
=
[]
treeList
.
forEach
((
val
:
any
)
=>
{
let
theMenu
:
any
=
{
title
:
''
,
value
:
null
}
theMenu
.
title
=
getValue
(
val
,
title
)
theMenu
.
value
=
getValue
(
val
,
value
)
val
.
children
&&
(
theMenu
.
children
=
this
.
formatTree
(
val
.
children
,
value
,
title
))
val
.
isHidden
&&
(
theMenu
.
isLeaf
=
val
.
isHidden
)
rsMenu
.
push
(
theMenu
)
})
return
rsMenu
}
options
=
(
config
:
ManualOptionsConfig
|
InterfaceOptionsConfig
|
undefined
,
datas
:
{
record
?:
object
data
:
object
[]
step
:
number
}
)
=>
{
if
(
config
)
{
if
(
config
.
from
===
'
manual
'
)
{
if
(
config
.
data
)
{
return
this
.
formatTree
(
config
.
data
,
"
value
"
,
"
title
"
)
}
}
else
if
(
config
.
from
===
'
interface
'
)
{
if
(
config
.
api
)
{
const
interfaceOptionsParams
:
{
[
key
:
string
]:
any
}
=
{}
if
(
config
.
request
&&
config
.
request
.
data
)
{
for
(
const
field
in
config
.
request
.
data
)
{
const
param
=
config
.
request
.
data
[
field
]
setValue
(
interfaceOptionsParams
,
field
,
getParam
(
param
,
datas
))
}
}
const
interfaceOptionsConfig
:
string
=
JSON
.
stringify
({
api
:
config
.
api
,
params
:
interfaceOptionsParams
})
if
(
interfaceOptionsConfig
!==
this
.
interfaceOptionsConfig
)
{
this
.
interfaceOptionsConfig
=
interfaceOptionsConfig
request
(
config
.
api
,
interfaceOptionsParams
).
then
((
_response
)
=>
{
if
(
config
.
response
)
{
const
response
=
getValue
(
_response
,
config
.
response
.
root
||
''
)
if
(
config
.
response
.
data
)
{
if
(
config
.
response
.
data
.
type
===
'
kv
'
)
{
this
.
setState
({
interfaceOptionsData
:
Object
.
keys
(
response
).
map
((
key
)
=>
({
value
:
key
,
title
:
response
[
key
]
}))
})
}
else
if
(
config
.
response
.
data
.
type
===
'
list
'
)
{
this
.
setState
({
interfaceOptionsData
:
response
.
map
((
item
:
any
)
=>
{
if
(
config
.
response
.
data
?.
type
===
'
list
'
)
{
const
value
=
config
.
response
.
data
.
keyField
const
title
=
config
.
response
.
data
.
titleField
return
this
.
formatTree
(
item
,
value
,
title
)
}
else
{
return
{}
}
})
})
}
}
}
})
}
return
this
.
state
.
interfaceOptionsData
.
map
((
option
)
=>
{
return
{
value
:
option
.
value
,
title
:
option
.
label
}
})
}
}
}
return
[]
}
reset
=
async
()
=>
{
const
defaults
=
await
this
.
defaultValue
()
if
(
defaults
===
undefined
)
{
const
{
config
:
{
treeData
}
}
=
this
.
props
if
(
treeData
&&
treeData
.
from
===
'
interface
'
&&
treeData
.
api
)
{
let
interfaceOptionsData
:
any
=
[]
const
res
:
any
=
await
request
(
treeData
.
api
,
{}).
then
((
_response
:
any
)
=>
{
if
(
treeData
.
response
)
{
const
response
=
getValue
(
_response
,
treeData
.
response
.
root
||
''
)
if
(
treeData
.
response
.
data
)
{
if
(
treeData
.
response
.
data
.
type
===
'
kv
'
)
{
interfaceOptionsData
=
Object
.
keys
(
response
).
map
((
key
)
=>
({
value
:
key
,
label
:
response
[
key
]
}))
}
else
if
(
treeData
.
response
.
data
.
type
===
'
list
'
)
{
interfaceOptionsData
=
response
.
map
((
item
:
any
)
=>
{
if
(
treeData
.
response
.
data
?.
type
===
'
list
'
)
{
return
({
value
:
getValue
(
item
,
treeData
.
response
.
data
.
keyField
),
label
:
getValue
(
item
,
treeData
.
response
.
data
.
titleField
)
})
}
})
}
}
}
})
return
treeData
.
defaultIndex
===
undefined
?
undefined
:
interfaceOptionsData
[
treeData
.
defaultIndex
||
0
].
value
}
return
undefined
}
else
{
if
(
typeof
defaults
===
'
string
'
||
typeof
defaults
===
'
number
'
)
{
return
defaults
}
else
{
console
.
warn
(
'
单项选择框的值需要是字符串或数值。
'
)
return
undefined
}
}
}
validate
=
async
(
_value
:
string
|
number
|
undefined
):
Promise
<
true
|
FieldError
[]
>
=>
{
const
{
config
:
{
required
}
}
=
this
.
props
const
errors
:
FieldError
[]
=
[]
if
(
required
)
{
if
(
_value
===
''
||
_value
===
undefined
)
{
errors
.
push
(
new
FieldError
(
'
不能为空
'
))
}
}
return
errors
.
length
?
errors
:
true
}
renderComponent
=
(
props
:
ITreeSelectField
)
=>
{
return
<
React
.
Fragment
>
您当前使用的UI版本没有实现TreeSelectSingleField组件的SelectSingle模式。
<
div
style
=
{
{
display
:
'
none
'
}
}
>
<
button
onClick
=
{
()
=>
props
.
onChange
(
""
)
}
>
onChange
</
button
>
</
div
>
</
React
.
Fragment
>
}
render
=
()
=>
{
const
{
value
,
config
:
{
treeData
:
optionsConfig
},
onChange
,
record
,
data
,
step
}
=
this
.
props
const
treeData
=
this
.
options
(
optionsConfig
,
{
record
,
data
,
step
});
return
(
<
React
.
Fragment
>
{
this
.
renderComponent
({
value
,
treeData
,
onChange
:
async
(
value
:
string
)
=>
await
onChange
(
value
)
})
}
</
React
.
Fragment
>
)
}
}
This diff is collapsed.
Click to expand it.
src/index.tsx
+
1
-
0
View file @
c2581279
...
...
@@ -12,6 +12,7 @@ export { default as DatetimeRangeField } from './components/formFields/datetimeR
export
{
default
as
SelectSingleField
}
from
'
./components/formFields/select/single
'
export
{
default
as
SelectMultipleField
}
from
'
./components/formFields/select/multiple
'
export
{
default
as
DescField
}
from
'
./components/formFields/description
'
export
{
default
as
TreeSelectField
}
from
'
./components/formFields/treeSelect
'
export
{
default
as
TableStep
}
from
'
./steps/table
'
export
{
default
as
TextColumn
}
from
'
./components/tableColumns/text
'
...
...
This diff is collapsed.
Click to expand it.
src/util/request.ts
+
1
-
1
View file @
c2581279
...
...
@@ -64,7 +64,7 @@ export interface IAPIConditionFailModal {
/* istanbul ignore file */
export
const
requestCondition
:
(
config
:
APIConditionConfig
,
data
:
any
,
renderSuccessModal
:
(
props
:
IAPIConditionSuccessModal
)
=>
React
.
ReactNode
|
void
,
renderFailModal
:
(
props
:
IAPIConditionFailModal
)
=>
React
.
ReactNode
|
void
)
=>
Promise
<
boolean
>
=
(
config
,
data
,
renderSuccessModal
,
renderFailModal
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
getValue
(
data
,
config
.
field
)
==
=
config
.
value
)
{
if
(
getValue
(
data
,
config
.
field
)
==
config
.
value
)
{
if
(
config
.
success
.
type
===
'
none
'
)
{
resolve
(
true
)
}
else
if
(
config
.
success
.
type
===
'
modal
'
)
{
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
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