index.tsx 2.56 KB
import { FunctionOutlined } from '@ant-design/icons';
import { Input, Select } from 'antd';
import cx from 'classnames';
import React, { useEffect, useState } from 'react';
import './index.less';

const prefix = 'qx-condition-sql';

/**
 * 条件表达式运算符
 */
export const OperatorCol = [
  {
    key: 'AND',
    text: '且',
  },
  {
    key: 'OR',
    text: '或',
  },
  {
    key: 'CUSTOM',
    text: 'CUSTOM',
  },
];

const options = OperatorCol.map((item) => ({
  value: item.key,
  label: item.key === 'CUSTOM' ? <FunctionOutlined /> : item.text,
}));

/**
 * 组合条件
 */
export const QxConditionSql: React.FC<ConditionSqlProps> = ({
  onChange,
  onBlur,
  value,
}) => {
  const [state, setState] = useState<ConditionSqlState>(
    value || {
      sqlType: 'AND',
    },
  );

  const handleInputValueChange = (
    e: React.ChangeEvent<HTMLTextAreaElement>,
  ) => {
    const expression = e.target.value;
    setState({ ...state, expression });
  };

  useEffect(() => {
    onChange?.(state);
  }, [state]);

  useEffect(() => {
    onChange?.({ expression: '', sqlType: 'AND' });
  }, []);

  return (
    <div className={prefix}>
      <div className={`${prefix}__header`}>
        <span className={`${prefix}__title`}>添加组合方式</span>
        <Select
          value={state.sqlType || value?.sqlType}
          bordered={false}
          className={`${prefix}__select`}
          options={options}
          onChange={(value) => {
            setState({
              sqlType: value,
              expression:
                value !== 'CUSTOM'
                  ? `1 ${value.toLocaleLowerCase()} 2`
                  : state.expression,
            });
          }}
        />
      </div>
      {state.sqlType === 'CUSTOM' ? (
        <div className={`${prefix}__input`}>
          <Input.TextArea
            className={cx(`${prefix}__input-textarea`, 'qx-input')}
            defaultValue={state.expression}
            onChange={handleInputValueChange}
            onBlur={(e) => {
              handleInputValueChange(e);
              onBlur?.({ ...state, expression: e.target.value });
            }}
            placeholder="请使用序号、小括号(英文)、逻辑符(and,or) 编写表达式例如:(1 and 2) or 3"
          />
        </div>
      ) : null}
    </div>
  );
};

interface ConditionSqlProps {
  onChange?: (val: ConditionSqlState) => void;
  onBlur?: (val: ConditionSqlState) => void;
  value?: ConditionSqlState;
}

export interface ConditionSqlState {
  expression?: string;
  sqlType: SqlType;
}

export type SqlType = 'AND' | 'OR' | 'CUSTOM';