@hzab/list-render 1.10.0-beta → 1.10.0-beta1
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/package.json +1 -1
- package/src/common/handleQuerySchema.ts +145 -0
- package/src/list-render.jsx +9 -6
package/package.json
CHANGED
|
@@ -3,6 +3,60 @@ import { getFieldMap } from "./utils";
|
|
|
3
3
|
import { isRunStr, handleSchemaStrVal, isScopeKey as formIsScopeKey, getScopeKeyVal } from '@hzab/form-render/src/common/schema-handler';
|
|
4
4
|
import { URL_PARAM_NAME } from "./constant";
|
|
5
5
|
|
|
6
|
+
// ===================== 类型定义 =====================
|
|
7
|
+
|
|
8
|
+
type AntdDateComponent = 'DatePicker' | 'DatePicker.RangePicker';
|
|
9
|
+
|
|
10
|
+
interface XComponentProps {
|
|
11
|
+
isSplitTimes?: boolean;
|
|
12
|
+
startKey?: string;
|
|
13
|
+
endKey?: string;
|
|
14
|
+
[k: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface FormilyField {
|
|
18
|
+
type?: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
'x-decorator'?: string;
|
|
21
|
+
'x-component'?: string;
|
|
22
|
+
'x-validator'?: unknown[];
|
|
23
|
+
'x-component-props'?: XComponentProps;
|
|
24
|
+
'x-decorator-props'?: Record<string, unknown>;
|
|
25
|
+
'x-designable-id'?: string;
|
|
26
|
+
'x-index'?: number;
|
|
27
|
+
[k: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface FormilyV1SchemaNode {
|
|
31
|
+
type?: string;
|
|
32
|
+
properties?: Record<string, FormilyField>;
|
|
33
|
+
[k: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface FormilyV1Schema {
|
|
37
|
+
form?: Record<string, unknown>;
|
|
38
|
+
schema: FormilyV1SchemaNode;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type URLQueryObject = Record<string, any> | null | undefined;
|
|
42
|
+
|
|
43
|
+
interface ExtractOptions {
|
|
44
|
+
/** 分拆开关字段名,位于 x-component-props;默认 'isSplitTimes' */
|
|
45
|
+
splitFlag?: string;
|
|
46
|
+
/** 分拆开关的期望值;默认 true */
|
|
47
|
+
splitFlagExpectedValue?: unknown;
|
|
48
|
+
/** 默认开始/结束键名(当 schema 未显式配置时),默认 'startTime' / 'endTime' */
|
|
49
|
+
defaultStartKey?: string;
|
|
50
|
+
defaultEndKey?: string;
|
|
51
|
+
/** 认为是 antd 日期组件的名单,默认 DatePicker / DatePicker.RangePicker */
|
|
52
|
+
antdDateComponents?: readonly AntdDateComponent[];
|
|
53
|
+
/**
|
|
54
|
+
* 命中并成功赋值后,是否从返回对象中删除对应的 startKey / endKey
|
|
55
|
+
* 默认 true(删除)
|
|
56
|
+
*/
|
|
57
|
+
removeMatchedKeys?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
6
60
|
export const handleQuerySchema = (opt) => {
|
|
7
61
|
const { schema, search, filters, onSearch, replaceComList, schemaScope } = opt || {};
|
|
8
62
|
const queryProperties = {};
|
|
@@ -379,4 +433,95 @@ export function getURLObjectQueryParam<T = any>(paramName = URL_PARAM_NAME): T |
|
|
|
379
433
|
}
|
|
380
434
|
}
|
|
381
435
|
|
|
436
|
+
|
|
437
|
+
// ===================== 辅助函数 =====================
|
|
438
|
+
|
|
439
|
+
const pickFormilyProperties = (schema: FormilyV1Schema): Record<string, FormilyField> =>
|
|
440
|
+
(schema?.schema?.properties ?? {});
|
|
441
|
+
|
|
442
|
+
const isAntdDateComponent = (comp: unknown, whitelist: readonly string[]) =>
|
|
443
|
+
typeof comp === 'string' && whitelist.includes(comp);
|
|
444
|
+
|
|
445
|
+
const filterKeys = (props: Record<string, FormilyField>, filters: readonly string[]) => {
|
|
446
|
+
const filterSet = new Set(filters);
|
|
447
|
+
return Object.entries(props).filter(([k]) => filterSet.has(k));
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
const matchSplitFlag = (field: FormilyField, splitFlag: string, expected: unknown) =>
|
|
451
|
+
field?.['x-component-props']?.[splitFlag] === expected;
|
|
452
|
+
|
|
453
|
+
/** 两个值都缺失则返回 undefined;否则返回二元组 */
|
|
454
|
+
const getRangeTupleOrUndefined = (
|
|
455
|
+
urlObj: URLQueryObject,
|
|
456
|
+
startKey: string,
|
|
457
|
+
endKey: string
|
|
458
|
+
): [any, any] | undefined => {
|
|
459
|
+
const obj = (urlObj ?? {}) as Record<string, any>;
|
|
460
|
+
const hasStart = Object.prototype.hasOwnProperty.call(obj, startKey);
|
|
461
|
+
const hasEnd = Object.prototype.hasOwnProperty.call(obj, endKey);
|
|
462
|
+
if (!hasStart && !hasEnd) return undefined;
|
|
463
|
+
return [obj[startKey], obj[endKey]];
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// ===================== 主函数 =====================
|
|
467
|
+
/**
|
|
468
|
+
* 根据formilySchema配置逆解析表单key并将url query赋值
|
|
469
|
+
* 三层筛选:根据filters + splitFlag + antdDateComponents 提取formilySchema配置项然后通过配置的key赋值并返回
|
|
470
|
+
* */
|
|
471
|
+
export function extractSplitDateRanges(
|
|
472
|
+
filters: string[],
|
|
473
|
+
formilySchema: FormilyV1Schema,
|
|
474
|
+
urlObj: URLQueryObject,
|
|
475
|
+
options: ExtractOptions = {}
|
|
476
|
+
): Record<string, any> {
|
|
477
|
+
const {
|
|
478
|
+
splitFlag = 'isSplitTimes',
|
|
479
|
+
splitFlagExpectedValue = true,
|
|
480
|
+
defaultStartKey = 'startTime',
|
|
481
|
+
defaultEndKey = 'endTime',
|
|
482
|
+
antdDateComponents = ['DatePicker', 'DatePicker.RangePicker'],
|
|
483
|
+
removeMatchedKeys = true,
|
|
484
|
+
} = options;
|
|
485
|
+
|
|
486
|
+
const properties = pickFormilyProperties(formilySchema);
|
|
487
|
+
const candidates = filterKeys(properties, filters);
|
|
488
|
+
|
|
489
|
+
// 保持不变性
|
|
490
|
+
const base = _.cloneDeep(urlObj) as Record<string, any>;
|
|
491
|
+
|
|
492
|
+
// 统一延迟删除,避免顺序影响
|
|
493
|
+
const keysToDelete = new Set<string>();
|
|
494
|
+
|
|
495
|
+
for (const [fieldKey, field] of candidates) {
|
|
496
|
+
// 未命中则直接跳过本次循环
|
|
497
|
+
if (!isAntdDateComponent(field?.['x-component'], antdDateComponents)) continue;
|
|
498
|
+
if (!matchSplitFlag(field, splitFlag, splitFlagExpectedValue)) continue;
|
|
499
|
+
|
|
500
|
+
const props = field?.['x-component-props'] ?? {};
|
|
501
|
+
const startKey = (props?.startKey as string) || defaultStartKey;
|
|
502
|
+
const endKey = (props?.endKey as string) || defaultEndKey;
|
|
503
|
+
|
|
504
|
+
const tuple = getRangeTupleOrUndefined(base, startKey, endKey);
|
|
505
|
+
if (!tuple) continue; // 两个值都没有则不赋值、不删除
|
|
506
|
+
|
|
507
|
+
// 命中,给 fieldKey 赋值
|
|
508
|
+
base[fieldKey] = tuple;
|
|
509
|
+
|
|
510
|
+
// 按需记录要删除的键(只删除“命中的”)
|
|
511
|
+
if (removeMatchedKeys) {
|
|
512
|
+
if (Object.prototype.hasOwnProperty.call(base, startKey)) keysToDelete.add(startKey);
|
|
513
|
+
if (Object.prototype.hasOwnProperty.call(base, endKey)) keysToDelete.add(endKey);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// 统一执行删除,保证无顺序副作用
|
|
518
|
+
if (removeMatchedKeys) {
|
|
519
|
+
for (const k of keysToDelete) {
|
|
520
|
+
delete base[k];
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return base;
|
|
525
|
+
}
|
|
526
|
+
|
|
382
527
|
export default handleQuerySchema;
|
package/src/list-render.jsx
CHANGED
|
@@ -15,7 +15,7 @@ import FormModal from "./FormModal";
|
|
|
15
15
|
import DetailModal from "./DetailModal";
|
|
16
16
|
|
|
17
17
|
import { objToFormData } from "./common/utils";
|
|
18
|
-
import { setURLObjectQueryParam, getURLObjectQueryParam, removeURLObjectQueryParam } from "./common/handleQuerySchema";
|
|
18
|
+
import { setURLObjectQueryParam, getURLObjectQueryParam, removeURLObjectQueryParam, extractSplitDateRanges } from "./common/handleQuerySchema";
|
|
19
19
|
import { URL_PARAM_NAME } from "./common/constant";
|
|
20
20
|
|
|
21
21
|
import "./index.less";
|
|
@@ -89,7 +89,7 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
89
89
|
onDel,
|
|
90
90
|
}));
|
|
91
91
|
|
|
92
|
-
const { schema = {}, config = {}, model = {}, msgConf = {} } = props;
|
|
92
|
+
const { schema = {}, config = {}, model = {}, msgConf = {}, filters } = props;
|
|
93
93
|
|
|
94
94
|
// useEffect(() => {
|
|
95
95
|
// const list = props.paginationConf?.pageSizeOptions || pageSizeOptionMap[props.layout] || [10, 20, 50, 100];
|
|
@@ -117,7 +117,11 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
117
117
|
// 延迟获取表单实例
|
|
118
118
|
Promise.resolve().then(() => {
|
|
119
119
|
if (queryRef.current && queryRef.current?.formRef?.current.formRender) {
|
|
120
|
-
|
|
120
|
+
const extractValues = extractSplitDateRanges(filters, schema, getUrlQuery);
|
|
121
|
+
|
|
122
|
+
queryRef.current.formRef.current.formRender?.setValues(extractValues)
|
|
123
|
+
|
|
124
|
+
formQueryRef.current = _.cloneDeep(getUrlQuery)
|
|
121
125
|
}
|
|
122
126
|
})
|
|
123
127
|
|
|
@@ -177,7 +181,7 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
177
181
|
delete mergedQueries.$timerange;
|
|
178
182
|
}
|
|
179
183
|
|
|
180
|
-
model.query = mergedQueries;
|
|
184
|
+
// model.query = mergedQueries;
|
|
181
185
|
// 取消上一次请求
|
|
182
186
|
getListSourceRef.current?.cancel({ code: 601, message: "取消上一次请求" });
|
|
183
187
|
|
|
@@ -227,9 +231,8 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
227
231
|
|
|
228
232
|
function onSearch(quer, source, isReset = false) {
|
|
229
233
|
const query = source === "queryRender" ? { ...quer } : { ...formQueryRef.current, ...quer };
|
|
230
|
-
|
|
231
234
|
// 重置操作时不赋值
|
|
232
|
-
if (!isReset && appendUrlQuery) setURLObjectQueryParam(query, appendUrlQueryKey);
|
|
235
|
+
if (source === "queryRender" && !isReset && appendUrlQuery) setURLObjectQueryParam(query, appendUrlQueryKey);
|
|
233
236
|
|
|
234
237
|
if (model && !model.query) {
|
|
235
238
|
model.query = {};
|