| 1 | 1 | import { ControlOutlined } from '@ant-design/icons'; | 
| 2 |  | -import { Select, Tooltip } from 'antd'; | 
|  | 2 | +import { Select, Tooltip, Input } from 'antd'; | 
|  | 3 | +import { size } from 'lodash-es'; | 
| 3 | 4 | import React, { useState } from 'react'; | 
| 4 | 5 | import type { QxBaseConditionField } from '../qx-base-condition'; | 
| 5 | 6 | import { QxBaseIcon } from '../qx-base-icon'; | 
| ... | ... | @@ -7,6 +8,18 @@ import { QxFieldSetter } from '../qx-field-setter'; | 
| 7 | 8 |  | 
| 8 | 9 | import './index.less'; | 
| 9 | 10 |  | 
|  | 11 | +export const multipleType = [ | 
|  | 12 | +  'STRING', | 
|  | 13 | +  'REL_MULTI', | 
|  | 14 | +  'ENUM', | 
|  | 15 | +  'ENUM_MULTI', | 
|  | 16 | +  'TEXT', | 
|  | 17 | +  // 'TREE', | 
|  | 18 | +  // 'USER', | 
|  | 19 | +  'USER_MULTI', | 
|  | 20 | +  // 'ORG', | 
|  | 21 | +  'ORG_MULTI', | 
|  | 22 | +]; | 
| 10 | 23 | /** | 
| 11 | 24 | * 过滤条件运算符及默认选项 | 
| 12 | 25 | */ | 
| ... | ... | @@ -636,6 +649,23 @@ export const ConditionCol: any = { | 
| 636 | 649 | }, | 
| 637 | 650 | }; | 
| 638 | 651 |  | 
|  | 652 | +const optValTypeCheck = { | 
|  | 653 | +  // 条件是否为"为空"、"不为空" | 
|  | 654 | +  isEmptyType: (opt: any) => { | 
|  | 655 | +    return ['IS_NULL', 'NOT_NULL'].includes(opt || ''); | 
|  | 656 | +  }, | 
|  | 657 | +  // 范围类型 | 
|  | 658 | +  isRangeType: (opt: any) => { | 
|  | 659 | +    return ['IN', 'NOT_IN'].includes(opt || ''); | 
|  | 660 | +  }, | 
|  | 661 | +  // 流程条件多选优化 | 
|  | 662 | +  isMultiType: (opt: any) => { | 
|  | 663 | +    return ['BELONG', 'NOT_BELONG', 'INCLUDE', 'NOT_INCLUDE'].includes( | 
|  | 664 | +      opt || '', | 
|  | 665 | +    ); | 
|  | 666 | +  }, | 
|  | 667 | +}; | 
|  | 668 | + | 
| 639 | 669 | export const WidgetsIcon = ({ widgetName }: { widgetName: string }) => { | 
| 640 | 670 | let iconType: string = ''; | 
| 641 | 671 | switch (widgetName) { | 
| ... | ... | @@ -762,15 +792,16 @@ export const WidgetsIcon = ({ widgetName }: { widgetName: string }) => { | 
| 762 | 792 |  | 
| 763 | 793 | export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ | 
| 764 | 794 | value, | 
| 765 |  | -  isMultiple = false, | 
| 766 |  | -  isRange = false, | 
| 767 | 795 | field, | 
| 768 | 796 | remove, | 
| 769 | 797 | onChange, | 
|  | 798 | +  mode = 'condition', | 
| 770 | 799 | ValueAssignmentPopup, | 
| 771 | 800 | }) => { | 
| 772 | 801 | const [CustomValueRender, setCustomValueRender] = | 
| 773 |  | -    useState<React.ReactNode>(null); | 
|  | 802 | +    useState<() => React.ReactNode>(); | 
|  | 803 | + | 
|  | 804 | +  const [open, setOpen] = useState(false); | 
| 774 | 805 |  | 
| 775 | 806 | const handleChange = (val: any) => { | 
| 776 | 807 | onChange?.({ | 
| ... | ... | @@ -781,40 +812,89 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ | 
| 781 | 812 | }; | 
| 782 | 813 |  | 
| 783 | 814 | const handleFilerChange = (val: string) => { | 
| 784 |  | -    onChange?.({ | 
|  | 815 | +    const newValue = { | 
| 785 | 816 | ...(value || {}), | 
| 786 | 817 | opt: val, | 
| 787 |  | -    }); | 
|  | 818 | +    }; | 
|  | 819 | + | 
|  | 820 | +    // "为空"、"不为空"条件时,置空"值" | 
|  | 821 | +    if (optValTypeCheck.isEmptyType(newValue.opt)) { | 
|  | 822 | +      newValue.valuesObj = []; | 
|  | 823 | +    } | 
|  | 824 | + | 
|  | 825 | +    // 切换到非'范围'类型时,删除第2个值 | 
|  | 826 | +    if (optValTypeCheck.isRangeType(newValue?.opt)) { | 
|  | 827 | +      newValue.valuesObj = (newValue.valuesObj || []).filter( | 
|  | 828 | +        (it) => it?.isRange, | 
|  | 829 | +      ); | 
|  | 830 | +    } else if ( | 
|  | 831 | +      optValTypeCheck.isMultiType(newValue?.opt) || | 
|  | 832 | +      multipleType.includes(newValue.fieldGroupType) | 
|  | 833 | +    ) { | 
|  | 834 | +    } else { | 
|  | 835 | +      const vals = (newValue.valuesObj || []).map((it) => it?.isRange); | 
|  | 836 | +      if (size(vals) > 1) { | 
|  | 837 | +        newValue.valuesObj = [newValue.valuesObj[0]]; | 
|  | 838 | +      } | 
|  | 839 | +    } | 
|  | 840 | + | 
|  | 841 | +    onChange?.(newValue); | 
| 788 | 842 | }; | 
| 789 | 843 |  | 
| 790 | 844 | const handleDefaultValueSettingChange = ( | 
| 791 | 845 | val: any, | 
| 792 |  | -    valueRender: React.ReactNode, | 
|  | 846 | +    valueRender: () => React.ReactNode, | 
| 793 | 847 | ) => { | 
| 794 | 848 | handleChange(val); | 
| 795 |  | -    setCustomValueRender(valueRender); | 
|  | 849 | +    setCustomValueRender(() => valueRender); | 
| 796 | 850 | }; | 
| 797 | 851 |  | 
|  | 852 | +  const handleOpenChange = setOpen; | 
|  | 853 | + | 
| 798 | 854 | const RenderContent = ( | 
| 799 | 855 | <> | 
| 800 |  | -      {CustomValueRender && ( | 
|  | 856 | +      {typeof CustomValueRender === 'function' && ( | 
| 801 | 857 | <div className="qx-base-condition-item__content-value-render"> | 
| 802 |  | -          {CustomValueRender} | 
|  | 858 | +          {CustomValueRender()} | 
| 803 | 859 | </div> | 
| 804 | 860 | )} | 
| 805 | 861 | <QxFieldSetter | 
| 806 | 862 | value={value?.valuesObj} | 
| 807 | 863 | fieldGroupType={value?.fieldGroupType} | 
| 808 | 864 | onChange={handleChange} | 
| 809 |  | -        isMultiple={isMultiple} | 
| 810 |  | -        isRange={isRange} | 
|  | 865 | +        isMultiple={multipleType.includes(value?.fieldGroupType)} | 
|  | 866 | +        isRange={optValTypeCheck.isRangeType(value?.opt)} | 
|  | 867 | +        disabled={optValTypeCheck.isEmptyType(value?.opt)} | 
| 811 | 868 | /> | 
| 812 |  | -      {ValueAssignmentPopup && ( | 
| 813 |  | -        <ControlOutlined className="qx-base-condition-item__content-suffix" /> | 
|  | 869 | +      {typeof ValueAssignmentPopup !== 'undefined' && ( | 
|  | 870 | +        <ControlOutlined | 
|  | 871 | +          onClick={() => { | 
|  | 872 | +            handleOpenChange(!open); | 
|  | 873 | +          }} | 
|  | 874 | +          className="qx-base-condition-item__content-suffix" | 
|  | 875 | +        /> | 
| 814 | 876 | )} | 
| 815 | 877 | </> | 
| 816 | 878 | ); | 
| 817 | 879 |  | 
|  | 880 | +  const RenderFilter = () => { | 
|  | 881 | +    switch (mode) { | 
|  | 882 | +      case 'condition': | 
|  | 883 | +        return ( | 
|  | 884 | +          <Select | 
|  | 885 | +            value={value?.opt} | 
|  | 886 | +            className="qx-base-condition-item__header-filter__select" | 
|  | 887 | +            bordered={false} | 
|  | 888 | +            fieldNames={{ label: 'text', value: 'key' }} | 
|  | 889 | +            options={ConditionCol[value.fieldGroupType]?.operations || []} | 
|  | 890 | +            onChange={handleFilerChange} | 
|  | 891 | +          /> | 
|  | 892 | +        ); | 
|  | 893 | +      default: | 
|  | 894 | +        return <a>设为</a>; | 
|  | 895 | +    } | 
|  | 896 | +  }; | 
|  | 897 | + | 
| 818 | 898 | return ( | 
| 819 | 899 | <div className="qx-base-condition-item"> | 
| 820 | 900 | <div className="qx-base-condition-item__header"> | 
| ... | ... | @@ -828,14 +908,7 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ | 
| 828 | 908 | </div> | 
| 829 | 909 | <div className="qx-base-condition-item__header-right"> | 
| 830 | 910 | <span className="qx-base-condition-item__header-filter"> | 
| 831 |  | -            <Select | 
| 832 |  | -              value={value?.opt} | 
| 833 |  | -              className="qx-base-condition-item__header-filter__select" | 
| 834 |  | -              bordered={false} | 
| 835 |  | -              fieldNames={{ label: 'text', value: 'key' }} | 
| 836 |  | -              options={ConditionCol[value.fieldGroupType]?.operations || []} | 
| 837 |  | -              onChange={handleFilerChange} | 
| 838 |  | -            /> | 
|  | 911 | +            <RenderFilter /> | 
| 839 | 912 | </span> | 
| 840 | 913 | <span className="qx-base-condition-item__header-delete"> | 
| 841 | 914 | <Tooltip title="删除"> | 
| ... | ... | @@ -848,12 +921,13 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ | 
| 848 | 921 | </div> | 
| 849 | 922 | </div> | 
| 850 | 923 | <div className="qx-base-condition-item__content"> | 
| 851 |  | -        {ValueAssignmentPopup ? ( | 
|  | 924 | +        {typeof ValueAssignmentPopup !== 'undefined' ? ( | 
| 852 | 925 | <ValueAssignmentPopup | 
|  | 926 | +            open={open} | 
| 853 | 927 | value={value} | 
| 854 |  | -            isMultiple={isMultiple} | 
| 855 | 928 | field={field} | 
| 856 | 929 | onChange={handleDefaultValueSettingChange} | 
|  | 930 | +            onOpenChange={handleOpenChange} | 
| 857 | 931 | > | 
| 858 | 932 | {RenderContent} | 
| 859 | 933 | </ValueAssignmentPopup> | 
| ... | ... | @@ -868,15 +942,16 @@ export const QxBaseConditionItem: React.FC<QxBaseConditionItemProps> = ({ | 
| 868 | 942 | export interface ValueAssignmentPopupProps | 
| 869 | 943 | extends Omit<QxBaseConditionItemProps, 'onChange'> { | 
| 870 | 944 | children?: React.ReactNode; | 
| 871 |  | -  onChange?: (val: any, valueRender: React.ReactNode) => void; | 
|  | 945 | +  onChange?: (val: any, valueRender: () => React.ReactNode) => void; | 
|  | 946 | +  open?: boolean; | 
|  | 947 | +  onOpenChange?: (open: boolean) => void; | 
| 872 | 948 | } | 
| 873 | 949 |  | 
| 874 | 950 | export interface QxBaseConditionItemProps { | 
| 875 | 951 | field: QxBaseConditionField; | 
| 876 | 952 | value?: any; | 
| 877 |  | -  isMultiple?: boolean; | 
| 878 |  | -  isRange?: boolean; | 
| 879 | 953 | onChange?: (val: any) => void; | 
| 880 | 954 | remove?: (field: QxBaseConditionField) => void; | 
| 881 | 955 | ValueAssignmentPopup?: React.FC<ValueAssignmentPopupProps>; | 
|  | 956 | +  mode?: string; | 
| 882 | 957 | } | 
... | ... |  |