Commit ecfe39da authored by 彭俊龙's avatar 彭俊龙

关联表单编辑数据联动

parent 26671d8e
import React, { useEffect, useCallback } from 'react' import React, { useEffect, useCallback, useMemo, useState } from 'react'
import { Input, InputNumber, DatePicker, Select } from 'antd' import { Input, InputNumber, DatePicker, Select } from 'antd'
import locale from 'antd/lib/date-picker/locale/zh_CN' import locale from 'antd/lib/date-picker/locale/zh_CN'
import moment from 'moment' import moment from 'moment'
import { debounce } from '../../../../../../utils' import { debounce } from '../../../../../../utils'
import { formAutomaticComputation } from '../../../../../../apis/process' import { formAutomaticComputation } from '../../../../../../apis/process'
import UserSelect from '../../../../../widgets/business/PersonSelector/components/UserSelect'
import AccountSelectorCell from './AccountSelectorCell' import AccountSelectorCell from './AccountSelectorCell'
import { getUserSelector, GetFieldValueByTableName } from '../../../../../../apis/process'
import eventEmitter from '../../../../../../utils/eventEmitter'
const initUserInfo = { const initUserInfo = {
fullName: '【本人姓名】', fullName: '【本人姓名】',
Phone: '【本人电话】', Phone: '【本人电话】',
...@@ -27,7 +29,7 @@ const formAutomatic = async (parmas, callback) => { ...@@ -27,7 +29,7 @@ const formAutomatic = async (parmas, callback) => {
const formAuto = debounce(formAutomatic) const formAuto = debounce(formAutomatic)
const ValueEdit = (props) => { const ValueEdit = (props) => {
const [pullDown, setPullDown] = useState([])
const preview = sessionStorage.getItem('FormRender') const preview = sessionStorage.getItem('FormRender')
const userInfo = preview === 'preview' ? initUserInfo : window?.globalConfig?.userInfo || initUserInfo const userInfo = preview === 'preview' ? initUserInfo : window?.globalConfig?.userInfo || initUserInfo
const { const {
...@@ -35,6 +37,7 @@ const ValueEdit = (props) => { ...@@ -35,6 +37,7 @@ const ValueEdit = (props) => {
value, value,
fieldName, fieldName,
record, record,
fieldTableKey,
autoArray, autoArray,
otherChange, otherChange,
presetValue, presetValue,
...@@ -49,9 +52,15 @@ const ValueEdit = (props) => { ...@@ -49,9 +52,15 @@ const ValueEdit = (props) => {
max, max,
formatter, formatter,
isStoreID, isStoreID,
displayName,
tableName,
whereField,
whereType,
_fieldName
} = props } = props
const property = isStoreID ? 'userID' : 'userName'
useEffect(() => { useEffect(() => {
console.log('ValueEdit', props)
if (widget === 'TextInput') { if (widget === 'TextInput') {
let value = presetValue let value = presetValue
if (loaclPaths.includes(value)) { if (loaclPaths.includes(value)) {
...@@ -70,17 +79,133 @@ const ValueEdit = (props) => { ...@@ -70,17 +79,133 @@ const ValueEdit = (props) => {
} }
onChange({ fieldName, fieldValue: value }) 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') { if (widget === 'AccountSelector') {
return <AccountSelectorCell {...props} /> return <AccountSelectorCell {...props} />
} }
const renderWidget = (w) => {
if (['CheckBox', 'ComboBox', 'RadioButton'].includes(widget) && sourceType === '手动输入') { if (['CheckBox', 'ComboBox', 'RadioButton'].includes(w) && sourceType === '手动输入') {
return ( return (
<Select <Select
value={value} value={value}
disabled={disabled}
style={{ width: '100%' }} style={{ width: '100%' }}
mode={isMultiple ? 'multiple' : ''} mode={isMultiple ? 'multiple' : ''}
onChange={(value) => onChange({ fieldName, fieldValue: value })} onChange={(value) => onChange({ fieldName, fieldValue: value })}
...@@ -89,9 +214,10 @@ const ValueEdit = (props) => { ...@@ -89,9 +214,10 @@ const ValueEdit = (props) => {
allowClear 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 isValid = value ? moment(value)._isValid : false
const timeOtions = format === 'dateTime' ? const timeOtions = format === 'dateTime' ?
{ {
...@@ -110,7 +236,7 @@ const ValueEdit = (props) => { ...@@ -110,7 +236,7 @@ const ValueEdit = (props) => {
<DatePicker <DatePicker
disabled={disabled} disabled={disabled}
placeholder={disabled ? (placeholder || '') : (placeholder || '点击选择日期')} placeholder={disabled ? (placeholder || '') : (placeholder || '点击选择日期')}
value={isValid ? moment(value) : null} value={isValid ? moment(value) : options === '默认为当前时间' ? moment() : null}
showNow showNow
{...timeOtions} {...timeOtions}
style={{ width: '100%' }} style={{ width: '100%' }}
...@@ -124,9 +250,7 @@ const ValueEdit = (props) => { ...@@ -124,9 +250,7 @@ const ValueEdit = (props) => {
}} }}
/> />
) )
} }else if (w === 'NumberInput') {
if (widget === 'NumberInput') {
return ( return (
<InputNumber <InputNumber
min={min || Number.MIN_SAFE_INTEGER} min={min || Number.MIN_SAFE_INTEGER}
...@@ -154,8 +278,39 @@ const ValueEdit = (props) => { ...@@ -154,8 +278,39 @@ const ValueEdit = (props) => {
style={{ width: '100%' }} 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 ( return (
<Input <Input
disabled={disabled} disabled={disabled}
...@@ -164,6 +319,12 @@ const ValueEdit = (props) => { ...@@ -164,6 +319,12 @@ const ValueEdit = (props) => {
value={value} value={value}
/> />
) )
}
}
return (<>{ renderWidget(widget) }</>)
} }
......
...@@ -171,7 +171,7 @@ const TablePack = (props, ref) => { ...@@ -171,7 +171,7 @@ const TablePack = (props, ref) => {
//关联表单表头 //关联表单表头
const getRelevanceColumnProps = ({ json, field, isEdit, autoArray, accountFieids }) => { const getRelevanceColumnProps = ({ json, field, isEdit, autoArray, accountFieids }) => {
const { fieldName, columnWidth, isSort, accurateSearch, alignment } = field const { fieldName, columnWidth, isSort, accurateSearch, alignment } = field
const { widget } = json?.[fieldName] || {} const { widget, disabled } = json?.[fieldName] || {}
let searchProps = {} let searchProps = {}
if (accurateSearch) { if (accurateSearch) {
searchProps = { searchProps = {
...@@ -254,14 +254,19 @@ const TablePack = (props, ref) => { ...@@ -254,14 +254,19 @@ const TablePack = (props, ref) => {
}, },
}), }),
render: (value, record) => { render: (value, record) => {
let jsonData = json[fieldName]
if(jsonData.hasOwnProperty('fieldName')){
jsonData['_fieldName'] = jsonData['fieldName']
}
let props = { let props = {
...json[fieldName], ...jsonData,
fieldName, fieldName,
value, value,
autoArray, autoArray,
disabled: !accountFieids?.some(v => v.fieldName === fieldName && v.isEdit), disabled: disabled || false, // || !accountFieids?.some(v => v.fieldName === fieldName && v.isEdit), 从台账设置中获取只读属性
record: { ...record }, record: { ...record },
} }
if (isEdit && !notUse?.includes('edit')) { if (isEdit && !notUse?.includes('edit')) {
return ( return (
<ValueEdit <ValueEdit
......
...@@ -41,8 +41,8 @@ const Drag = (props) => { ...@@ -41,8 +41,8 @@ const Drag = (props) => {
getContainer={false} getContainer={false}
cancelText='取消' cancelText='取消'
okText='确定' okText='确定'
{...props}
style={style} style={style}
{...props}
title={ title={
<div style={{ width: '100%', cursor: 'move' }} onMouseDown={onMouseDown}> <div style={{ width: '100%', cursor: 'move' }} onMouseDown={onMouseDown}>
{props.title} {props.title}
......
...@@ -40,6 +40,8 @@ const RelationForm = (props) => { ...@@ -40,6 +40,8 @@ const RelationForm = (props) => {
sql, sql,
fieldList, fieldList,
} = schema } = schema
const initParams = { const initParams = {
user: userID, user: userID,
accountName: otherSource?.accountName, accountName: otherSource?.accountName,
...@@ -73,6 +75,8 @@ const RelationForm = (props) => { ...@@ -73,6 +75,8 @@ const RelationForm = (props) => {
return formDataObj return formDataObj
}, [addons?.formData]) }, [addons?.formData])
const localForm = useMemo(() => { const localForm = useMemo(() => {
const { addFieldGroup } = config const { addFieldGroup } = config
let array = [] let array = []
...@@ -443,6 +447,46 @@ const RelationForm = (props) => { ...@@ -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 ( return (
<div className={styles.relationForm}> <div className={styles.relationForm}>
<div> <div>
......
...@@ -76,6 +76,39 @@ const AccountSelector = (props) => { ...@@ -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 getConfig = async () => {
const { code, data } = await GetAccountConfigInfo(accountName); const { code, data } = await GetAccountConfigInfo(accountName);
if (code == 0) { if (code == 0) {
...@@ -100,7 +133,7 @@ const AccountSelector = (props) => { ...@@ -100,7 +133,7 @@ const AccountSelector = (props) => {
user: userID, user: userID,
accountName: accountName, accountName: accountName,
...outParams, ...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); const { data, code, msg } = await GetAccountPageList(param);
if (code === 0) { if (code === 0) {
......
...@@ -4,19 +4,19 @@ import styles from './index.less' ...@@ -4,19 +4,19 @@ import styles from './index.less'
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons' import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
import Drag from '../../../../components/Drag' import Drag from '../../../../components/Drag'
import { LoadLedgers, QueryFields, ReloadTableFields } from '../../../../../apis/process' import { LoadLedgers, QueryFields, ReloadTableFields } from '../../../../../apis/process'
import SqlFilter from '../SqlFilter'
const { TreeNode } = TreeSelect const { TreeNode } = TreeSelect
const OtherSource = (props) => { const OtherSource = (props) => {
const { addons, onChange, value } = props const { addons, onChange, value } = props
const { '台账名称': accountName } = addons?.formData || {} const { '台账名称': accountName, tableNameParent } = addons?.formData || {}
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
const [options, setOptions] = useState([]) const [options, setOptions] = useState([])
const [fromField, setFromField] = useState([]) const [fromField, setFromField] = useState([])
const [toField, setToField] = useState([]) const [toField, setToField] = useState([])
const [form] = Form.useForm() const [form] = Form.useForm()
console.log(addons.formData, 'addons.formData');
const toFieldFocus = async () => { const toFieldFocus = async () => {
const { code, data } = await QueryFields(accountName) const { code, data } = await QueryFields(accountName)
if (code === 0) { if (code === 0) {
...@@ -93,11 +93,12 @@ const OtherSource = (props) => { ...@@ -93,11 +93,12 @@ const OtherSource = (props) => {
label={'SQL过滤'} label={'SQL过滤'}
name={'sql'} name={'sql'}
> >
<Input.TextArea {/* <Input.TextArea
style={{ width: '100%' }} style={{ width: '100%' }}
rows={3} rows={3}
placeholder='示例:部门="XX部门"' placeholder='示例:部门="XX部门"'
/> /> */}
<SqlFilter addons={addons}/>
</Form.Item> </Form.Item>
<Space align="baseline"> <Space align="baseline">
<div style={{ width: '60px' }}>字段映射:</div> <div style={{ width: '60px' }}>字段映射:</div>
......
import React, { useState } from 'react' import React, { useState, useEffect } from 'react'
import { Input, Modal, Dropdown, Menu } from 'antd' import { Input, Modal, Dropdown, Menu } from 'antd'
import styles from './index.less' import styles from './index.less'
import Drag from '../../../../components/Drag' import Drag from '../../../../components/Drag'
import { LoadTableFields, ReloadTableFields } from '../../../../../apis/process';
const fnList = [ const fnList = [
{ label: '本人姓名', value: '$本人姓名' }, { label: '本人姓名', value: '$本人姓名' },
{ label: '本人ID', value: '$本人ID' }, { label: '本人ID', value: '$本人ID' },
...@@ -14,9 +14,14 @@ const fnList = [ ...@@ -14,9 +14,14 @@ const fnList = [
const SqlFilter = (props) => { const SqlFilter = (props) => {
const { value, onChange, addons } = props const { value, onChange, addons } = props
const { tableNameParent, widget, $id } = addons.formData;
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
const [inputValue, setInputValue] = useState('') const [inputValue, setInputValue] = useState('')
const [fields, setFields] = useState([]);
useEffect(() => {
getFieldData();
}, []);
const onFocus = () => { const onFocus = () => {
setInputValue(value || '') setInputValue(value || '')
setVisible(true) setVisible(true)
...@@ -30,6 +35,21 @@ const SqlFilter = (props) => { ...@@ -30,6 +35,21 @@ const SqlFilter = (props) => {
ruleText.current.focus() 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 = () => { const onOk = () => {
onChange(inputValue) onChange(inputValue)
setVisible(false) setVisible(false)
...@@ -59,7 +79,29 @@ const SqlFilter = (props) => { ...@@ -59,7 +79,29 @@ const SqlFilter = (props) => {
onOk={onOk} onOk={onOk}
title={'SQL过滤'} title={'SQL过滤'}
visible={visible} 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}> <div className={styles.textAreaBox}>
<Input.TextArea <Input.TextArea
id="SqlFilter" id="SqlFilter"
...@@ -72,6 +114,8 @@ const SqlFilter = (props) => { ...@@ -72,6 +114,8 @@ const SqlFilter = (props) => {
<div className={styles.insertFn}>自定义变量</div> <div className={styles.insertFn}>自定义变量</div>
</Dropdown> </Dropdown>
</div> </div>
</div>
</Drag> </Drag>
</div> </div>
) )
......
...@@ -2,21 +2,39 @@ ...@@ -2,21 +2,39 @@
width: 100%; width: 100%;
.textAreaBox { .textAreaBox {
position: relative; position: relative;
flex: 1;
.insertFn { .insertFn {
position: absolute; position: absolute;
bottom: 10px; bottom: 10px;
right: 10px; right: 10px;
border: 1px solid #1890FF;
padding: 2px 15px; padding: 2px 15px;
border-radius: 5px; border-radius: 5px;
z-index: 1; z-index: 1;
cursor: pointer; cursor: pointer;
border: 1px solid #1890FF;
} }
textArea { textArea {
max-height: 360px !important; max-height: 360px !important;
min-height: 250px !important; min-height: 330px !important;
border: 1px solid transparent; border: 1px solid transparent;
background-color: #F0F2F6; 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment