@bit-sun/business-component 4.2.0-alpha.22 → 4.2.0-alpha.24
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.
- package/dist/index.esm.js +30 -10
- package/dist/index.js +30 -10
- package/package.json +1 -1
- package/src/components/Functional/SearchSelect/index.md +109 -0
- package/src/components/Functional/SearchSelect/index.tsx +12 -2
- package/src/components/Solution/RuleComponent/README.md +187 -0
- package/src/components/Solution/RuleComponent/RuleField.md +63 -0
- package/src/components/Solution/RuleComponent/index.js +29 -12
- package/src/components/Solution/RuleSetter/README.md +97 -0
package/dist/index.esm.js
CHANGED
|
@@ -5339,8 +5339,7 @@ var SearchSelect = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
5339
5339
|
searchStartLength = _ref.searchStartLength,
|
|
5340
5340
|
_ref$isQuery = _ref.isQuery,
|
|
5341
5341
|
isQuery = _ref$isQuery === void 0 ? false : _ref$isQuery,
|
|
5342
|
-
_ref$requestType = _ref.requestType
|
|
5343
|
-
requestType = _ref$requestType === void 0 ? 'get' : _ref$requestType;
|
|
5342
|
+
_ref$requestType = _ref.requestType;
|
|
5344
5343
|
var requestConfig = _objectSpread2({
|
|
5345
5344
|
url: url,
|
|
5346
5345
|
method: method,
|
|
@@ -5627,9 +5626,16 @@ var SearchSelect = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
5627
5626
|
var getRequest;
|
|
5628
5627
|
var methodName = method === null || method === void 0 ? void 0 : (_method$toLocaleLower = method.toLocaleLowerCase) === null || _method$toLocaleLower === void 0 ? void 0 : _method$toLocaleLower.call(method);
|
|
5629
5628
|
if (['post', 'patch', 'put'].includes(methodName)) {
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5629
|
+
var bodyData = convertBodyParams(queryParams);
|
|
5630
|
+
var urlStr = convertUrlQueryParams(queryParams);
|
|
5631
|
+
// Fix: support sending params in body
|
|
5632
|
+
if (requestConfig.isBodyRequest) {
|
|
5633
|
+
if (!bodyData) {
|
|
5634
|
+
bodyData = convertQueryParams(queryParams);
|
|
5635
|
+
}
|
|
5636
|
+
urlStr = '';
|
|
5637
|
+
}
|
|
5638
|
+
getRequest = requestUtil[methodName]("".concat(url).concat(urlStr), bodyData, {
|
|
5633
5639
|
headers: _objectSpread2({}, extralHeaders)
|
|
5634
5640
|
});
|
|
5635
5641
|
} else {
|
|
@@ -39202,12 +39208,24 @@ var RuleObjectComponent = /*#__PURE__*/function (_Component) {
|
|
|
39202
39208
|
padding: '10px',
|
|
39203
39209
|
borderRadius: '4px'
|
|
39204
39210
|
}
|
|
39205
|
-
}, /*#__PURE__*/React$1.createElement(
|
|
39211
|
+
}, /*#__PURE__*/React$1.createElement(Select, {
|
|
39212
|
+
disabled: disabled,
|
|
39206
39213
|
style: {
|
|
39207
|
-
|
|
39208
|
-
|
|
39209
|
-
}
|
|
39210
|
-
|
|
39214
|
+
width: 150,
|
|
39215
|
+
marginRight: 10
|
|
39216
|
+
},
|
|
39217
|
+
placeholder: "\u8BF7\u9009\u62E9",
|
|
39218
|
+
value: String(itemDetail.reqConditionData.reqParamType || '10'),
|
|
39219
|
+
onChange: function onChange(val) {
|
|
39220
|
+
return _this.handleReqDataChange(itemDetail, 'reqParamType', val);
|
|
39221
|
+
}
|
|
39222
|
+
}, /*#__PURE__*/React$1.createElement(Select.Option, {
|
|
39223
|
+
value: "10"
|
|
39224
|
+
}, "\u8BF7\u6C42\u53C2\u6570\u540D\u79F0"), /*#__PURE__*/React$1.createElement(Select.Option, {
|
|
39225
|
+
value: "20"
|
|
39226
|
+
}, "\u8BF7\u6C42\u5934\u53C2\u6570\u540D\u79F0"), /*#__PURE__*/React$1.createElement(Select.Option, {
|
|
39227
|
+
value: "40"
|
|
39228
|
+
}, "\u6E90\u8BF7\u6C42\u5730\u5740")), String(itemDetail.reqConditionData.reqParamType || '10') !== '40' && /*#__PURE__*/React$1.createElement(Input, {
|
|
39211
39229
|
disabled: disabled,
|
|
39212
39230
|
style: {
|
|
39213
39231
|
width: 150,
|
|
@@ -39763,6 +39781,8 @@ var RuleObjectComponent = /*#__PURE__*/function (_Component) {
|
|
|
39763
39781
|
if (valueNames) {
|
|
39764
39782
|
itemDetail.reqConditionData.paramNames = valueNames;
|
|
39765
39783
|
}
|
|
39784
|
+
} else if (field === 'reqParamType') {
|
|
39785
|
+
itemDetail.reqConditionData.reqParamType = value;
|
|
39766
39786
|
}
|
|
39767
39787
|
_this.setState({
|
|
39768
39788
|
ruleClassData: ruleClassData
|
package/dist/index.js
CHANGED
|
@@ -5362,8 +5362,7 @@ var SearchSelect = /*#__PURE__*/React$1.forwardRef(function (props, ref) {
|
|
|
5362
5362
|
searchStartLength = _ref.searchStartLength,
|
|
5363
5363
|
_ref$isQuery = _ref.isQuery,
|
|
5364
5364
|
isQuery = _ref$isQuery === void 0 ? false : _ref$isQuery,
|
|
5365
|
-
_ref$requestType = _ref.requestType
|
|
5366
|
-
requestType = _ref$requestType === void 0 ? 'get' : _ref$requestType;
|
|
5365
|
+
_ref$requestType = _ref.requestType;
|
|
5367
5366
|
var requestConfig = _objectSpread2({
|
|
5368
5367
|
url: url,
|
|
5369
5368
|
method: method,
|
|
@@ -5650,9 +5649,16 @@ var SearchSelect = /*#__PURE__*/React$1.forwardRef(function (props, ref) {
|
|
|
5650
5649
|
var getRequest;
|
|
5651
5650
|
var methodName = method === null || method === void 0 ? void 0 : (_method$toLocaleLower = method.toLocaleLowerCase) === null || _method$toLocaleLower === void 0 ? void 0 : _method$toLocaleLower.call(method);
|
|
5652
5651
|
if (['post', 'patch', 'put'].includes(methodName)) {
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5652
|
+
var bodyData = convertBodyParams(queryParams);
|
|
5653
|
+
var urlStr = convertUrlQueryParams(queryParams);
|
|
5654
|
+
// Fix: support sending params in body
|
|
5655
|
+
if (requestConfig.isBodyRequest) {
|
|
5656
|
+
if (!bodyData) {
|
|
5657
|
+
bodyData = convertQueryParams(queryParams);
|
|
5658
|
+
}
|
|
5659
|
+
urlStr = '';
|
|
5660
|
+
}
|
|
5661
|
+
getRequest = requestUtil[methodName]("".concat(url).concat(urlStr), bodyData, {
|
|
5656
5662
|
headers: _objectSpread2({}, extralHeaders)
|
|
5657
5663
|
});
|
|
5658
5664
|
} else {
|
|
@@ -39225,12 +39231,24 @@ var RuleObjectComponent = /*#__PURE__*/function (_Component) {
|
|
|
39225
39231
|
padding: '10px',
|
|
39226
39232
|
borderRadius: '4px'
|
|
39227
39233
|
}
|
|
39228
|
-
}, /*#__PURE__*/React__default['default'].createElement(
|
|
39234
|
+
}, /*#__PURE__*/React__default['default'].createElement(antd.Select, {
|
|
39235
|
+
disabled: disabled,
|
|
39229
39236
|
style: {
|
|
39230
|
-
|
|
39231
|
-
|
|
39232
|
-
}
|
|
39233
|
-
|
|
39237
|
+
width: 150,
|
|
39238
|
+
marginRight: 10
|
|
39239
|
+
},
|
|
39240
|
+
placeholder: "\u8BF7\u9009\u62E9",
|
|
39241
|
+
value: String(itemDetail.reqConditionData.reqParamType || '10'),
|
|
39242
|
+
onChange: function onChange(val) {
|
|
39243
|
+
return _this.handleReqDataChange(itemDetail, 'reqParamType', val);
|
|
39244
|
+
}
|
|
39245
|
+
}, /*#__PURE__*/React__default['default'].createElement(antd.Select.Option, {
|
|
39246
|
+
value: "10"
|
|
39247
|
+
}, "\u8BF7\u6C42\u53C2\u6570\u540D\u79F0"), /*#__PURE__*/React__default['default'].createElement(antd.Select.Option, {
|
|
39248
|
+
value: "20"
|
|
39249
|
+
}, "\u8BF7\u6C42\u5934\u53C2\u6570\u540D\u79F0"), /*#__PURE__*/React__default['default'].createElement(antd.Select.Option, {
|
|
39250
|
+
value: "40"
|
|
39251
|
+
}, "\u6E90\u8BF7\u6C42\u5730\u5740")), String(itemDetail.reqConditionData.reqParamType || '10') !== '40' && /*#__PURE__*/React__default['default'].createElement(antd.Input, {
|
|
39234
39252
|
disabled: disabled,
|
|
39235
39253
|
style: {
|
|
39236
39254
|
width: 150,
|
|
@@ -39786,6 +39804,8 @@ var RuleObjectComponent = /*#__PURE__*/function (_Component) {
|
|
|
39786
39804
|
if (valueNames) {
|
|
39787
39805
|
itemDetail.reqConditionData.paramNames = valueNames;
|
|
39788
39806
|
}
|
|
39807
|
+
} else if (field === 'reqParamType') {
|
|
39808
|
+
itemDetail.reqConditionData.reqParamType = value;
|
|
39789
39809
|
}
|
|
39790
39810
|
_this.setState({
|
|
39791
39811
|
ruleClassData: ruleClassData
|
package/package.json
CHANGED
|
@@ -138,4 +138,113 @@ export default () => {
|
|
|
138
138
|
};
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
+
## POST Body Request Demo
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import React, { useState } from 'react';
|
|
145
|
+
import { Button } from 'antd';
|
|
146
|
+
import { SearchSelect } from '../../../index';
|
|
147
|
+
|
|
148
|
+
export default () => {
|
|
149
|
+
const [tableSource, setTableSource] = useState([]);
|
|
150
|
+
const userInfo = { employeeResVo: { id: 'mock-id' } }; // Mock userInfo
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<SearchSelect
|
|
154
|
+
selectBusinessType="salesOrder" // Custom key
|
|
155
|
+
modalTableProps={{
|
|
156
|
+
modalTableTitle: '选择销售单明细',
|
|
157
|
+
tableSearchForm: [
|
|
158
|
+
{
|
|
159
|
+
name: 'orderNo',
|
|
160
|
+
label: '单据编号',
|
|
161
|
+
item: {
|
|
162
|
+
type: 'input'
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'orderDate',
|
|
167
|
+
label: '单据日期',
|
|
168
|
+
item: {
|
|
169
|
+
type: 'rangepicker'
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'saleOrgCode',
|
|
174
|
+
label: '销售组织',
|
|
175
|
+
item: {
|
|
176
|
+
type: 'select',
|
|
177
|
+
props: {
|
|
178
|
+
showSearch: true,
|
|
179
|
+
optionFilterProp: 'children'
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
remoteSource: {
|
|
183
|
+
url: `/user/orgViewNode/listNoPage?qp-orgViewCode-eq=sales-organizational-view&qp-employeeId-eq=${userInfo?.employeeResVo?.id}`,
|
|
184
|
+
method: 'GET',
|
|
185
|
+
converter: ({ data }: { data: any }) => {
|
|
186
|
+
return (
|
|
187
|
+
(data &&
|
|
188
|
+
Array.isArray(data) &&
|
|
189
|
+
data.length &&
|
|
190
|
+
data.map((v: any) => ({ text: v.name, value: v.code }))) ||
|
|
191
|
+
[]
|
|
192
|
+
);
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: 'customerCode',
|
|
198
|
+
label: '客户',
|
|
199
|
+
item: {
|
|
200
|
+
type: 'bs-customer2SearchSelect',
|
|
201
|
+
props: {
|
|
202
|
+
selectBusinessType: 'customer2',
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
tableColumns: [
|
|
208
|
+
{ title: '单据编号', key: 'orderNo' },
|
|
209
|
+
{ title: '单据日期', key: 'orderDate' },
|
|
210
|
+
{ title: '销售组织', key: 'saleDepartmentName' },
|
|
211
|
+
{ title: '客户', key: 'customerName' },
|
|
212
|
+
{ title: 'SKU', key: 'skuCode' },
|
|
213
|
+
{ title: '商品名称', key: 'spuName' },
|
|
214
|
+
{ title: '数量', key: 'planQuantity' },
|
|
215
|
+
{ title: '销售金额', key: 'saleTaxedAmount' },
|
|
216
|
+
],
|
|
217
|
+
}}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
fieldComponent={<Button type="primary">新增</Button>}
|
|
221
|
+
selectProps={{
|
|
222
|
+
mode: 'multiple', // Allow multiple selection
|
|
223
|
+
}}
|
|
224
|
+
onSaveCallback={(rows: any) => {
|
|
225
|
+
if (!rows || rows.length === 0) return;
|
|
226
|
+
const newDetails = rows.map((item: any) => ({
|
|
227
|
+
key: Date.now() + Math.random(),
|
|
228
|
+
saleOrderNo: item.orderNo,
|
|
229
|
+
saleOrderDetailLineNo: item.lineNo,
|
|
230
|
+
skuCode: item.skuCode,
|
|
231
|
+
quantity: item.planQuantity,
|
|
232
|
+
saleAmount: item.saleTaxedAmount,
|
|
233
|
+
subsidyAmount: 0,
|
|
234
|
+
}));
|
|
235
|
+
setTableSource([...tableSource, ...newDetails]);
|
|
236
|
+
return Promise.resolve();
|
|
237
|
+
}}
|
|
238
|
+
requestConfig={{
|
|
239
|
+
url: '/drp-ops/new/tradeSubOrder/pageListAndDetailByData',
|
|
240
|
+
method: 'post',
|
|
241
|
+
isBodyRequest: true, // Enable body params for POST
|
|
242
|
+
mappingValueField: 'detailId', // Unique ID for selection
|
|
243
|
+
mappingTextField: 'orderNo', // Just for display if needed
|
|
244
|
+
}}
|
|
245
|
+
/>
|
|
246
|
+
);
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
141
250
|
More skills for writing demo: https://d.umijs.org/guide/demo-principle
|
|
@@ -7,7 +7,7 @@ import request from '@/utils/request';
|
|
|
7
7
|
import _, { escapeRegExp, isNil, values, cloneDeep, isEmpty } from "lodash"
|
|
8
8
|
import './index.less';
|
|
9
9
|
import { BusinessSearchSelect, QueryMutipleInput, QueryMutipleSearchSelect } from '@/index';
|
|
10
|
-
import { handleSourceName, getFormRowInfo, hasMoreQueryFields, defaultVisibleFieldsCount, getRealStr, getTableHeigth, getCurrentSRKs, getRenderSource, handleParams, convertUrlQueryParams, convertBodyParams, formatSelectedValue, convertResData, makeUniqueValue, handleSelectOptionsShowValue, LightHeightOption, maxTagPlaceholder, getShowStr, handleTableColumns } from './utils';
|
|
10
|
+
import { handleSourceName, getFormRowInfo, hasMoreQueryFields, defaultVisibleFieldsCount, getRealStr, getTableHeigth, getCurrentSRKs, getRenderSource, handleParams, convertUrlQueryParams, convertBodyParams, formatSelectedValue, convertResData, makeUniqueValue, handleSelectOptionsShowValue, LightHeightOption, maxTagPlaceholder, getShowStr, handleTableColumns, convertQueryParams } from './utils';
|
|
11
11
|
import { judgeIsRequestError } from '@/utils/requestUtils';
|
|
12
12
|
import zhankaitiaojian from '../../../assets/zhankaitiaojian-icon.svg';
|
|
13
13
|
import PropertySelector from '@/components/Business/PropertyModal';
|
|
@@ -242,7 +242,17 @@ const SearchSelect = forwardRef((props: any, ref: any) => {
|
|
|
242
242
|
let getRequest;
|
|
243
243
|
const methodName = method?.toLocaleLowerCase?.();
|
|
244
244
|
if(['post','patch','put'].includes(methodName)) {
|
|
245
|
-
|
|
245
|
+
let bodyData = convertBodyParams(queryParams);
|
|
246
|
+
let urlStr = convertUrlQueryParams(queryParams);
|
|
247
|
+
|
|
248
|
+
// Fix: support sending params in body
|
|
249
|
+
if(requestConfig.isBodyRequest) {
|
|
250
|
+
if(!bodyData) {
|
|
251
|
+
bodyData = convertQueryParams(queryParams);
|
|
252
|
+
}
|
|
253
|
+
urlStr = '';
|
|
254
|
+
}
|
|
255
|
+
getRequest = request[methodName](`${url}${urlStr}`,bodyData, { headers: { ...extralHeaders }})
|
|
246
256
|
} else {
|
|
247
257
|
getRequest = request.get( `${url}${convertUrlQueryParams(queryParams)}`,{headers: { ...extralHeaders }})
|
|
248
258
|
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# RuleObjectComponent 规则组件
|
|
2
|
+
|
|
3
|
+
## 简介
|
|
4
|
+
`RuleObjectComponent` 是一个功能强大的规则构建器组件,支持可视化的条件组合(并且/或者逻辑嵌套)、动态参数插入、执行动作配置以及返回值配置。它广泛应用于需要灵活定义业务规则的场景。
|
|
5
|
+
|
|
6
|
+
## 组件路径
|
|
7
|
+
`src/components/Solution/RuleComponent/index.js`
|
|
8
|
+
|
|
9
|
+
## Props 属性说明
|
|
10
|
+
|
|
11
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
12
|
+
|Ref | --- | --- | --- |
|
|
13
|
+
| regularDataList | `Array` | 是 | 规则左侧“对象”选择树的数据源。 |
|
|
14
|
+
| operationList | `Array` | 是 | 规则中间“操作符”下拉列表的数据源。 |
|
|
15
|
+
| ruleClassData | `Array` | 是 | 规则组件的核心数据模型,用于回显和存储规则配置。 |
|
|
16
|
+
| callBack | `Function` | 是 | 数据变更时的回调函数,返回最新的 `ruleClassData`。 |
|
|
17
|
+
| systemVariableList | `Array` | 否 | “插入参数”功能的数据源,允许用户选择系统变量而非固定值。 |
|
|
18
|
+
| initialThresholdQuery | `Object` | 否 | 用于获取规则值域(右侧输入框/选择框)的初始查询参数。 |
|
|
19
|
+
| ruleGroupInfo | `Object` | 否 | 规则组信息,用于规则组实例场景。 |
|
|
20
|
+
| ruleTypeData | `Array` | 否 | “动作”配置的数据源。 |
|
|
21
|
+
| ruleReturnConfig | `Array` | 否 | “返回值”配置的数据源。 |
|
|
22
|
+
| disabled | `Boolean` | 否 | 是否禁用(只读模式)。 |
|
|
23
|
+
| canDelete | `Boolean` | 否 | 是否显示删除规则按钮。 |
|
|
24
|
+
| onlyOneRule | `Boolean` | 否 | 是否限制为单条规则(不显示新增规则按钮)。 |
|
|
25
|
+
| onlyCondition | `Boolean` | 否 | 是否仅展示条件部分(隐藏动作和返回值)。 |
|
|
26
|
+
| onlyAction | `Boolean` | 否 | 是否仅展示动作部分。 |
|
|
27
|
+
| needShowInsertSQL | `Boolean` | 否 | 是否显示“插入SQL”功能按钮。 |
|
|
28
|
+
| headerButtonComponentFun | `Function` | 否 | 自定义头部按钮渲染函数。 |
|
|
29
|
+
|
|
30
|
+
## 数据结构示例
|
|
31
|
+
|
|
32
|
+
### ruleClassData 结构
|
|
33
|
+
```json
|
|
34
|
+
[
|
|
35
|
+
{
|
|
36
|
+
"ruleName": "规则1",
|
|
37
|
+
"subExpression": [
|
|
38
|
+
{
|
|
39
|
+
"operationType": "logic", // logic 或 relation
|
|
40
|
+
"operationCode": "and", // logic时为 and/or
|
|
41
|
+
"subExpression": [ ... ] // 嵌套子条件
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"operationType": "relation",
|
|
45
|
+
"elementId": "...", // 左侧对象ID
|
|
46
|
+
"operationCode": "...", // 操作符
|
|
47
|
+
"params": ["..."], // 右侧值
|
|
48
|
+
// 新增参数条件控制
|
|
49
|
+
"isReqCondition": true,
|
|
50
|
+
"reqConditionData": {
|
|
51
|
+
"reqParamName": "param1",
|
|
52
|
+
"dataTypeCode": "21",
|
|
53
|
+
"operationCode": "eq",
|
|
54
|
+
"params": ["value"]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"extraInfo": {
|
|
59
|
+
"execute": [], // 动作
|
|
60
|
+
"response": [] // 返回值
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 功能特性
|
|
67
|
+
1. **多层级逻辑嵌套**:支持无限层级的“并且/或者”逻辑组合。
|
|
68
|
+
2. **动态表单渲染**:根据选择的对象属性类型(`dataTypeCode`),自动渲染对应的输入组件(文本框、日期选择、业务选择器等)。
|
|
69
|
+
3. **参数插入**:支持将系统变量作为条件值。
|
|
70
|
+
4. **参数条件控制**:支持为特定条件配置请求参数名称、类型及校验规则。
|
|
71
|
+
5. **动作与返回值**:支持配置规则命中后的执行动作及返回值。
|
|
72
|
+
|
|
73
|
+
## 代码演示
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import React, { useState } from 'react';
|
|
77
|
+
import { RuleComponent } from '../../../index';
|
|
78
|
+
|
|
79
|
+
export default () => {
|
|
80
|
+
const [ruleClassData, setRuleClassData] = useState([]);
|
|
81
|
+
const [disabled, setDisabled] = useState(false);
|
|
82
|
+
|
|
83
|
+
// 模拟规则对象数据源
|
|
84
|
+
const regularDataList = [
|
|
85
|
+
{
|
|
86
|
+
id: 'user_info',
|
|
87
|
+
name: '用户信息',
|
|
88
|
+
code: 'user',
|
|
89
|
+
valueType: 'object',
|
|
90
|
+
propertyList: [
|
|
91
|
+
{ id: 'age', name: '年龄', code: 'age', valueType: '22', inputType: 11, choiceType: 10, },
|
|
92
|
+
{ id: 'name', name: '姓名', code: 'name', valueType: '21', inputType: 11, choiceType: 10, },
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: 'order_info',
|
|
97
|
+
name: '订单信息',
|
|
98
|
+
code: 'order',
|
|
99
|
+
valueType: 'object',
|
|
100
|
+
propertyList: [
|
|
101
|
+
{ id: 'amount', name: '金额', code: 'amount', valueType: '22', inputType: 11, choiceType: 10, },
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
// 模拟操作符数据源
|
|
107
|
+
const operationList = [
|
|
108
|
+
{
|
|
109
|
+
code: '21', // 字符串
|
|
110
|
+
operationList: [
|
|
111
|
+
{ code: 'eq', name: '等于' },
|
|
112
|
+
{ code: 'cn', name: '包含' },
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
code: '22', // 数值
|
|
117
|
+
operationList: [
|
|
118
|
+
{ code: 'eq', name: '等于' },
|
|
119
|
+
{ code: 'gt', name: '大于' },
|
|
120
|
+
{ code: 'lt', name: '小于' },
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
// 模拟系统变量
|
|
126
|
+
const systemVariableList = [
|
|
127
|
+
{ code: 'sys_uid', name: '当前用户ID' },
|
|
128
|
+
{ code: 'sys_time', name: '当前时间' },
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
const handleSave = () => {
|
|
132
|
+
console.log('保存规则数据:', JSON.stringify(ruleClassData, null, 2));
|
|
133
|
+
alert('规则数据已输出到控制台,请查看!');
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<div style={{ background: '#f0f2f5', padding: 20, width: '1200px' }}>
|
|
138
|
+
<div style={{ marginBottom: 16, textAlign: 'right' }}>
|
|
139
|
+
<button
|
|
140
|
+
onClick={() => setDisabled(!disabled)}
|
|
141
|
+
style={{
|
|
142
|
+
backgroundColor: '#faad14',
|
|
143
|
+
color: '#fff',
|
|
144
|
+
border: 'none',
|
|
145
|
+
padding: '6px 15px',
|
|
146
|
+
borderRadius: '2px',
|
|
147
|
+
cursor: 'pointer',
|
|
148
|
+
marginRight: '10px'
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
{disabled ? '启用编辑' : '禁用编辑'}
|
|
152
|
+
</button>
|
|
153
|
+
<button
|
|
154
|
+
onClick={handleSave}
|
|
155
|
+
style={{
|
|
156
|
+
backgroundColor: '#1890ff',
|
|
157
|
+
color: '#fff',
|
|
158
|
+
border: 'none',
|
|
159
|
+
padding: '6px 15px',
|
|
160
|
+
borderRadius: '2px',
|
|
161
|
+
cursor: 'pointer'
|
|
162
|
+
}}
|
|
163
|
+
>
|
|
164
|
+
保存规则
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
<RuleComponent
|
|
168
|
+
regularDataList={regularDataList}
|
|
169
|
+
operationList={operationList}
|
|
170
|
+
ruleClassData={ruleClassData}
|
|
171
|
+
needShowInsertSQL={true}
|
|
172
|
+
needShowReqCondition={true}
|
|
173
|
+
systemVariableList={systemVariableList}
|
|
174
|
+
disabled={disabled}
|
|
175
|
+
callBack={(newData) => {
|
|
176
|
+
console.log('Rule Changed:', newData);
|
|
177
|
+
setRuleClassData([...newData]);
|
|
178
|
+
}}
|
|
179
|
+
/>
|
|
180
|
+
<div style={{ marginTop: 20 }}>
|
|
181
|
+
<h4>当前规则数据:</h4>
|
|
182
|
+
<pre>{JSON.stringify(ruleClassData, null, 2)}</pre>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
};
|
|
187
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# RuleField 规则字段组件
|
|
2
|
+
|
|
3
|
+
## 简介
|
|
4
|
+
`RuleField` 是 `RuleObjectComponent` 内部使用的核心子组件,主要负责根据规则配置的**数据类型**和**操作符**,动态渲染出合适的输入控件(如输入框、下拉框、日期选择器、业务选择器等)。
|
|
5
|
+
|
|
6
|
+
## 组件路径
|
|
7
|
+
`src/components/Solution/RuleComponent/ruleFiled.js`
|
|
8
|
+
|
|
9
|
+
## Props 属性说明
|
|
10
|
+
|
|
11
|
+
| 属性名 | 类型 | 说明 |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| selectOperation | `String` | 当前选中的操作符编码(如 `eq`, `in`, `be` 等)。 |
|
|
14
|
+
| dataTypeCode | `String` | 数据类型编码(21:字符串, 22:数值, 41:日期, 32:日期时间等)。 |
|
|
15
|
+
| dataChoiceBusinessType | `String`/`Number` | 业务数据选择类型(如 110:物理仓, 120:逻辑仓, 250:客户 等),用于决定渲染哪种业务选择器。 |
|
|
16
|
+
| dataInputBusinessType | `Number` | 输入交互类型(11:单选, 12:多选)。 |
|
|
17
|
+
| values | `Array` | 当前输入的值数组。 |
|
|
18
|
+
| valueNames | `Array` | 当前输入值的名称数组(用于回显)。 |
|
|
19
|
+
| callback | `Function` | 值发生变化时的回调,签名:`(newValues, newValueNames) => void`。 |
|
|
20
|
+
| disabled | `Boolean` | 是否禁用。 |
|
|
21
|
+
| customerWidth | `String` | 自定义控件宽度。 |
|
|
22
|
+
| queryIdentify | `String` | 字典或枚举的标识符,用于获取下拉选项数据。 |
|
|
23
|
+
| queryIdentifyType | `String` | 标识符类型(`dictCodeIdentify`, `dynamicDictCodeIdentify` 等)。 |
|
|
24
|
+
| initialThresholdQuery | `Object` | 初始查询参数。 |
|
|
25
|
+
| propertyCode | `String` | 属性编码。 |
|
|
26
|
+
| others | `Object` | 其他扩展配置,如 `customSelectorConfig`。 |
|
|
27
|
+
|
|
28
|
+
## 支持的控件类型
|
|
29
|
+
|
|
30
|
+
组件根据 `dataTypeCode` 和 `dataChoiceBusinessType` 自动匹配以下控件:
|
|
31
|
+
|
|
32
|
+
1. **基础控件**:
|
|
33
|
+
* Input (文本/数值)
|
|
34
|
+
* DatePicker / RangePicker (日期/时间)
|
|
35
|
+
* Select (枚举/字典下拉)
|
|
36
|
+
|
|
37
|
+
2. **区间控件**:
|
|
38
|
+
* 当操作符为区间类型(如 `be`, `bed`)时,自动渲染两个输入控件及中间的 `~` 符号。
|
|
39
|
+
|
|
40
|
+
3. **业务选择器**:
|
|
41
|
+
* 物理仓 (`physicalWarehouse`)
|
|
42
|
+
* 逻辑仓 (`realWarehouse`)
|
|
43
|
+
* 虚拟仓 (`virtualWarehouse`)
|
|
44
|
+
* 渠道仓 (`channelWarehouse`)
|
|
45
|
+
* 商品SPU/SKU
|
|
46
|
+
* 省市区级联 (`BsCascader`)
|
|
47
|
+
* 行政/采购/销售/库存/结算组织 (`BusinessTreeSearchSelect`)
|
|
48
|
+
* 供应商/客户/店铺/员工 (`BusinessSearchSelect`)
|
|
49
|
+
* 品牌/类目
|
|
50
|
+
* 自定义选择器 (`CustomSelector`)
|
|
51
|
+
|
|
52
|
+
## 使用示例
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
<RuleField
|
|
56
|
+
selectOperation="eq"
|
|
57
|
+
dataTypeCode="21"
|
|
58
|
+
values={['some value']}
|
|
59
|
+
valueNames={['some value']}
|
|
60
|
+
callback={(vals, names) => console.log(vals, names)}
|
|
61
|
+
disabled={false}
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
@@ -1143,21 +1143,36 @@ class RuleObjectComponent extends Component {
|
|
|
1143
1143
|
borderRadius: '4px',
|
|
1144
1144
|
}}
|
|
1145
1145
|
>
|
|
1146
|
-
<
|
|
1147
|
-
请求参数名称:
|
|
1148
|
-
</span>
|
|
1149
|
-
<Input
|
|
1146
|
+
<Select
|
|
1150
1147
|
disabled={disabled}
|
|
1151
1148
|
style={{ width: 150, marginRight: 10 }}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
)
|
|
1149
|
+
placeholder="请选择"
|
|
1150
|
+
value={String(
|
|
1151
|
+
itemDetail.reqConditionData.reqParamType || '10',
|
|
1152
|
+
)}
|
|
1153
|
+
onChange={(val) =>
|
|
1154
|
+
this.handleReqDataChange(itemDetail, 'reqParamType', val)
|
|
1159
1155
|
}
|
|
1160
|
-
|
|
1156
|
+
>
|
|
1157
|
+
<Select.Option value="10">请求参数名称</Select.Option>
|
|
1158
|
+
<Select.Option value="20">请求头参数名称</Select.Option>
|
|
1159
|
+
<Select.Option value="40">源请求地址</Select.Option>
|
|
1160
|
+
</Select>
|
|
1161
|
+
{String(itemDetail.reqConditionData.reqParamType || '10') !==
|
|
1162
|
+
'40' && (
|
|
1163
|
+
<Input
|
|
1164
|
+
disabled={disabled}
|
|
1165
|
+
style={{ width: 150, marginRight: 10 }}
|
|
1166
|
+
value={itemDetail.reqConditionData.reqParamName}
|
|
1167
|
+
onChange={(e) =>
|
|
1168
|
+
this.handleReqDataChange(
|
|
1169
|
+
itemDetail,
|
|
1170
|
+
'reqParamName',
|
|
1171
|
+
e.target.value,
|
|
1172
|
+
)
|
|
1173
|
+
}
|
|
1174
|
+
/>
|
|
1175
|
+
)}
|
|
1161
1176
|
|
|
1162
1177
|
<span style={{ marginRight: 8, flexShrink: 0 }}>类型:</span>
|
|
1163
1178
|
<Select
|
|
@@ -1843,6 +1858,8 @@ class RuleObjectComponent extends Component {
|
|
|
1843
1858
|
if (valueNames) {
|
|
1844
1859
|
itemDetail.reqConditionData.paramNames = valueNames;
|
|
1845
1860
|
}
|
|
1861
|
+
} else if (field === 'reqParamType') {
|
|
1862
|
+
itemDetail.reqConditionData.reqParamType = value;
|
|
1846
1863
|
}
|
|
1847
1864
|
|
|
1848
1865
|
this.setState(
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# RuleSetter 规则设置器组件
|
|
2
|
+
|
|
3
|
+
## 简介
|
|
4
|
+
`RuleSetter` 是一个封装了完整规则编辑逻辑的高级业务组件。它内部集成了 `RuleObjectComponent`,并内置了规则模板详情查询、规则对象树加载、操作符获取、规则实例数据回显以及规则保存等全套数据交互逻辑。
|
|
5
|
+
|
|
6
|
+
开发者只需提供规则模板 ID (`id`) 和业务标识 (`extStrField01`),即可快速在页面中引入一个功能完备的规则编辑器。
|
|
7
|
+
|
|
8
|
+
## 组件路径
|
|
9
|
+
`src/components/Solution/RuleSetter/index.tsx`
|
|
10
|
+
|
|
11
|
+
## Props 属性说明
|
|
12
|
+
|
|
13
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
14
|
+
|Ref | --- | --- | --- |
|
|
15
|
+
| id / sceneId | `String` | 是 | 规则模板 ID,用于加载规则元数据(对象树、操作符等)。 |
|
|
16
|
+
| extStrField01 | `String` | 否 | 业务关键字段(如业务单据ID、租户ID等),用于区分同一模板下的不同业务实例。 |
|
|
17
|
+
| name | `String` | 否 | 规则实例名称。 |
|
|
18
|
+
| type | `String` | 否 | 组件模式。`instance` 表示规则实例模式(加载并保存具体的业务规则);为空则通常用于模板设计模式。 |
|
|
19
|
+
| saveUrl | `String` | 否 | 自定义保存接口地址。默认为 `/basic/ruleDetail/addAndUpdate`。 |
|
|
20
|
+
| customerValidator | `Function` | 否 | 自定义校验函数。`(ruleResultList, ruleTypeData) => boolean`。 |
|
|
21
|
+
| parseCustomParams | `Function` | 否 | 自定义保存参数处理函数。`(params) => newParams`。 |
|
|
22
|
+
| RuleObjectComponentProps | `Object` | 否 | 透传给底层 `RuleObjectComponent` 的属性对象。可用于开启特定功能(如插入SQL)。 |
|
|
23
|
+
|
|
24
|
+
## 开启“插入 SQL”功能
|
|
25
|
+
|
|
26
|
+
通过 `RuleObjectComponentProps` 属性,可以将 `needShowInsertSQL` 参数传递给底层的规则组件,从而开启“插入 SQL”功能。
|
|
27
|
+
|
|
28
|
+
开启后,在每条规则条件的右侧会新增一个“插入 SQL”按钮,允许用户直接输入 SQL 片段作为条件值。
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
<RuleSetter
|
|
32
|
+
id="template_123"
|
|
33
|
+
type="instance"
|
|
34
|
+
RuleObjectComponentProps={{
|
|
35
|
+
needShowInsertSQL: true
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 代码演示
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import React, { useRef } from 'react';
|
|
44
|
+
import { Button, message } from 'antd';
|
|
45
|
+
import { RuleSetter } from '../../../index';
|
|
46
|
+
|
|
47
|
+
export default () => {
|
|
48
|
+
const ruleSetterRef = useRef();
|
|
49
|
+
|
|
50
|
+
const handleSave = () => {
|
|
51
|
+
if (ruleSetterRef.current) {
|
|
52
|
+
// 调用组件内部的保存方法
|
|
53
|
+
ruleSetterRef.current.handleSave()
|
|
54
|
+
.then(() => {
|
|
55
|
+
message.success('规则保存成功');
|
|
56
|
+
})
|
|
57
|
+
.catch((err) => {
|
|
58
|
+
console.error('保存失败', err);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div style={{ background: '#f5f5f5', padding: 20 }}>
|
|
65
|
+
<div style={{ marginBottom: 16, textAlign: 'right' }}>
|
|
66
|
+
<Button type="primary" onClick={handleSave}>
|
|
67
|
+
保存规则
|
|
68
|
+
</Button>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<RuleSetter
|
|
72
|
+
ref={ruleSetterRef}
|
|
73
|
+
id="100000132" // 示例模板ID,请替换为实际存在的ID
|
|
74
|
+
type="instance"
|
|
75
|
+
extStrField01="business_order_001" // 示例业务ID
|
|
76
|
+
name="订单审核规则"
|
|
77
|
+
// 开启插入SQL功能
|
|
78
|
+
RuleObjectComponentProps={{
|
|
79
|
+
needShowInsertSQL: true,
|
|
80
|
+
needShowReqCondition: true,
|
|
81
|
+
// 也可以传递其他 RuleObjectComponent 支持的属性
|
|
82
|
+
onlyCondition: false
|
|
83
|
+
}}
|
|
84
|
+
saveUrl="/api/custom/save/rule" // 可选:自定义保存接口
|
|
85
|
+
/>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 注意事项
|
|
92
|
+
|
|
93
|
+
1. **数据依赖**:该组件强依赖后端接口(如 `/basic/ruleTemplate/`等),请确保后端服务正常且接口地址匹配。
|
|
94
|
+
2. **Ref 引用**:组件暴露了 `handleSave` 方法,父组件需要通过 `ref` 来触发保存操作。
|
|
95
|
+
3. **模式区别**:
|
|
96
|
+
* `type="instance"`:会根据 `id` 和 `extStrField01` 加载已保存的规则实例数据。
|
|
97
|
+
* `type` 为空:主要用于设计规则模板本身,加载的是模板定义数据。
|