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

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

parent d2bd1b78
{
"name": "panda-xform",
"version": "2.5.9",
"description": "2.5.9: 细节修改",
"version": "2.6.0",
"description": "2.6.0: 所有形态增加隐藏条件",
"keywords": [
"panda-xform"
],
......
......@@ -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) {
return request({
......@@ -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() {
return request({
url: `PandaOMS/OMS/CaseManage/GetGroupAndRole`,
......
This diff is collapsed.
......@@ -6,7 +6,7 @@
*/
import React, { useMemo, useContext, forwardRef, useImperativeHandle, createContext, useState } from 'react'
import FormRender, { useForm } from 'form-render'
import { ConfigProvider } from 'antd'
import { ConfigProvider, Spin } from 'antd'
import widgets from '../widgets'
import { isObject } from '../../utils'
import { getWatch } from './watch'
......@@ -28,6 +28,7 @@ const XRender = (props, ref) => {
const prefixCls = getPrefixCls('pandaXform')
const pandaXform = getPrefixCls()
const [startTime, setStartTime] = useState(new Date().getTime())
const [loading, setLoading] = useState(true)
const form = useForm()
const schemaForm = useMemo(() => {
......@@ -89,11 +90,15 @@ const XRender = (props, ref) => {
//初始化时存储外部传的额外数据
const onMount = () => {
setTimeout(() => {
setLoading(false)
}, 500)
// form.setValueByPath('extraData', extraData || { codes: { '事件编号': '12312' } })
}
return (
<div className={prefixCls}>
<Spin spinning={loading}>
<FormRender
configProvider={{ prefixCls: pandaXform }}
form={form}
......@@ -107,6 +112,7 @@ const XRender = (props, ref) => {
watch={watch}
onMount={onMount}
/>
</Spin>
</div>
)
......
import { message } from 'antd'
import { isObject } from '../../utils'
import { formAutomaticComputation, GetSelectItemList } from '../../apis/process'
import { formAutomaticComputation, GetSelectItemList, formFieldHideComputation } from '../../apis/process'
export const debounce = (fn) => {
let t = null
......@@ -57,6 +57,7 @@ const getWidgetInfo = (json, widget) => {
for (let s in child) {
if (child[s].widget === widget) {
AutoCalculate.push({
gorupName: v,
fieldName: s,
...child[s],
targetPath: `${v}.${s}`,
......@@ -69,6 +70,30 @@ const getWidgetInfo = (json, widget) => {
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) => {
let parent = json?.properties
if (isObject(parent)) {
......@@ -96,7 +121,7 @@ const getFieldName = (configs, tableName) => {
return path
}
const automaticComputation = async (params) => {
const formAutomatic = async (params) => {
if ((new Date().getTime() - params.startTime) < 2000) return
let param = {
tableName: params.tableName,
......@@ -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) => {
let watch = {}
let paths = []
let { relationForm } = form?.getValues()
const configs = relationForm?.configs || []
const AutoCalculate = getWidgetInfo(schema, 'NumberInput')
const HiddenWidget = getHiddenWidget(schema)
if (Array.isArray(AutoCalculate)) {
AutoCalculate.forEach(item => {
const { fieldName, rules, calculateRule } = item
const { gorupName, fieldName, rules, calculateRule } = item
if (Array.isArray(rules)) {
rules.forEach(s => {
if (schema.tableName === s.tableName) {
......@@ -136,24 +201,48 @@ const getAutoWatch = (schema, form, startTime) => {
s.fields.forEach(v => {
let path = getPath(schema, v)
if (path) {
paths.push({ path: path, fieldName, formula: calculateRule })
paths.push({ gorupName, type: ['AutoCalculate'], path: path, fieldName, formula: calculateRule })
}
})
}
} else {
let path = getFieldName(configs, s.tableName)
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)) {
paths.forEach(v => {
watch[v.path] = () => {
let params = {
...v,
tableName: schema.tableName,
filedFormulas: paths.filter(s => s.path === v.path),
form: form,
......@@ -162,7 +251,12 @@ const getAutoWatch = (schema, form, startTime) => {
schema: schema,
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) => {
let array = data.filter(v => v.nodeName === value)
console.log(data, array)
if (Array.isArray(array) && array.length) {
form.setValueByPath(targetPath, array[0].nodeValue)
}
}
......
......@@ -9,9 +9,9 @@ const SwitchSelector = (props) => {
useEffect(() => {
if (addons) {
addons.setValue(addons.dataPath, presetValue === text[0])
addons.setValue(addons.dataPath, presetValue)
} else {
onChange(presetValue === text[0])
onChange(presetValue)
}
}, [presetValue])
......@@ -23,7 +23,7 @@ const SwitchSelector = (props) => {
return (
<Switch
checked={Boolean(Number(value === text[0]))}
checked={Boolean(value === text[0])}
disabled={disabled}
checkedChildren={text[0]}
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'
import DateDefault from './DateDefault'
import TimeDefault from './TimeDefault'
import WidgetType from './WidgetType'
import HiddenCondition from './HiddenCondition'
const groupBase = {
FieldNames,
......@@ -16,6 +17,7 @@ const groupBase = {
DateDefault,
TimeDefault,
WidgetType,
HiddenCondition,
}
export default groupBase
\ No newline at end of file
......@@ -61,7 +61,6 @@ const ControlRules = (props) => {
const { code, data } = await ruleValidation(rule)
if (!data) {
return message.error('校验不通过!')
}
}
onChange(rule)
......
......@@ -27,6 +27,9 @@ body #app {
}
}
}
.@{ant-prefix}-spin-spinning {
background: rgb(255, 255, 255, 0.7);
}
.@{ant-prefix}-tabs-content-holder {
height: 664px;
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