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 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) }</>)
}
......
......@@ -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],
...jsonData,
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
......
......@@ -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}
......
......@@ -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>
......
......@@ -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) {
......
......@@ -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>
......
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>
)
......
......@@ -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: 250px !important;
min-height: 330px !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
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