// @ts-nocheck
import React, { useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { Form } from 'antd';
import { DownOutlined, UpOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import _isEmpty from 'lodash/isEmpty';
import * as Components from './components';
import styles from './index.less?modules';
/**
* 通用表单
*/
const getRuleMsg = (valueType, label = '', placeholder = '') => {
if (placeholder) return placeholder;
if (['请选择', '请填写'].indexOf(label) > -1) {
return label;
}
if (['input', 'textArea', 'inputNumber', 'list'].indexOf(valueType) > -1) {
return `请填写${label}`;
}
if (['rangePicker'].indexOf(valueType) > -1) {
return void 0;
}
return `请选择${label}`;
};
const XParamForm: React.FC = (props) => {
const { onReady, schema, style, expand, onExpand, ...others } = props;
const [form] = Form.useForm();
onReady && onReady(form);
// 收起展开
const [isExpand, setIsExpand] = useState(false);
const [renderExpand, setRenderExpand] = useState(false);
const paramsContent = useRef();
setTimeout(() => {
const paramsContentHeight = paramsContent.current?.clientHeight;
if (paramsContentHeight && paramsContentHeight > 48 && !renderExpand) {
setRenderExpand(true);
setIsExpand(false);
}
if (paramsContentHeight && paramsContentHeight <= 48 && renderExpand) {
setRenderExpand(false);
setIsExpand(false);
}
}, 500);
// 事件处理
const eventAction = {};
// dom渲染
const domRender = {
// label
renderLabel: (label, labelStyle = {}, tooltip) => {
if (label) {
return (
<span className={styles['XParamForm-label']} style={labelStyle}>
{label}:
</span>
);
}
return null;
},
// 初始化分组配置项
renderGroupSchema: (item) => {
const { valueType, label, labelStyle, schema: memberSchema = [], style: memberStyle = {}, ...formItemProps } = item;
// 属性名称
// const labelDom = domRender.renderLabel(label, labelStyle);
return (
<div
style={{
border: '1px solid rgba(121, 121, 121, 1)',
height: 'auto',
padding: '15px 30px',
marginBottom: '24px',
backgroundColor: 'rgb(253, 253, 253)',
...memberStyle,
}}>
{domRender.renderSchema(memberSchema)}
</div>
);
},
// 初始化普通成员配置项
renderItemSchema: (item) => {
const formItems = [];
const { required, rules, valueType, name, label, style = {}, labelStyle, itemProps = {}, tooltip, ...formItemProps } = item;
// 成员组件
const NodeComponent = Components[valueType] || Components['input'];
// 属性名称
const labelDom = domRender.renderLabel(label, labelStyle, tooltip);
const _itemProps = { placeholder: getRuleMsg(valueType, label, itemProps?.placeholder), ...itemProps };
formItems.push(
<Form.Item
name={name}
label={labelDom}
style={style}
colon={false}
rules={_isEmpty(rules) ? [{ required: required, message: `请填写 ${label}!` }] : rules}
{...formItemProps}>
<NodeComponent {..._itemProps} />
</Form.Item>,
);
return formItems;
},
// 表单项
renderSchema: (schema) => {
const formItems = [];
schema.forEach((item) => {
if (item.valueType == 'button') return;
if (item.display && item.display == 'none') return;
// 如果值类型是一个分组,则分组下的内容在一个面板内,但是数据是平铺的
if (item.valueType == 'group') {
formItems.push(domRender.renderGroupSchema(item));
} else {
formItems.push(domRender.renderItemSchema(item));
}
});
return (
<div style={{ display: 'flex', flexWrap: 'wrap', flexDirection: 'row' }} ref={paramsContent}>
{formItems}
</div>
);
},
renderOperate: () => {
console.log('renderOperate', schema);
const btnItems = [];
schema.forEach((item) => {
if (item.valueType == 'button' && (!item.display || item.display !== 'none')) btnItems.push(domRender.renderItemSchema(item));
});
return btnItems;
},
renderExpand: () => {
const style = { margin: '0 6px' };
return (
renderExpand && (
<span
className={styles['expand']}
onClick={() => {
setIsExpand(!isExpand);
onExpand && onExpand(!isExpand);
}}>
{isExpand ? ' 收起' : ' 展开'}
{isExpand ? <UpOutlined style={style} /> : <DownOutlined style={style} />}
</span>
)
);
},
renderDropdown: () => {
const props = {
valueType: 'dropdown',
label: '下载',
};
const NodeComponent = Components[props.valueType];
return <NodeComponent />;
},
};
return (
<div className={styles['XParamForm']} style={style}>
<Form form={form} {...others}>
<div className={styles['formItems']} style={{ height: isExpand ? 'fit-content' : 48 }}>
{domRender.renderSchema(schema)}
</div>
<span className={styles['btnItems']}>
{domRender.renderExpand()}
{domRender.renderOperate(schema)}
</span>
</Form>
</div>
);
};
/**
* 常用的配置
*/
XParamForm.propTypes = {
style: PropTypes.object,
};
/**
* 默认的配置
*/
XParamForm.defaultProps = {
style: {},
layout: 'inline',
scrollToFirstError: true, // 提交失败自动滚动到第一个错误字段
schema: [],
};
export default XParamForm;
.XParamForm {
width: 100%;
padding: 0;
background: #fff;
&-label {
font-size: 14px;
}
.formItems {
display: flex;
flex-direction: column;
overflow: hidden;
}
.btnItems {
display: flex;
flex: 0 0 auto;
align-items: flex-start;
justify-content: flex-end;
// :global {
// .ant-form-item {
// padding-right: 0 !important;
// }
// }
}
.expand {
z-index: 1;
flex: 0 0 54px;
margin-top: 14px;
cursor: pointer;
}
:global {
.ant-form-inline {
display: flex;
flex-wrap: nowrap;
align-items: flex-start;
justify-content: space-between;
}
.ant-form-inline .ant-form-item {
margin: 0;
padding: 8px 24px 8px 0;
}
// .ant-btn {
// height: 28px !important;
// margin: 0 8px;
// padding: 0px 18px !important;
// font-size: 14px !important;
// }
// .ant-select.ant-select-in-form-item {
// height: 100%;
// }
// .ant-select-show-search.ant-select:not(.ant-select-customize-input) .ant-select-selector {
// height: 100%;
// overflow-y: auto;
// background-color: #fff;
// }
// .ant-select-show-search.ant-select:not(.ant-select-customize-input) .ant-select-selector,
// .ant-select:not(.ant-select-disabled):hover .ant-select-selector,
// .ant-input-affix-wrapper:not(.ant-input-affix-wrapper-disabled):hover,
// .ant-input-affix-wrapper:focus,
// .ant-input-affix-wrapper-focused,
// .ant-picker-focused {
// border-color: #d4d9e5;
// }
}
}