@nokecy/qc-ui 1.1.48 → 1.1.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/cjs/RuleBuilder/RuleBuilderContainer.js +2 -1
  2. package/dist/cjs/RuleBuilder/RuleCard.d.ts +2 -0
  3. package/dist/cjs/RuleBuilder/RuleCard.js +27 -3
  4. package/dist/cjs/RuleBuilder/RuleGroupEditor.d.ts +2 -0
  5. package/dist/cjs/RuleBuilder/RuleGroupEditor.js +5 -1
  6. package/dist/cjs/RuleBuilder/constants/operators.d.ts +5 -0
  7. package/dist/cjs/RuleBuilder/constants/operators.js +9 -1
  8. package/dist/cjs/RuleBuilder/index.d.ts +1 -1
  9. package/dist/cjs/RuleBuilder/index.js +6 -0
  10. package/dist/cjs/RuleBuilder/inputs/ValueInput.d.ts +10 -2
  11. package/dist/cjs/RuleBuilder/inputs/ValueInput.js +56 -5
  12. package/dist/cjs/RuleBuilder/types/index.d.ts +13 -1
  13. package/dist/cjs/RuleBuilder/types/index.js +1 -1
  14. package/dist/cjs/RuleBuilder/utils/validation.js +38 -0
  15. package/dist/esm/RuleBuilder/RuleBuilderContainer.js +2 -1
  16. package/dist/esm/RuleBuilder/RuleCard.d.ts +2 -0
  17. package/dist/esm/RuleBuilder/RuleCard.js +28 -4
  18. package/dist/esm/RuleBuilder/RuleGroupEditor.d.ts +2 -0
  19. package/dist/esm/RuleBuilder/RuleGroupEditor.js +5 -1
  20. package/dist/esm/RuleBuilder/constants/operators.d.ts +5 -0
  21. package/dist/esm/RuleBuilder/constants/operators.js +8 -0
  22. package/dist/esm/RuleBuilder/index.d.ts +1 -1
  23. package/dist/esm/RuleBuilder/index.js +1 -1
  24. package/dist/esm/RuleBuilder/inputs/ValueInput.d.ts +10 -2
  25. package/dist/esm/RuleBuilder/inputs/ValueInput.js +57 -6
  26. package/dist/esm/RuleBuilder/types/index.d.ts +13 -1
  27. package/dist/esm/RuleBuilder/types/index.js +1 -1
  28. package/dist/esm/RuleBuilder/utils/validation.js +39 -1
  29. package/dist/umd/qc-ui.min.js +1 -1
  30. package/package.json +1 -1
@@ -5,11 +5,12 @@
5
5
  * - IsNull/IsNotNull: 不渲染任何输入
6
6
  * - Between: 渲染 BetweenValueInput
7
7
  * - In/NotIn: 渲染 MultiValueInput
8
- * - 其他: 渲染 SingleValueInput
8
+ * - 其他: 渲染 SingleValueInput;允许比较字段时前置「固定值 / 字段」切换
9
9
  */
10
10
 
11
11
  import React from 'react';
12
- import { operatorRequiresValue, operatorRequiresValue2, operatorRequiresMultiValue } from "../constants/operators";
12
+ import { Segmented, Select, Space } from 'antd';
13
+ import { operatorRequiresValue, operatorRequiresValue2, operatorRequiresMultiValue, operatorSupportsValueField } from "../constants/operators";
13
14
  import SingleValueInput from "./SingleValueInput";
14
15
  import BetweenValueInput from "./BetweenValueInput";
15
16
  import MultiValueInput from "./MultiValueInput";
@@ -22,7 +23,12 @@ export var ValueInput = function ValueInput(_ref) {
22
23
  _ref$disabled = _ref.disabled,
23
24
  disabled = _ref$disabled === void 0 ? false : _ref$disabled,
24
25
  _ref$size = _ref.size,
25
- size = _ref$size === void 0 ? 'middle' : _ref$size;
26
+ size = _ref$size === void 0 ? 'middle' : _ref$size,
27
+ valueField = _ref.valueField,
28
+ onValueFieldChange = _ref.onValueFieldChange,
29
+ _ref$fields = _ref.fields,
30
+ fields = _ref$fields === void 0 ? [] : _ref$fields,
31
+ fieldName = _ref.fieldName;
26
32
  // 不需要值输入的操作符(IsNull/IsNotNull)
27
33
  if (!operatorRequiresValue(operator) && !operatorRequiresValue2(operator) && !operatorRequiresMultiValue(operator)) {
28
34
  return null;
@@ -58,9 +64,7 @@ export var ValueInput = function ValueInput(_ref) {
58
64
  size: size
59
65
  });
60
66
  }
61
-
62
- // 其他操作符:渲染单值输入
63
- return /*#__PURE__*/React.createElement(SingleValueInput, {
67
+ var singleValueInput = /*#__PURE__*/React.createElement(SingleValueInput, {
64
68
  value: value,
65
69
  onChange: function onChange(val) {
66
70
  return _onChange(val);
@@ -69,5 +73,52 @@ export var ValueInput = function ValueInput(_ref) {
69
73
  disabled: disabled,
70
74
  size: size
71
75
  });
76
+
77
+ // 其他操作符:渲染单值输入
78
+ if (!onValueFieldChange || !operatorSupportsValueField(operator)) {
79
+ return singleValueInput;
80
+ }
81
+
82
+ // 比较类操作符:可切换为与同类型的另一个字段比较。@author nokecy
83
+ var isFieldMode = valueField !== undefined;
84
+ return /*#__PURE__*/React.createElement(Space, {
85
+ size: 4
86
+ }, /*#__PURE__*/React.createElement(Segmented, {
87
+ size: size,
88
+ value: isFieldMode ? 'field' : 'value',
89
+ disabled: disabled,
90
+ options: [{
91
+ label: '固定值',
92
+ value: 'value'
93
+ }, {
94
+ label: '字段',
95
+ value: 'field'
96
+ }],
97
+ onChange: function onChange(mode) {
98
+ return onValueFieldChange(mode === 'field' ? '' : undefined);
99
+ }
100
+ }), isFieldMode ? /*#__PURE__*/React.createElement(Select, {
101
+ value: valueField || undefined,
102
+ onChange: function onChange(name) {
103
+ return onValueFieldChange(name);
104
+ },
105
+ placeholder: "\u8BF7\u9009\u62E9\u6BD4\u8F83\u5B57\u6BB5",
106
+ disabled: disabled,
107
+ size: size,
108
+ showSearch: true,
109
+ optionFilterProp: "label",
110
+ style: {
111
+ width: 200
112
+ },
113
+ options: fields.filter(function (field) {
114
+ return field.dataType === dataType && field.name !== fieldName;
115
+ }).map(function (field) {
116
+ return {
117
+ value: field.name,
118
+ label: field.displayName,
119
+ title: field.description
120
+ };
121
+ })
122
+ }) : singleValueInput);
72
123
  };
73
124
  export default ValueInput;
@@ -8,7 +8,7 @@
8
8
  * JSON 序列化属性名:
9
9
  * - fieldName (不是 FieldName)
10
10
  * - operator (不是 Operator)
11
- * - value, value2
11
+ * - value, value2, valueField
12
12
  * - logic, rules, groups
13
13
  */
14
14
  /**
@@ -78,6 +78,12 @@ export interface RuleDto {
78
78
  value?: any;
79
79
  /** 第二个值(用于 Between 操作符) */
80
80
  value2?: any;
81
+ /**
82
+ * 比较字段:与另一个字段的值比较,与 value 互斥,仅 6 个比较操作符可用。
83
+ * undefined 为固定值模式;空字符串表示已切到字段模式但尚未选择。
84
+ * @author nokecy
85
+ */
86
+ valueField?: string;
81
87
  }
82
88
  /**
83
89
  * 规则组 DTO(与后端保持一致)
@@ -143,6 +149,12 @@ export interface RuleBuilderConfig {
143
149
  maxNestingLevel?: number;
144
150
  /** 是否显示 JSON 预览 */
145
151
  showJsonPreview?: boolean;
152
+ /**
153
+ * 是否允许规则与另一个字段比较(valueField)。
154
+ * 需要后端规则引擎与调用方的格式转换都支持 valueField 才能开启,默认关闭。
155
+ * @author nokecy
156
+ */
157
+ allowFieldComparison?: boolean;
146
158
  /** 自定义验证器 */
147
159
  validator?: (rule: RuleGroupDto) => ValidationResult;
148
160
  }
@@ -8,7 +8,7 @@
8
8
  * JSON 序列化属性名:
9
9
  * - fieldName (不是 FieldName)
10
10
  * - operator (不是 Operator)
11
- * - value, value2
11
+ * - value, value2, valueField
12
12
  * - logic, rules, groups
13
13
  */
14
14
 
@@ -14,7 +14,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
14
14
  * 规则验证逻辑
15
15
  */
16
16
 
17
- import { operatorRequiresValue, operatorRequiresValue2, operatorRequiresMultiValue, getOperatorsByDataType } from "../constants/operators";
17
+ import { operatorRequiresValue, operatorRequiresValue2, operatorRequiresMultiValue, operatorSupportsValueField, getOperatorsByDataType } from "../constants/operators";
18
18
 
19
19
  /**
20
20
  * 验证规则组
@@ -107,6 +107,12 @@ export function validateRule(rule, fields) {
107
107
  });
108
108
  }
109
109
 
110
+ // 比较字段模式:值来自另一个字段,不再校验固定值。@author nokecy
111
+ if (rule.valueField !== undefined) {
112
+ errors.push.apply(errors, _toConsumableArray(validateValueField(rule, fields)));
113
+ return errors;
114
+ }
115
+
110
116
  // 4. 检查值是否为空(对于需要值的操作符)
111
117
  if (operatorRequiresValue(rule.operator)) {
112
118
  if (rule.value === undefined || rule.value === null || rule.value === '') {
@@ -189,6 +195,38 @@ export function validateRule(rule, fields) {
189
195
  return errors;
190
196
  }
191
197
 
198
+ /**
199
+ * 验证比较字段模式的规则
200
+ * @param rule 规则(valueField 已设置)
201
+ * @param fields 字段定义列表
202
+ * @returns 错误列表
203
+ * @author nokecy
204
+ */
205
+ function validateValueField(rule, fields) {
206
+ var errors = [];
207
+ var addError = function addError(message) {
208
+ return errors.push({
209
+ path: [],
210
+ message: message,
211
+ field: rule.fieldName
212
+ });
213
+ };
214
+ if (!operatorSupportsValueField(rule.operator)) {
215
+ addError('当前操作符不支持比较字段');
216
+ }
217
+ if (rule.value !== undefined && rule.value !== null && rule.value !== '') {
218
+ addError('固定值和比较字段只能设置一个');
219
+ }
220
+ if (!rule.valueField) {
221
+ addError('请选择比较字段');
222
+ } else if (!fields.some(function (f) {
223
+ return f.name === rule.valueField;
224
+ })) {
225
+ addError("\u6BD4\u8F83\u5B57\u6BB5 \"".concat(rule.valueField, "\" \u4E0D\u5B58\u5728"));
226
+ }
227
+ return errors;
228
+ }
229
+
192
230
  /**
193
231
  * 验证值的类型是否匹配
194
232
  * @param value 值