mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 11:58:10 +08:00
补充条件组合逻辑
This commit is contained in:
parent
0e78191ddc
commit
5a8c2d8fee
@ -1,74 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import ConditionBuilder from '../../../src/components/condition-builder';
|
|
||||||
|
|
||||||
const fields = [
|
|
||||||
{
|
|
||||||
label: '姓名',
|
|
||||||
name: 'name',
|
|
||||||
type: 'text'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '年龄',
|
|
||||||
name: 'age',
|
|
||||||
type: 'number'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '出生日期',
|
|
||||||
name: 'birthday',
|
|
||||||
type: 'date'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '起床时间',
|
|
||||||
name: 'wakeupAt',
|
|
||||||
type: 'time'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '入职时间',
|
|
||||||
name: 'ruzhi',
|
|
||||||
type: 'datetime'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '关系字段',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
label: '姓名',
|
|
||||||
name: 'name2',
|
|
||||||
type: 'text'
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
label: '年龄',
|
|
||||||
name: 'age2',
|
|
||||||
type: 'number'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const funcs = [
|
|
||||||
// {
|
|
||||||
// label: '文本',
|
|
||||||
// children: [
|
|
||||||
// {
|
|
||||||
// type: 'LOWERCASE',
|
|
||||||
// label: '转小写',
|
|
||||||
// returnType: 'text',
|
|
||||||
// args: [
|
|
||||||
// {
|
|
||||||
// type: 'text',
|
|
||||||
// label: '文本'
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
];
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
type: 'page',
|
type: 'page',
|
||||||
title: '表单页面',
|
title: '表单页面',
|
||||||
@ -76,50 +5,19 @@ export default {
|
|||||||
type: 'form',
|
type: 'form',
|
||||||
mode: 'horizontal',
|
mode: 'horizontal',
|
||||||
title: '',
|
title: '',
|
||||||
data: {a: [{b: 1, c: [{d: 2}]}]},
|
debug: true,
|
||||||
// debug: true,
|
|
||||||
api: '/api/mock2/form/saveForm',
|
api: '/api/mock2/form/saveForm',
|
||||||
controls: [
|
controls: [
|
||||||
// {
|
{
|
||||||
// label: 'Name',
|
label: 'Name',
|
||||||
// type: 'text',
|
type: 'text',
|
||||||
// name: 'name'
|
name: 'name'
|
||||||
// },
|
},
|
||||||
|
|
||||||
// {
|
|
||||||
// label: 'Email',
|
|
||||||
// type: 'email',
|
|
||||||
// name: 'email'
|
|
||||||
// },
|
|
||||||
|
|
||||||
// {
|
|
||||||
// name: 'a',
|
|
||||||
// type: 'static',
|
|
||||||
// tpl: '${a|json:2}'
|
|
||||||
// },
|
|
||||||
|
|
||||||
// {
|
|
||||||
// name: 'a.0.b',
|
|
||||||
// type: 'text',
|
|
||||||
// label: 'B'
|
|
||||||
// },
|
|
||||||
|
|
||||||
// {
|
|
||||||
// name: 'a.0.c.0.d',
|
|
||||||
// type: 'number',
|
|
||||||
// label: 'D'
|
|
||||||
// },
|
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'a',
|
label: 'Email',
|
||||||
component: ({value, onChange}) => (
|
type: 'email',
|
||||||
<ConditionBuilder
|
name: 'email'
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
fields={fields}
|
|
||||||
funcs={funcs}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
.#{$ns}CBDelete {
|
||||||
|
margin-left: $gap-xs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&:not(:hover) .#{$ns}CBGroup-toolbarRight {
|
&:not(:hover) .#{$ns}CBGroup-toolbarRight {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -168,7 +172,7 @@
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover > &-body {
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ import {
|
|||||||
ExpressionFunc,
|
ExpressionFunc,
|
||||||
Type,
|
Type,
|
||||||
FieldSimple,
|
FieldSimple,
|
||||||
FieldGroup
|
FieldGroup,
|
||||||
|
OperatorType
|
||||||
} from './types';
|
} from './types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ConditionField from './Field';
|
import ConditionField from './Field';
|
||||||
@ -34,6 +35,7 @@ export interface ExpressionProps extends ThemeProps {
|
|||||||
funcs?: Funcs;
|
funcs?: Funcs;
|
||||||
defaultType?: 'value' | 'field' | 'func' | 'raw';
|
defaultType?: 'value' | 'field' | 'func' | 'raw';
|
||||||
allowedTypes?: Array<'value' | 'field' | 'func' | 'raw'>;
|
allowedTypes?: Array<'value' | 'field' | 'func' | 'raw'>;
|
||||||
|
op?: OperatorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldMap = {
|
const fieldMap = {
|
||||||
@ -109,7 +111,8 @@ export class Expression extends React.Component<ExpressionProps> {
|
|||||||
defaultType,
|
defaultType,
|
||||||
allowedTypes,
|
allowedTypes,
|
||||||
funcs,
|
funcs,
|
||||||
fields
|
fields,
|
||||||
|
op
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const inputType =
|
const inputType =
|
||||||
((value as any)?.type === 'field'
|
((value as any)?.type === 'field'
|
||||||
@ -138,6 +141,7 @@ export class Expression extends React.Component<ExpressionProps> {
|
|||||||
field={valueField!}
|
field={valueField!}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={this.handleValueChange}
|
onChange={this.handleValueChange}
|
||||||
|
op={op}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
@ -158,11 +158,7 @@ export class ConditionGroup extends React.Component<ConditionGroupProps> {
|
|||||||
<Icon icon="plus" className="icon" />
|
<Icon icon="plus" className="icon" />
|
||||||
添加条件
|
添加条件
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button onClick={this.handleAddGroup} size="xs">
|
||||||
onClick={this.handleAddGroup}
|
|
||||||
size="xs"
|
|
||||||
className="m-r-xs"
|
|
||||||
>
|
|
||||||
<Icon icon="plus-cicle" className="icon" />
|
<Icon icon="plus-cicle" className="icon" />
|
||||||
添加条件组
|
添加条件组
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -95,7 +95,7 @@ export class ConditionItem extends React.Component<ConditionItemProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderLeft() {
|
renderLeft() {
|
||||||
const {value, fields, funcs} = this.props;
|
const {value, fields, funcs, config} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Expression
|
<Expression
|
||||||
@ -104,7 +104,9 @@ export class ConditionItem extends React.Component<ConditionItemProps> {
|
|||||||
onChange={this.handleLeftChange}
|
onChange={this.handleLeftChange}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
defaultType="field"
|
defaultType="field"
|
||||||
allowedTypes={['field', 'func']}
|
allowedTypes={(config.valueTypes || ['field', 'func']).filter(
|
||||||
|
type => type === 'field' || type === 'func'
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -272,13 +274,17 @@ export class ConditionItem extends React.Component<ConditionItemProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Expression
|
<Expression
|
||||||
|
op={op}
|
||||||
funcs={funcs}
|
funcs={funcs}
|
||||||
valueField={field}
|
valueField={field}
|
||||||
value={value.right}
|
value={value.right}
|
||||||
onChange={this.handleRightChange}
|
onChange={this.handleRightChange}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
defaultType="value"
|
defaultType="value"
|
||||||
allowedTypes={field?.valueTypes || ['value', 'field', 'func', 'raw']}
|
allowedTypes={
|
||||||
|
field?.valueTypes ||
|
||||||
|
config.valueTypes || ['value', 'field', 'func', 'raw']
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {FieldSimple} from './types';
|
import {FieldSimple, OperatorType} from './types';
|
||||||
import {ThemeProps, themeable} from '../../theme';
|
import {ThemeProps, themeable} from '../../theme';
|
||||||
import InputBox from '../InputBox';
|
import InputBox from '../InputBox';
|
||||||
import NumberInput from '../NumberInput';
|
import NumberInput from '../NumberInput';
|
||||||
import DatePicker from '../DatePicker';
|
import DatePicker from '../DatePicker';
|
||||||
|
import Select from '../Select';
|
||||||
|
import Switch from '../Switch';
|
||||||
|
|
||||||
export interface ValueProps extends ThemeProps {
|
export interface ValueProps extends ThemeProps {
|
||||||
value: any;
|
value: any;
|
||||||
onChange: (value: any) => void;
|
onChange: (value: any) => void;
|
||||||
field: FieldSimple;
|
field: FieldSimple;
|
||||||
|
op?: OperatorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Value extends React.Component<ValueProps> {
|
export class Value extends React.Component<ValueProps> {
|
||||||
render() {
|
render() {
|
||||||
const {classnames: cx, field, value, onChange} = this.props;
|
const {classnames: cx, field, value, onChange, op} = this.props;
|
||||||
let input: JSX.Element | undefined = undefined;
|
let input: JSX.Element | undefined = undefined;
|
||||||
|
|
||||||
if (field.type === 'text') {
|
if (field.type === 'text') {
|
||||||
@ -27,7 +30,7 @@ export class Value extends React.Component<ValueProps> {
|
|||||||
} else if (field.type === 'number') {
|
} else if (field.type === 'number') {
|
||||||
input = (
|
input = (
|
||||||
<NumberInput
|
<NumberInput
|
||||||
placeholder={field.placeholder || '请选择日期'}
|
placeholder={field.placeholder || '请输入数字'}
|
||||||
min={field.minimum}
|
min={field.minimum}
|
||||||
max={field.maximum}
|
max={field.maximum}
|
||||||
value={value ?? field.defaultValue}
|
value={value ?? field.defaultValue}
|
||||||
@ -69,6 +72,20 @@ export class Value extends React.Component<ValueProps> {
|
|||||||
timeFormat={field.timeFormat || 'HH:mm'}
|
timeFormat={field.timeFormat || 'HH:mm'}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
} else if (field.type === 'select') {
|
||||||
|
input = (
|
||||||
|
<Select
|
||||||
|
simpleValue
|
||||||
|
options={field.options!}
|
||||||
|
value={value ?? field.defaultValue}
|
||||||
|
onChange={onChange}
|
||||||
|
multiple={op === 'select_any_in' || op === 'select_not_any_in'}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else if (field.type === 'boolean') {
|
||||||
|
input = (
|
||||||
|
<Switch value={value ?? field.defaultValue} onChange={onChange} />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className={cx('CBValue')}>{input}</div>;
|
return <div className={cx('CBValue')}>{input}</div>;
|
||||||
|
@ -5,6 +5,7 @@ export interface BaseFieldConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
|
valueTypes?: Array<'value' | 'field' | 'func' | 'raw'>;
|
||||||
fields: Fields;
|
fields: Fields;
|
||||||
funcs?: Funcs;
|
funcs?: Funcs;
|
||||||
maxLevel?: number;
|
maxLevel?: number;
|
||||||
@ -27,10 +28,15 @@ export const OperationMap = {
|
|||||||
like: '模糊匹配',
|
like: '模糊匹配',
|
||||||
not_like: '不匹配',
|
not_like: '不匹配',
|
||||||
starts_with: '匹配开头',
|
starts_with: '匹配开头',
|
||||||
ends_with: '匹配结尾'
|
ends_with: '匹配结尾',
|
||||||
|
select_equals: '等于',
|
||||||
|
select_not_equals: '不等于',
|
||||||
|
select_any_in: '包含',
|
||||||
|
select_not_any_in: '不包含'
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultConfig: Config = {
|
const defaultConfig: Config = {
|
||||||
|
valueTypes: ['value'],
|
||||||
types: {
|
types: {
|
||||||
text: {
|
text: {
|
||||||
placeholder: '请输入文本',
|
placeholder: '请输入文本',
|
||||||
@ -103,6 +109,20 @@ const defaultConfig: Config = {
|
|||||||
'is_empty',
|
'is_empty',
|
||||||
'is_not_empty'
|
'is_not_empty'
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
select: {
|
||||||
|
operators: [
|
||||||
|
'select_equals',
|
||||||
|
'select_not_equals',
|
||||||
|
'select_any_in',
|
||||||
|
'select_not_any_in'
|
||||||
|
],
|
||||||
|
valueTypes: ['value']
|
||||||
|
},
|
||||||
|
|
||||||
|
boolean: {
|
||||||
|
operators: ['equal', 'not_equal']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -21,7 +21,11 @@ export type OperatorType =
|
|||||||
| 'greater'
|
| 'greater'
|
||||||
| 'greater_or_equal'
|
| 'greater_or_equal'
|
||||||
| 'between'
|
| 'between'
|
||||||
| 'not_between';
|
| 'not_between'
|
||||||
|
| 'select_equals'
|
||||||
|
| 'select_not_equals'
|
||||||
|
| 'select_any_in'
|
||||||
|
| 'select_not_any_in';
|
||||||
|
|
||||||
export type FieldItem = {
|
export type FieldItem = {
|
||||||
type: 'text';
|
type: 'text';
|
||||||
@ -180,4 +184,5 @@ export type Type = {
|
|||||||
defaultOp?: OperatorType;
|
defaultOp?: OperatorType;
|
||||||
operators: Array<OperatorType>;
|
operators: Array<OperatorType>;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
valueTypes?: Array<'value' | 'field' | 'func' | 'raw'>;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user