Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xform
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
田翔
xform
Commits
ecfe39da
Commit
ecfe39da
authored
Jan 03, 2025
by
彭俊龙
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
关联表单编辑数据联动
parent
26671d8e
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
334 additions
and
27 deletions
+334
-27
index.js
...ccount/components/TablePack/components/ValueEdit/index.js
+174
-13
index.js
src/core/Account/components/TablePack/index.js
+8
-3
index.js
src/core/components/Drag/index.js
+1
-1
index.js
src/core/widgets/advanced/RelationForm/index.js
+44
-0
index.js
src/core/widgets/business/AccountSelector/index.js
+34
-1
index.js
src/core/widgets/settings/groupSource/OtherSource/index.js
+6
-5
index.js
src/core/widgets/settings/groupSource/SqlFilter/index.js
+46
-2
index.less
src/core/widgets/settings/groupSource/SqlFilter/index.less
+21
-2
No files found.
src/core/Account/components/TablePack/components/ValueEdit/index.js
View file @
ecfe39da
import
React
,
{
useEffect
,
useCallback
}
from
'react'
import
React
,
{
useEffect
,
useCallback
,
useMemo
,
useState
}
from
'react'
import
{
Input
,
InputNumber
,
DatePicker
,
Select
}
from
'antd'
import
locale
from
'antd/lib/date-picker/locale/zh_CN'
import
moment
from
'moment'
import
{
debounce
}
from
'../../../../../../utils'
import
{
formAutomaticComputation
}
from
'../../../../../../apis/process'
import
UserSelect
from
'../../../../../widgets/business/PersonSelector/components/UserSelect'
import
AccountSelectorCell
from
'./AccountSelectorCell'
import
{
getUserSelector
,
GetFieldValueByTableName
}
from
'../../../../../../apis/process'
import
eventEmitter
from
'../../../../../../utils/eventEmitter'
const
initUserInfo
=
{
fullName
:
'【本人姓名】'
,
Phone
:
'【本人电话】'
,
...
...
@@ -27,7 +29,7 @@ const formAutomatic = async (parmas, callback) => {
const
formAuto
=
debounce
(
formAutomatic
)
const
ValueEdit
=
(
props
)
=>
{
const
[
pullDown
,
setPullDown
]
=
useState
([])
const
preview
=
sessionStorage
.
getItem
(
'FormRender'
)
const
userInfo
=
preview
===
'preview'
?
initUserInfo
:
window
?.
globalConfig
?.
userInfo
||
initUserInfo
const
{
...
...
@@ -35,6 +37,7 @@ const ValueEdit = (props) => {
value
,
fieldName
,
record
,
fieldTableKey
,
autoArray
,
otherChange
,
presetValue
,
...
...
@@ -49,9 +52,15 @@ const ValueEdit = (props) => {
max
,
formatter
,
isStoreID
,
displayName
,
tableName
,
whereField
,
whereType
,
_fieldName
}
=
props
const
property
=
isStoreID
?
'userID'
:
'userName'
useEffect
(()
=>
{
console
.
log
(
'ValueEdit'
,
props
)
if
(
widget
===
'TextInput'
)
{
let
value
=
presetValue
if
(
loaclPaths
.
includes
(
value
))
{
...
...
@@ -70,17 +79,133 @@ const ValueEdit = (props) => {
}
onChange
({
fieldName
,
fieldValue
:
value
})
}
}
else
if
(
widget
===
'PersonSelector'
){
getUsers
()
}
else
if
(
widget
===
'RelevanceSelect'
){
getTableData
();
if
(
fieldTableKey
){
eventEmitter
.
on
(
`
${
record
.
ID
}
_event`
,
(
val
)
=>
dealParentData
(
val
))
}
else
if
(
presetValue
){
eventEmitter
.
emit
(
`
${
record
.
ID
}
_event`
,
presetValue
)
}
}
return
()
=>
{
if
(
fieldTableKey
){
eventEmitter
.
removeAllListeners
(
`
${
record
.
ID
}
_event`
);
}
}
},
[])
const
dealParentData
=
async
(
val
)
=>
{
if
(
!
whereField
)
{
console
.
log
(
'请选择联动字段!'
)
return
}
if
(
!
whereType
)
{
console
.
log
(
'请选择联动条件!'
)
return
}
const
{
code
,
data
,
msg
}
=
await
GetFieldValueByTableName
({
params
:
{
tableName
:
tableName
,
fieldName
:
`
${
displayName
}
,
${
_fieldName
}
`
,
},
data
:
[{
field
:
whereField
,
type
:
whereType
,
value
:
val
}]
})
if
(
code
===
0
)
{
if
(
Array
.
isArray
(
data
))
{
setPullDown
(
data
.
map
(
v
=>
{
return
{
label
:
v
.
find
(
x
=>
x
.
fieldName
===
displayName
)?.
fieldValue
,
value
:
v
.
find
(
x
=>
x
.
fieldName
===
_fieldName
)?.
fieldValue
,
}
}))
}
else
{
setPullDown
([])
}
}
else
{
message
.
error
(
msg
)
}
}
const
getTableData
=
async
()
=>
{
if
(
!
tableName
)
{
console
.
log
(
'请选择表名!'
)
return
}
if
(
!
_fieldName
)
{
console
.
log
(
'请选择存储字段名!'
)
return
}
if
(
!
displayName
)
{
console
.
log
(
'请选择展示字段名!'
)
return
}
const
{
code
,
data
,
msg
}
=
await
GetFieldValueByTableName
({
params
:
{
tableName
:
tableName
,
fieldName
:
`
${
displayName
}
,
${
_fieldName
}
`
,
},
data
:
[]
})
if
(
code
===
0
)
{
if
(
Array
.
isArray
(
data
))
{
setPullDown
(
data
.
map
(
v
=>
{
return
{
label
:
v
.
find
(
x
=>
x
.
fieldName
===
displayName
)?.
fieldValue
,
value
:
v
.
find
(
x
=>
x
.
fieldName
===
_fieldName
)?.
fieldValue
,
}
}))
}
else
{
setPullDown
([])
}
}
else
{
message
.
error
(
msg
)
}
}
const
getUsers
=
async
()
=>
{
let
time
=
new
Date
().
getTime
()
+
Math
.
random
()
const
{
code
,
data
,
msg
}
=
await
getUserSelector
(
''
,
false
,
time
)
if
(
code
===
0
)
{
if
(
data
)
{
setPullDown
(
data
.
dropdownList
.
map
((
v
,
i
)
=>
{
let
length
=
v
.
groupName
?.
length
return
{
label
:
(
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'space-between'
}}
>
<
span
>
{
v
.
userName
}
<
/span
>
<
span
style
=
{{
fontSize
:
'12px'
,
color
:
'#b4b1b1'
,
}}
>
{
length
>
20
?
`...
${
v
.
groupName
.
slice
(
length
-
20
,
length
)}
`
:
v
.
groupName
}
<
/span
>
<
/div
>
),
userName
:
v
.
userName
,
value
:
v
[
property
],
groupName
:
v
.
groupName
}
}))
}
else
{
setPullDown
([])
}
}
else
{
message
.
info
(
msg
)
}
}
if
(
widget
===
'AccountSelector'
)
{
return
<
AccountSelectorCell
{...
props
}
/
>
}
if
([
'CheckBox'
,
'ComboBox'
,
'RadioButton'
].
includes
(
widget
)
&&
sourceType
===
'手动输入'
)
{
const
renderWidget
=
(
w
)
=>
{
if
([
'CheckBox'
,
'ComboBox'
,
'RadioButton'
].
includes
(
w
)
&&
sourceType
===
'手动输入'
)
{
return
(
<
Select
value
=
{
value
}
disabled
=
{
disabled
}
style
=
{{
width
:
'100%'
}}
mode
=
{
isMultiple
?
'multiple'
:
''
}
onChange
=
{(
value
)
=>
onChange
({
fieldName
,
fieldValue
:
value
})}
...
...
@@ -89,9 +214,10 @@ const ValueEdit = (props) => {
allowClear
/>
)
}
else
if
(
w
===
'DateTime'
)
{
if
(
options
===
'默认为当前时间'
&&
!
value
){
onChange
({
fieldName
,
fieldValue
:
moment
().
format
(
'YYYY-MM-DD HH:mm:ss'
)
})
}
if
(
widget
===
'DateTime'
)
{
const
isValid
=
value
?
moment
(
value
).
_isValid
:
false
const
timeOtions
=
format
===
'dateTime'
?
{
...
...
@@ -110,7 +236,7 @@ const ValueEdit = (props) => {
<
DatePicker
disabled
=
{
disabled
}
placeholder
=
{
disabled
?
(
placeholder
||
''
)
:
(
placeholder
||
'点击选择日期'
)}
value
=
{
isValid
?
moment
(
value
)
:
null
}
value
=
{
isValid
?
moment
(
value
)
:
options
===
'默认为当前时间'
?
moment
(
)
:
null
}
showNow
{...
timeOtions
}
style
=
{{
width
:
'100%'
}}
...
...
@@ -124,9 +250,7 @@ const ValueEdit = (props) => {
}}
/
>
)
}
if
(
widget
===
'NumberInput'
)
{
}
else
if
(
w
===
'NumberInput'
)
{
return
(
<
InputNumber
min
=
{
min
||
Number
.
MIN_SAFE_INTEGER
}
...
...
@@ -154,8 +278,39 @@ const ValueEdit = (props) => {
style
=
{{
width
:
'100%'
}}
/
>
)
}
else
if
(
w
===
'PersonSelector'
){
return
(
<
Select
value
=
{
value
}
style
=
{{
width
:
'100%'
}}
disabled
=
{
disabled
}
showSearch
mode
=
{
isMultiple
?
'multiple'
:
''
}
onChange
=
{(
value
)
=>
onChange
({
fieldName
,
fieldValue
:
value
})}
placeholder
=
{
`请输入
${
fieldName
}
`
}
options
=
{
pullDown
}
filterOption
=
{(
input
,
option
)
=>
(
option
?.
userName
||
''
).
toLowerCase
().
includes
(
input
.
toLowerCase
())}
allowClear
/>
)
}
else
if
(
w
===
'RelevanceSelect'
){
return
(
<
Select
value
=
{
value
}
style
=
{{
width
:
'100%'
}}
disabled
=
{
disabled
}
onChange
=
{(
value
)
=>
{
onChange
({
fieldName
,
fieldValue
:
value
})
if
(
!
fieldTableKey
){
eventEmitter
.
emit
(
`
${
record
.
ID
}
_event`
,
value
)
}
}}
placeholder
=
{
`请输入
${
_fieldName
}
`
}
options
=
{
pullDown
}
allowClear
/>
)
}
else
{
return
(
<
Input
disabled
=
{
disabled
}
...
...
@@ -164,6 +319,12 @@ const ValueEdit = (props) => {
value
=
{
value
}
/
>
)
}
}
return
(
<>
{
renderWidget
(
widget
)
}
<
/>
)
}
...
...
src/core/Account/components/TablePack/index.js
View file @
ecfe39da
...
...
@@ -171,7 +171,7 @@ const TablePack = (props, ref) => {
//关联表单表头
const
getRelevanceColumnProps
=
({
json
,
field
,
isEdit
,
autoArray
,
accountFieids
})
=>
{
const
{
fieldName
,
columnWidth
,
isSort
,
accurateSearch
,
alignment
}
=
field
const
{
widget
}
=
json
?.[
fieldName
]
||
{}
const
{
widget
,
disabled
}
=
json
?.[
fieldName
]
||
{}
let
searchProps
=
{}
if
(
accurateSearch
)
{
searchProps
=
{
...
...
@@ -254,14 +254,19 @@ const TablePack = (props, ref) => {
},
}),
render
:
(
value
,
record
)
=>
{
let
jsonData
=
json
[
fieldName
]
if
(
jsonData
.
hasOwnProperty
(
'fieldName'
)){
jsonData
[
'_fieldName'
]
=
jsonData
[
'fieldName'
]
}
let
props
=
{
...
json
[
fieldName
]
,
...
json
Data
,
fieldName
,
value
,
autoArray
,
disabled
:
!
accountFieids
?.
some
(
v
=>
v
.
fieldName
===
fieldName
&&
v
.
isEdit
),
disabled
:
disabled
||
false
,
// || !accountFieids?.some(v => v.fieldName === fieldName && v.isEdit), 从台账设置中获取只读属性
record
:
{
...
record
},
}
if
(
isEdit
&&
!
notUse
?.
includes
(
'edit'
))
{
return
(
<
ValueEdit
...
...
src/core/components/Drag/index.js
View file @
ecfe39da
...
...
@@ -41,8 +41,8 @@ const Drag = (props) => {
getContainer
=
{
false
}
cancelText
=
'取消'
okText
=
'确定'
{...
props
}
style
=
{
style
}
{...
props
}
title
=
{
<
div
style
=
{{
width
:
'100%'
,
cursor
:
'move'
}}
onMouseDown
=
{
onMouseDown
}
>
{
props
.
title
}
...
...
src/core/widgets/advanced/RelationForm/index.js
View file @
ecfe39da
...
...
@@ -40,6 +40,8 @@ const RelationForm = (props) => {
sql
,
fieldList
,
}
=
schema
const
initParams
=
{
user
:
userID
,
accountName
:
otherSource
?.
accountName
,
...
...
@@ -73,6 +75,8 @@ const RelationForm = (props) => {
return
formDataObj
},
[
addons
?.
formData
])
const
localForm
=
useMemo
(()
=>
{
const
{
addFieldGroup
}
=
config
let
array
=
[]
...
...
@@ -443,6 +447,46 @@ const RelationForm = (props) => {
}
},
[])
useEffect
(()
=>
{
if
(
otherSource
?.
sql
&&
addons
)
{
const
sql
=
dealSql
(
otherSource
.
sql
)
setParamsOther
({
...
paramsOther
,
condition
:
window
.
btoa
(
encodeURIComponent
(
sql
))
})
console
.
log
(
paramsOther
,
sql
,
'paramsOther'
);
}
},
[
otherSource
])
const
dealSql
=
(
sql
)
=>
{
let
_sql
=
sql
;
if
(
!
addons
){
return
_sql
;
}
// 使用正则表达式匹配括号内的内容
const
regex
=
/{
([^
}
]
+
)
}/g
;
const
matches
=
[];
let
match
;
while
((
match
=
regex
.
exec
(
_sql
))
!==
null
)
{
matches
.
push
({
text
:
`{
${
match
[
1
]}
}`
,
value
:
match
[
1
]
});
}
if
(
matches
.
length
>
0
)
{
const
formData
=
addons
?.
formData
;
Object
.
keys
(
formData
).
forEach
((
k
)
=>
{
if
(
isObject
(
formData
[
k
]))
{
Object
.
keys
(
formData
[
k
]).
forEach
((
key
)
=>
{
const
d
=
matches
.
find
((
m
)
=>
m
.
value
===
key
);
if
(
d
){
_sql
=
_sql
.
replace
(
d
.
text
,
`'
${
formData
[
k
][
key
]}
'`
||
`''`
);
}
});
}
})
}
return
_sql
;
}
return
(
<
div
className
=
{
styles
.
relationForm
}
>
<
div
>
...
...
src/core/widgets/business/AccountSelector/index.js
View file @
ecfe39da
...
...
@@ -76,6 +76,39 @@ const AccountSelector = (props) => {
}
}
const
dealSql
=
(
sql
)
=>
{
let
_sql
=
sql
;
if
(
!
addons
){
return
_sql
;
}
// 使用正则表达式匹配括号内的内容
const
regex
=
/{
([^
}
]
+
)
}/g
;
const
matches
=
[];
let
match
;
while
((
match
=
regex
.
exec
(
_sql
))
!==
null
)
{
matches
.
push
({
text
:
`{
${
match
[
1
]}
}`
,
value
:
match
[
1
]
});
}
if
(
matches
.
length
>
0
)
{
const
formData
=
addons
?.
formData
;
Object
.
keys
(
formData
).
forEach
((
k
)
=>
{
if
(
isObject
(
formData
[
k
]))
{
Object
.
keys
(
formData
[
k
]).
forEach
((
key
)
=>
{
const
d
=
matches
.
find
((
m
)
=>
m
.
value
===
key
);
if
(
d
){
_sql
=
_sql
.
replace
(
d
.
text
,
`'
${
formData
[
k
][
key
]}
'`
||
`''`
);
}
});
}
})
}
return
_sql
;
}
const
getConfig
=
async
()
=>
{
const
{
code
,
data
}
=
await
GetAccountConfigInfo
(
accountName
);
if
(
code
==
0
)
{
...
...
@@ -100,7 +133,7 @@ const AccountSelector = (props) => {
user
:
userID
,
accountName
:
accountName
,
...
outParams
,
condition
:
sql
?
window
.
btoa
(
encodeURIComponent
(
sql
))
:
(
outParams
.
condition
||
params
.
condition
||
''
),
condition
:
sql
?
window
.
btoa
(
encodeURIComponent
(
dealSql
(
sql
)
))
:
(
outParams
.
condition
||
params
.
condition
||
''
),
};
const
{
data
,
code
,
msg
}
=
await
GetAccountPageList
(
param
);
if
(
code
===
0
)
{
...
...
src/core/widgets/settings/groupSource/OtherSource/index.js
View file @
ecfe39da
...
...
@@ -4,19 +4,19 @@ import styles from './index.less'
import
{
MinusCircleOutlined
,
PlusOutlined
}
from
'@ant-design/icons'
import
Drag
from
'../../../../components/Drag'
import
{
LoadLedgers
,
QueryFields
,
ReloadTableFields
}
from
'../../../../../apis/process'
import
SqlFilter
from
'../SqlFilter'
const
{
TreeNode
}
=
TreeSelect
const
OtherSource
=
(
props
)
=>
{
const
{
addons
,
onChange
,
value
}
=
props
const
{
'台账名称'
:
accountName
}
=
addons
?.
formData
||
{}
const
{
'台账名称'
:
accountName
,
tableNameParent
}
=
addons
?.
formData
||
{}
const
[
visible
,
setVisible
]
=
useState
(
false
)
const
[
options
,
setOptions
]
=
useState
([])
const
[
fromField
,
setFromField
]
=
useState
([])
const
[
toField
,
setToField
]
=
useState
([])
const
[
form
]
=
Form
.
useForm
()
console
.
log
(
addons
.
formData
,
'addons.formData'
);
const
toFieldFocus
=
async
()
=>
{
const
{
code
,
data
}
=
await
QueryFields
(
accountName
)
if
(
code
===
0
)
{
...
...
@@ -93,11 +93,12 @@ const OtherSource = (props) => {
label
=
{
'SQL过滤'
}
name
=
{
'sql'
}
>
<
Input
.
TextArea
{
/*
<Input.TextArea
style={{ width: '100%' }}
rows={3}
placeholder='示例:部门="XX部门"'
/>
/> */
}
<
SqlFilter
addons
=
{
addons
}
/
>
<
/Form.Item
>
<
Space
align
=
"baseline"
>
<
div
style
=
{{
width
:
'60px'
}}
>
字段映射
:
<
/div
>
...
...
src/core/widgets/settings/groupSource/SqlFilter/index.js
View file @
ecfe39da
import
React
,
{
useState
}
from
'react'
import
React
,
{
useState
,
useEffect
}
from
'react'
import
{
Input
,
Modal
,
Dropdown
,
Menu
}
from
'antd'
import
styles
from
'./index.less'
import
Drag
from
'../../../../components/Drag'
import
{
LoadTableFields
,
ReloadTableFields
}
from
'../../../../../apis/process'
;
const
fnList
=
[
{
label
:
'本人姓名'
,
value
:
'$本人姓名'
},
{
label
:
'本人ID'
,
value
:
'$本人ID'
},
...
...
@@ -14,9 +14,14 @@ const fnList = [
const
SqlFilter
=
(
props
)
=>
{
const
{
value
,
onChange
,
addons
}
=
props
const
{
tableNameParent
,
widget
,
$id
}
=
addons
.
formData
;
const
[
visible
,
setVisible
]
=
useState
(
false
)
const
[
inputValue
,
setInputValue
]
=
useState
(
''
)
const
[
fields
,
setFields
]
=
useState
([]);
useEffect
(()
=>
{
getFieldData
();
},
[]);
const
onFocus
=
()
=>
{
setInputValue
(
value
||
''
)
setVisible
(
true
)
...
...
@@ -30,6 +35,21 @@ const SqlFilter = (props) => {
ruleText
.
current
.
focus
()
}
const
getFieldData
=
async
()
=>
{
if
(
!
tableNameParent
)
{
return
message
.
info
(
'缺少表名!'
)
}
const
{
data
}
=
await
ReloadTableFields
({
tableName
:
tableNameParent
});
if
(
Array
.
isArray
(
data
.
root
))
{
const
fields
=
data
.
root
.
map
(
x
=>
{
return
{
value
:
`{
${
x
.
name
}
}`
,
label
:
x
.
name
}
});
setFields
(
fields
);
}
console
.
log
(
data
,
'data'
);
};
const
onOk
=
()
=>
{
onChange
(
inputValue
)
setVisible
(
false
)
...
...
@@ -59,7 +79,29 @@ const SqlFilter = (props) => {
onOk
=
{
onOk
}
title
=
{
'SQL过滤'
}
visible
=
{
visible
}
width
=
{
800
}
bodyStyle
=
{{
height
:
350
,
}}
>
<
div
style
=
{{
width
:
'100%'
,
height
:
'100%'
,
display
:
'flex'
,
}}
>
<
div
className
=
{
styles
.
fieldListBox
}
>
<
div
style
=
{{
fontSize
:
14
,
fontWeight
:
'bold'
,
marginBottom
:
5
,
paddingRight
:
10
}}
>
{
tableNameParent
}
<
/div
>
<
div
className
=
{
styles
.
fieldList
}
>
{
fields
.
map
((
item
,
index
)
=>
(
<
div
key
=
{
index
}
onClick
=
{()
=>
insertFn
(
item
.
value
)}
>
{
item
.
label
}
<
/div>
))
}
<
/div
>
<
/div
>
<
div
className
=
{
styles
.
textAreaBox
}
>
<
Input
.
TextArea
id
=
"SqlFilter"
...
...
@@ -72,6 +114,8 @@ const SqlFilter = (props) => {
<
div
className
=
{
styles
.
insertFn
}
>
自定义变量
<
/div
>
<
/Dropdown
>
<
/div
>
<
/div
>
<
/Drag
>
<
/div
>
)
...
...
src/core/widgets/settings/groupSource/SqlFilter/index.less
View file @
ecfe39da
...
...
@@ -2,21 +2,39 @@
width: 100%;
.textAreaBox {
position: relative;
flex: 1;
.insertFn {
position: absolute;
bottom: 10px;
right: 10px;
border: 1px solid #1890FF;
padding: 2px 15px;
border-radius: 5px;
z-index: 1;
cursor: pointer;
border: 1px solid #1890FF;
}
textArea {
max-height: 360px !important;
min-height:
25
0px !important;
min-height:
33
0px !important;
border: 1px solid transparent;
background-color: #F0F2F6;
}
}
.fieldListBox{
max-height: 370px;
.fieldList{
>div{
padding: 5px 10px;
white-space: nowrap;
cursor: pointer;
transition: background-color 0.3s ease;
&:hover {
background-color: #e0e0e0;
}
}
max-height: 300px;
overflow-y: auto;
}
}
}
\ No newline at end of file
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