Skip to content

Commit

Permalink
feat: CRUD支持matchFunc,用于前端分页的搜索匹配函数 (#8556)
Browse files Browse the repository at this point in the history
* feat: CRUD支持matchFunc,用于前端分页的搜索匹配函数

* patch(feat: CRUD支持matchFunc): 搜索函数执行时机修改,支持source为上下文数据
  • Loading branch information
lurunze1226 authored Oct 31, 2023
1 parent 7380d4b commit b325687
Show file tree
Hide file tree
Showing 6 changed files with 1,017 additions and 72 deletions.
33 changes: 31 additions & 2 deletions docs/zh-CN/components/crud.md
Original file line number Diff line number Diff line change
Expand Up @@ -3085,6 +3085,33 @@ CRUD 中不限制有多少个单条操作、添加一个操作对应的添加一
}
```

### 匹配函数

> `3.5.0` 及以上版本
支持自定义匹配函数`matchFunc`,当开启`loadDataOnce`时,会基于该函数计算的匹配结果进行过滤,主要用于处理列字段类型较为复杂或者字段值格式和后端返回不一致的场景,函数签名如下:

```typescript
interface CRUDMatchFunc {
(
/* 当前列表的全量数据 */
items: any,
/* 最近一次接口返回的全量数据 */
itemsRaw: any,
/** 相关配置 */
options?: {
/* 查询参数 */
query: Record<string, any>,
/* 列配置 */
columns: any;
}
): boolean;
}
```

具体效果请参考[示例](../../../examples/crud/match-func)


## 动态列

> since 1.1.6
Expand Down Expand Up @@ -3220,8 +3247,8 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据,

## 属性表

| 属性名 | 类型 | 默认值 | 说明 |
| ------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| 属性名 | 类型 | 默认值 | 说明 | 版本 |
| ------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --- |
| type | `string` | | `type` 指定为 CRUD 渲染器 |
| mode | `string` | `"table"` | `"table" 、 "cards" 或者 "list"` |
| title | `string` | `""` | 可设置成空,当设置成空时,没有标题栏 |
Expand Down Expand Up @@ -3276,6 +3303,8 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据,
| resetPageAfterAjaxItemAction | `boolean` | `false` | 单条数据 ajax 操作后是否重置页码为第一页 |
| autoFillHeight | `boolean``{height: number}` | | 内容区域自适应高度 |
| canAccessSuperData | `boolean` | `true` | 指定是否可以自动获取上层的数据并映射到表格行数据上,如果列也配置了该属性,则列的优先级更高 |
| matchFunc | `string` | [`CRUDMatchFunc`](#匹配函数) | 自定义匹配函数, 当开启`loadDataOnce`时,会基于该函数计算的匹配结果进行过滤,主要用于处理列字段类型较为复杂或者字段值格式和后端返回不一致的场景 | `3.5.0` |


注意除了上面这些属性,CRUD 在不同模式下的属性需要参考各自的文档,比如

Expand Down
298 changes: 298 additions & 0 deletions examples/components/CRUD/MatchFunc.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
export default {
type: 'page',
title: '匹配函数',
remark: '使用前端分页处理列字段类型较为复杂或者字段值格式和后端返回不一致的场景',
body: [
{
type: 'container',
style: {
padding: '8px',
marginBottom: '8px',
backgroundColor: '#f5f5f5',
borderRadius: '4px'
},
body: [
{
"type": "tpl",
tpl: '<h4>匹配函数签名:</h4>',
"inline": false
},
{
"type": "code",
"language": "typescript",
"value": `interface CRUDMatchFunc {
(
/* 当前列表的全量数据 */
items: any,
/* 最近一次接口返回的全量数据 */
itemsRaw: any,
/** 相关配置 */
options?: {
/* 查询参数 */
query: Record<string, any>,
/* 列配置 */
columns: any;
}
): boolean;
}`
}
]
},
{
"type": "crud",
"syncLocation": false,
"api": "/api/mock2/crud/loadDataOnce",
"loadDataOnce": true,
"loadDataOnceFetchOnFilter": false,
"perPage": 5,
"matchFunc": `
const {query = {}, columns} = options;
let result = items.concat();
Object.keys(query).forEach(key => {
const value = query[key];
if (value == null) {
return;
}
if (key === 'status') {
result = result.filter(item => item.status === Boolean(value));
} else if (key === 'time') {
if (typeof value === 'string') {
const [start, end] = value.split(",");
result = result.filter(item => {
const time = Number(item.time);
return time >= Number(start) && time <= Number(end);
});
}
}
});
return result;`,
"filter": {
"debug": true,
"body": [
{
"type": "switch",
"name": "status",
"label": "已核验",
"size": "sm"
},
{
"type": "input-datetime-range",
"name": "time",
"label": "时间",
"size": "full"
}
],
"actions": [
{
"type": "reset",
"label": "重置"
},
{
"type": "submit",
"level": "primary",
"label": "查询"
}
]
},
"columns": [
{
"name": "id",
"label": "ID"
},
{
"name": "browser",
"label": "Browser"
},
{
"name": "version",
"label": "Engine version",
"searchable": {
"type": "select",
"name": "version",
"label": "Engine version",
"clearable": true,
"multiple": true,
"searchable": true,
"checkAll": true,
"options": [
"1.7",
"3.3",
"5.6"
],
"maxTagCount": 10,
"extractValue": true,
"joinValues": false,
"delimiter": ",",
"defaultCheckAll": false,
"checkAllLabel": "全选"
}
},
{
"name": "grade",
"label": "CSS grade"
},
{
"name": "status",
"label": "已核验",
"type": "tpl",
"tpl": "${status === true ? '是' : '否'}",
"filterable": {
"options": [
{"label": "是", "value": true},
{"label": "否", "value": false}
]
}
},
{
"name": "time",
"type": "date",
"label": "时间",
"format": "YYYY-MM-DD HH:mm:ss"
}
]
},
{
"type": "divider",
},
{
"type": "tpl",
tpl: '<h2>使用数据域变量作为数据源:</h2>',
"inline": false
},
{
"type": "service",
"api": {
"url": "/api/mock2/crud/loadDataOnce",
"method": "get",
"responseData": {
"table": "${rows}"
}
},
"body": [
{
"type": "crud",
"syncLocation": false,
"source": "${table}",
"loadDataOnce": true,
"loadDataOnceFetchOnFilter": false,
"perPage": 5,
"matchFunc": `
const {query = {}, columns} = options;
let result = itemsRaw.concat();
Object.keys(query).forEach(key => {
const value = query[key];
if (value == null) {
return;
}
if (key === 'status') {
result = result.filter(item => item.status === Boolean(value));
} else if (key === 'time') {
if (typeof value === 'string') {
const [start, end] = value.split(",");
result = result.filter(item => {
const time = Number(item.time);
return time >= Number(start) && time <= Number(end);
});
}
}
});
return result;`,
"filter": {
"debug": true,
"body": [
{
"type": "switch",
"name": "status",
"label": "已核验",
"size": "sm"
},
{
"type": "input-datetime-range",
"name": "time",
"label": "时间",
"size": "full"
}
],
"actions": [
{
"type": "reset",
"label": "重置"
},
{
"type": "submit",
"level": "primary",
"label": "查询"
}
]
},
"columns": [
{
"name": "id",
"label": "ID"
},
{
"name": "browser",
"label": "Browser"
},
{
"name": "version",
"label": "Engine version",
"searchable": {
"type": "select",
"name": "version",
"label": "Engine version",
"clearable": true,
"multiple": true,
"searchable": true,
"checkAll": true,
"options": [
"1.7",
"3.3",
"5.6"
],
"maxTagCount": 10,
"extractValue": true,
"joinValues": false,
"delimiter": ",",
"defaultCheckAll": false,
"checkAllLabel": "全选"
}
},
{
"name": "grade",
"label": "CSS grade"
},
{
"name": "status",
"label": "已核验",
"type": "tpl",
"tpl": "${status === true ? '是' : '否'}",
"filterable": {
"options": [
{"label": "是", "value": true},
{"label": "否", "value": false}
]
}
},
{
"name": "time",
"type": "date",
"label": "时间",
"format": "YYYY-MM-DD HH:mm:ss"
}
]
}
]
}
]
};
18 changes: 15 additions & 3 deletions examples/components/Example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import ExportCSVExcelSchema from './CRUD/ExportCSVExcel';
import CRUDDynamicSchema from './CRUD/Dynamic';
import CRUDSimplePagerSchema from './CRUD/SimplePager';
import CRUDParsePrimitiveQuerySchema from './CRUD/ParsePrimitiveQuery';
import CRUDMatchFuncSchema from './CRUD/MatchFunc';
import ItemActionchema from './CRUD/ItemAction';
import SdkTest from './Sdk/Test';
import JSONSchemaForm from './Form/Schem';
Expand Down Expand Up @@ -438,9 +439,20 @@ export const examples = [
component: makeSchemaRenderer(PopOverCrudSchema)
},
{
label: '一次性加载',
path: '/examples/crud/load-once',
component: makeSchemaRenderer(LoadOnceTableCrudSchema)
label: '前端分页',
icon: 'fa fa-list-ol',
children: [
{
label: '一次性加载',
path: '/examples/crud/load-once',
component: makeSchemaRenderer(LoadOnceTableCrudSchema)
},
{
label: '匹配函数',
path: '/examples/crud/match-func',
component: makeSchemaRenderer(CRUDMatchFuncSchema)
}
]
},
{
label: '点击联动',
Expand Down
Loading

0 comments on commit b325687

Please sign in to comment.