Commit 967dd880 authored by 田翔's avatar 田翔

fix: 所有形态增加隐藏条件

parent d2bd1b78
{ {
"name": "panda-xform", "name": "panda-xform",
"version": "2.5.9", "version": "2.6.0",
"description": "2.5.9: 细节修改", "description": "2.6.0: 所有形态增加隐藏条件",
"keywords": [ "keywords": [
"panda-xform" "panda-xform"
], ],
......
...@@ -22,6 +22,15 @@ export function getSelectName(nodeName) { ...@@ -22,6 +22,15 @@ export function getSelectName(nodeName) {
}); });
} }
//字段校验
export function getFormFieldHideDtos(data) {
return request({
url: `/PandaWorkFlow/WorkFlow/BPM/CaseManage/GetFormFieldHideDtos`,
method: 'post',
data
})
}
//关联表单显示隐藏控制规则 //关联表单显示隐藏控制规则
export function ruleValidation(ruleContent) { export function ruleValidation(ruleContent) {
return request({ return request({
...@@ -79,6 +88,15 @@ export function formAutomaticComputation(data) { ...@@ -79,6 +88,15 @@ export function formAutomaticComputation(data) {
}) })
} }
//表单字段隐藏计算
export function formFieldHideComputation(data) {
return request({
url: `/PandaWorkFlow/WorkFlow/BPM/CaseManage/FormFieldHideComputation`,
method: 'post',
data
})
}
export function getGroupAndRole() { export function getGroupAndRole() {
return request({ return request({
url: `PandaOMS/OMS/CaseManage/GetGroupAndRole`, url: `PandaOMS/OMS/CaseManage/GetGroupAndRole`,
......
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*/ */
import React, { useMemo, useContext, forwardRef, useImperativeHandle, createContext, useState } from 'react' import React, { useMemo, useContext, forwardRef, useImperativeHandle, createContext, useState } from 'react'
import FormRender, { useForm } from 'form-render' import FormRender, { useForm } from 'form-render'
import { ConfigProvider } from 'antd' import { ConfigProvider, Spin } from 'antd'
import widgets from '../widgets' import widgets from '../widgets'
import { isObject } from '../../utils' import { isObject } from '../../utils'
import { getWatch } from './watch' import { getWatch } from './watch'
...@@ -28,6 +28,7 @@ const XRender = (props, ref) => { ...@@ -28,6 +28,7 @@ const XRender = (props, ref) => {
const prefixCls = getPrefixCls('pandaXform') const prefixCls = getPrefixCls('pandaXform')
const pandaXform = getPrefixCls() const pandaXform = getPrefixCls()
const [startTime, setStartTime] = useState(new Date().getTime()) const [startTime, setStartTime] = useState(new Date().getTime())
const [loading, setLoading] = useState(true)
const form = useForm() const form = useForm()
const schemaForm = useMemo(() => { const schemaForm = useMemo(() => {
...@@ -89,11 +90,15 @@ const XRender = (props, ref) => { ...@@ -89,11 +90,15 @@ const XRender = (props, ref) => {
//初始化时存储外部传的额外数据 //初始化时存储外部传的额外数据
const onMount = () => { const onMount = () => {
setTimeout(() => {
setLoading(false)
}, 500)
// form.setValueByPath('extraData', extraData || { codes: { '事件编号': '12312' } }) // form.setValueByPath('extraData', extraData || { codes: { '事件编号': '12312' } })
} }
return ( return (
<div className={prefixCls}> <div className={prefixCls}>
<Spin spinning={loading}>
<FormRender <FormRender
configProvider={{ prefixCls: pandaXform }} configProvider={{ prefixCls: pandaXform }}
form={form} form={form}
...@@ -107,6 +112,7 @@ const XRender = (props, ref) => { ...@@ -107,6 +112,7 @@ const XRender = (props, ref) => {
watch={watch} watch={watch}
onMount={onMount} onMount={onMount}
/> />
</Spin>
</div> </div>
) )
......
import { message } from 'antd' import { message } from 'antd'
import { isObject } from '../../utils' import { isObject } from '../../utils'
import { formAutomaticComputation, GetSelectItemList } from '../../apis/process' import { formAutomaticComputation, GetSelectItemList, formFieldHideComputation } from '../../apis/process'
export const debounce = (fn) => { export const debounce = (fn) => {
let t = null let t = null
...@@ -57,6 +57,7 @@ const getWidgetInfo = (json, widget) => { ...@@ -57,6 +57,7 @@ const getWidgetInfo = (json, widget) => {
for (let s in child) { for (let s in child) {
if (child[s].widget === widget) { if (child[s].widget === widget) {
AutoCalculate.push({ AutoCalculate.push({
gorupName: v,
fieldName: s, fieldName: s,
...child[s], ...child[s],
targetPath: `${v}.${s}`, targetPath: `${v}.${s}`,
...@@ -69,6 +70,30 @@ const getWidgetInfo = (json, widget) => { ...@@ -69,6 +70,30 @@ const getWidgetInfo = (json, widget) => {
return AutoCalculate return AutoCalculate
} }
//获取含有隐藏条件形态
const getHiddenWidget = (json) => {
let HiddenWidget = []
let parent = json?.properties
if (isObject(parent)) {
for (let v in parent) {
let child = parent[v]?.properties
if (isObject(child)) {
for (let s in child) {
if (Array.isArray(child[s].hiddenRules) && child[s].hiddenRules.length) {
HiddenWidget.push({
gorupName: v,
fieldName: s,
...child[s],
targetPath: `${v}.${s}`,
})
}
}
}
}
}
return HiddenWidget
}
const getPath = (json, filed) => { const getPath = (json, filed) => {
let parent = json?.properties let parent = json?.properties
if (isObject(parent)) { if (isObject(parent)) {
...@@ -96,7 +121,7 @@ const getFieldName = (configs, tableName) => { ...@@ -96,7 +121,7 @@ const getFieldName = (configs, tableName) => {
return path return path
} }
const automaticComputation = async (params) => { const formAutomatic = async (params) => {
if ((new Date().getTime() - params.startTime) < 2000) return if ((new Date().getTime() - params.startTime) < 2000) return
let param = { let param = {
tableName: params.tableName, tableName: params.tableName,
...@@ -119,16 +144,56 @@ const automaticComputation = async (params) => { ...@@ -119,16 +144,56 @@ const automaticComputation = async (params) => {
} }
} }
//自动计算监听 //如果该分组下所有字段隐藏那就影隐藏分组
const getGroupHidden = (form, schema, gorupName) => {
let gorupSchema = schema?.properties?.[gorupName]?.properties || {}
let hidden = true
for (let key in gorupSchema) {
let sunSchema = form.getSchemaByPath(`${gorupName}.${key}`)
if (!sunSchema.hidden) {
hidden = false
}
}
return hidden
}
const formFieldHide = async (params) => {
let param = {
tableName: params.tableName,
filedFormulas: params.filedFormulas,
relationForm: params.relationForm,
values: jsonToValues(params.form.getValues(), params.paths).formValue
}
const { code, data } = await formFieldHideComputation(param)
if (code === 0) {
if (Array.isArray(data)) {
data.forEach(v => {
let path = getPath(params.schema, v.fieldName)
if (path) {
params?.form?.setSchemaByPath(path, { ...params?.form?.getSchemaByPath(path), hidden: v.fieldValue })
let hidden = getGroupHidden(params?.form, params.schema, params.gorupName)
params?.form?.setSchemaByPath(params.gorupName, { ...params?.form?.getSchemaByPath(params.gorupName), hidden: hidden })
}
})
}
}
}
const Automatic = debounce(formAutomatic)
const fieldHide = debounce(formFieldHide)
//自动计算监听/隐藏条件监听
const getAutoWatch = (schema, form, startTime) => { const getAutoWatch = (schema, form, startTime) => {
let watch = {} let watch = {}
let paths = [] let paths = []
let { relationForm } = form?.getValues() let { relationForm } = form?.getValues()
const configs = relationForm?.configs || [] const configs = relationForm?.configs || []
const AutoCalculate = getWidgetInfo(schema, 'NumberInput') const AutoCalculate = getWidgetInfo(schema, 'NumberInput')
const HiddenWidget = getHiddenWidget(schema)
if (Array.isArray(AutoCalculate)) { if (Array.isArray(AutoCalculate)) {
AutoCalculate.forEach(item => { AutoCalculate.forEach(item => {
const { fieldName, rules, calculateRule } = item const { gorupName, fieldName, rules, calculateRule } = item
if (Array.isArray(rules)) { if (Array.isArray(rules)) {
rules.forEach(s => { rules.forEach(s => {
if (schema.tableName === s.tableName) { if (schema.tableName === s.tableName) {
...@@ -136,24 +201,48 @@ const getAutoWatch = (schema, form, startTime) => { ...@@ -136,24 +201,48 @@ const getAutoWatch = (schema, form, startTime) => {
s.fields.forEach(v => { s.fields.forEach(v => {
let path = getPath(schema, v) let path = getPath(schema, v)
if (path) { if (path) {
paths.push({ path: path, fieldName, formula: calculateRule }) paths.push({ gorupName, type: ['AutoCalculate'], path: path, fieldName, formula: calculateRule })
} }
}) })
} }
} else { } else {
let path = getFieldName(configs, s.tableName) let path = getFieldName(configs, s.tableName)
if (path) { if (path) {
paths.push({ path, fieldName, formula: calculateRule }) paths.push({ gorupName, type: ['AutoCalculate'], path, fieldName, formula: calculateRule })
} }
} }
}) })
} }
}) })
} }
if (Array.isArray(HiddenWidget)) {
HiddenWidget.forEach(item => {
const { gorupName, fieldName, hiddenRules, hiddenCondition } = item
if (Array.isArray(hiddenRules)) {
hiddenRules.forEach(v => {
if (Array.isArray(v.fields)) {
v.fields.forEach(s => {
let path = getPath(schema, s)
if (path) {
paths.push({
gorupName,
type: ['HiddenWidget'],
path,
fieldName,
formula: hiddenCondition
})
}
})
}
})
}
})
}
if (Array.isArray(paths)) { if (Array.isArray(paths)) {
paths.forEach(v => { paths.forEach(v => {
watch[v.path] = () => { watch[v.path] = () => {
let params = { let params = {
...v,
tableName: schema.tableName, tableName: schema.tableName,
filedFormulas: paths.filter(s => s.path === v.path), filedFormulas: paths.filter(s => s.path === v.path),
form: form, form: form,
...@@ -162,7 +251,12 @@ const getAutoWatch = (schema, form, startTime) => { ...@@ -162,7 +251,12 @@ const getAutoWatch = (schema, form, startTime) => {
schema: schema, schema: schema,
startTime startTime
} }
debounce(automaticComputation)(params) if (v.type.includes('AutoCalculate')) {
Automatic(params)
}
if (v.type.includes('HiddenWidget')) {
fieldHide(params)
}
} }
}) })
} }
...@@ -177,7 +271,6 @@ const getSelectItemList = async (params) => { ...@@ -177,7 +271,6 @@ const getSelectItemList = async (params) => {
let array = data.filter(v => v.nodeName === value) let array = data.filter(v => v.nodeName === value)
console.log(data, array) console.log(data, array)
if (Array.isArray(array) && array.length) { if (Array.isArray(array) && array.length) {
form.setValueByPath(targetPath, array[0].nodeValue) form.setValueByPath(targetPath, array[0].nodeValue)
} }
} }
......
...@@ -9,9 +9,9 @@ const SwitchSelector = (props) => { ...@@ -9,9 +9,9 @@ const SwitchSelector = (props) => {
useEffect(() => { useEffect(() => {
if (addons) { if (addons) {
addons.setValue(addons.dataPath, presetValue === text[0]) addons.setValue(addons.dataPath, presetValue)
} else { } else {
onChange(presetValue === text[0]) onChange(presetValue)
} }
}, [presetValue]) }, [presetValue])
...@@ -23,7 +23,7 @@ const SwitchSelector = (props) => { ...@@ -23,7 +23,7 @@ const SwitchSelector = (props) => {
return ( return (
<Switch <Switch
checked={Boolean(Number(value === text[0]))} checked={Boolean(value === text[0])}
disabled={disabled} disabled={disabled}
checkedChildren={text[0]} checkedChildren={text[0]}
unCheckedChildren={text[1]} unCheckedChildren={text[1]}
......
import React, { useState, useRef } from 'react'
import { Modal, Input, message, Dropdown, Menu, Tree } from 'antd'
import styles from './index.less'
import { ReloadTableFields, ruleValidation, getFormFieldHideDtos } from '../../../../../apis/process'
import Drag from '../../../../components/Drag'
const { TextArea } = Input
const fnList = [
{ label: '是否为工作日', value: '$fn.isWorkDay()' },
{ label: '是否为工作时间', value: '$fn.isWorkTime()' },
]
const HiddenCondition = (props) => {
const { value, onChange, addons } = props
const { tableNameParent } = addons.formData
const [visible, setVisible] = useState(false)
const [fieldList, setFieldList] = useState([])
const [rule, setRule] = useState([])
const [currentSelectId, setCurrentSelectId] = useState('')
const ruleText = useRef()
const getFieldList = async () => {
let { code, data, msg } = await ReloadTableFields({ tableName: tableNameParent })
if (code === 0) {
setFieldList([
{
title: tableNameParent,
key: tableNameParent,
children: data.root.map(v => { return { title: v.name, key: `${tableNameParent}.${v.name}` } })
}
])
} else {
message.error(msg)
}
}
const inputClick = () => {
setVisible(true)
getFieldList()
setRule(value || '')
if (value) {
setTimeout(() => {
document
.getElementById('ruleText')
.setSelectionRange(value.length, value.length)
}, 200)
}
}
const onSelect = (prop, treeNode) => {
if (!treeNode.node.children) {
insert(`{${treeNode.node.key}}`)
}
setCurrentSelectId(prop[0]);
}
const onOk = async () => {
if (rule) {
const { code, data } = await getFormFieldHideDtos({ formula: rule })
if (data) {
addons.setValue('hiddenRules', data)
onChange(rule)
setVisible(false)
} else {
addons.setValue('hiddenRules', [])
message.error('校验不通过!')
}
}
}
const onCancel = () => {
setVisible(false)
}
const insert = text => {
let ednIndex = document.getElementById('ruleText').selectionEnd
let rangeIndex = document.getElementById('ruleText').selectionStart
setRule(`${rule.slice(0, rangeIndex)}${text}${rule.slice(rangeIndex)}`)
rangeIndex += text.toString().length
ruleText.current.focus()
}
const insertFn = value => {
insert(value)
}
const fnListRender = (
<Menu>
{fnList.map(item => (
<Menu.Item key={item.value} onClick={() => insertFn(item.value)}>
{item.label}
</Menu.Item>
))}
</Menu>
)
return (
<div>
<Input
value={value}
onClick={inputClick}
/>
<Drag
title="规则配置"
visible={visible}
onOk={onOk}
width="740px"
onCancel={onCancel}
maskClosable={false}
destroyOnClose
getContainer={false}
>
{
tableNameParent ? (
<div className={styles.configContent}>
<div className={styles.leftTree}>
<Tree
blockNode
defaultExpandedKeys={[tableNameParent]}
autoExpandParent={true}
onSelect={onSelect}
selectedKeys={[currentSelectId]}
treeData={fieldList}
/>
</div>
<div className={styles.rightContent}>
<div className={styles.textAreaBox}>
<Dropdown overlay={fnListRender} placement="bottom" arrow>
<div className={styles.insertFn}>插入函数</div>
</Dropdown>
<TextArea
id="ruleText"
autoSize={{ minRows: 19, maxRows: 19 }}
value={rule}
rows={4}
ref={ruleText}
onChange={e => setRule(e.target.value)}
/>
</div>
<ul className={styles.tipBox}>
<li>
<p>请从左侧面板选择字段或选项</p>
<p>
{'支持'} <i>英文</i> {'模式下运算符(+、-、*、/><=!=<=>='}
</p>
</li>
<li>{`示例:{表名.是否缴费} = ‘是’ and {表名.缴费金额} > 1000`}</li>
</ul>
</div>
</div>
) : null
}
</Drag>
</div>
)
}
export default HiddenCondition
.configContent {
height: 500px;
display: flex;
.leftTree {
width: 180px;
height: 100%;
margin-right: 10px;
overflow-y: auto;
}
.rightContent {
flex: 1;
.title {
width: 100%;
background-color: #E6F3FF;
color: #1890FF;
font-size: 14px;
padding: 5px 10px;
border: 1px solid #EEF6FE;
}
.textAreaBox {
position: relative;
.insertFn {
position: absolute;
bottom: 10px;
right: 10px;
border: 1px solid #1890FF;
padding: 2px 15px;
border-radius: 5px;
z-index: 1;
cursor: pointer;
}
textArea {
max-height: 360px !important;
min-height: 360px !important;
border: 1px solid transparent;
background-color: #F0F2F6;
}
}
.tipBox {
padding-top: 12px;
padding-left: 25px;
li {
list-style: disc;
color: #AEAEAE;
}
em {
font-style: normal;
color: #1890FF;
}
i {
font-style: normal;
color: red;
}
p {
margin-bottom: 0;
color: #AEAEAE;
}
}
}
}
\ No newline at end of file
...@@ -6,6 +6,7 @@ import CascadeDefault from './CascadeDefault' ...@@ -6,6 +6,7 @@ import CascadeDefault from './CascadeDefault'
import DateDefault from './DateDefault' import DateDefault from './DateDefault'
import TimeDefault from './TimeDefault' import TimeDefault from './TimeDefault'
import WidgetType from './WidgetType' import WidgetType from './WidgetType'
import HiddenCondition from './HiddenCondition'
const groupBase = { const groupBase = {
FieldNames, FieldNames,
...@@ -16,6 +17,7 @@ const groupBase = { ...@@ -16,6 +17,7 @@ const groupBase = {
DateDefault, DateDefault,
TimeDefault, TimeDefault,
WidgetType, WidgetType,
HiddenCondition,
} }
export default groupBase export default groupBase
\ No newline at end of file
...@@ -61,7 +61,6 @@ const ControlRules = (props) => { ...@@ -61,7 +61,6 @@ const ControlRules = (props) => {
const { code, data } = await ruleValidation(rule) const { code, data } = await ruleValidation(rule)
if (!data) { if (!data) {
return message.error('校验不通过!') return message.error('校验不通过!')
} }
} }
onChange(rule) onChange(rule)
......
...@@ -27,6 +27,9 @@ body #app { ...@@ -27,6 +27,9 @@ body #app {
} }
} }
} }
.@{ant-prefix}-spin-spinning {
background: rgb(255, 255, 255, 0.7);
}
.@{ant-prefix}-tabs-content-holder { .@{ant-prefix}-tabs-content-holder {
height: 664px; height: 664px;
overflow: auto; overflow: auto;
......
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