From 392779cf90c2a3e2f5f5e987a7b4a8ca9cecb7e8 Mon Sep 17 00:00:00 2001 From: RUNZE LU <36724300+lurunze1226@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:23:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20CRUD2=E7=BB=84=E4=BB=B6=E5=BC=80?= =?UTF-8?q?=E5=90=AFsyncLocation=E5=90=8E=E5=88=86=E9=A1=B5=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=9C=AA=E5=90=8C=E6=AD=A5pageField=E5=80=BC=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=97=A0=E6=B3=95=E5=88=87=E6=8D=A2=E9=A1=B5=E7=A0=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98;=20feat:=20CRUD2=E6=94=AF=E6=8C=81parsePrimi?= =?UTF-8?q?tiveQuery=20(#8908)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/store/crud.ts | 11 ++- packages/amis/src/renderers/CRUD2.tsx | 122 ++++++++++++++++++-------- 2 files changed, 95 insertions(+), 38 deletions(-) diff --git a/packages/amis-core/src/store/crud.ts b/packages/amis-core/src/store/crud.ts index 5bc78ca34..1cbcf0116 100644 --- a/packages/amis-core/src/store/crud.ts +++ b/packages/amis-core/src/store/crud.ts @@ -521,13 +521,18 @@ export const CRUDStore = ServiceStore.named('CRUDStore') } }); - function changePage(page: number, perPage?: number | string) { - self.page = page; + function changePage(page: number | string, perPage?: number | string) { + const pageNum = typeof page !== 'number' ? parseInt(page, 10) : page; + + self.page = isNaN(pageNum) ? 1 : pageNum; perPage && changePerPage(perPage); } function changePerPage(perPage: number | string) { - self.perPage = parseInt(perPage as string, 10); + const perPageNum = + typeof perPage !== 'number' ? parseInt(perPage, 10) : perPage; + + self.perPage = isNaN(perPageNum) ? 10 : perPageNum; } function selectAction(action: ActionObject) { diff --git a/packages/amis/src/renderers/CRUD2.tsx b/packages/amis/src/renderers/CRUD2.tsx index 8afb037bd..daee85d5f 100644 --- a/packages/amis/src/renderers/CRUD2.tsx +++ b/packages/amis/src/renderers/CRUD2.tsx @@ -1,8 +1,18 @@ import React from 'react'; +import {findDOMNode} from 'react-dom'; import omitBy from 'lodash/omitBy'; -import {Renderer, RendererProps, filterTarget, ActionObject} from 'amis-core'; -import {CRUDStore, ICRUDStore} from 'amis-core'; +import pick from 'lodash/pick'; +import findIndex from 'lodash/findIndex'; +import upperFirst from 'lodash/upperFirst'; import { + Renderer, + RendererProps, + filterTarget, + ActionObject, + ScopedContext, + IScopedContext, + CRUDStore, + ICRUDStore, createObject, extendObject, isObjectShallowModified, @@ -13,14 +23,15 @@ import { isArrayChildrenModified, autobind, parseQuery, - isObject + isObject, + evalExpression, + filter, + isEffectiveApi, + isApiOutdated, + isPureVariable, + resolveVariableAndFilter, + parsePrimitiveQueryString } from 'amis-core'; -import {ScopedContext, IScopedContext} from 'amis-core'; -import pick from 'lodash/pick'; -import {findDOMNode} from 'react-dom'; -import {evalExpression, filter} from 'amis-core'; -import {isEffectiveApi, isApiOutdated} from 'amis-core'; -import findIndex from 'lodash/findIndex'; import {Html, SpinnerExtraProps} from 'amis-ui'; import { BaseSchema, @@ -33,11 +44,10 @@ import { import {CardsSchema} from './Cards'; import {ListSchema} from './List'; import {TableSchema2} from './Table2'; +import {SchemaCollection} from '../Schema'; + import type {Table2RendererEvent} from './Table2'; import type {CardsRendererEvent} from './Cards'; -import {isPureVariable, resolveVariableAndFilter} from 'amis-core'; -import {SchemaCollection} from '../Schema'; -import upperFirst from 'lodash/upperFirst'; export type CRUDRendererEvent = Table2RendererEvent | CardsRendererEvent; @@ -184,6 +194,11 @@ export interface CRUD2CommonSchema extends BaseSchema, SpinnerExtraProps { /** 行标识符,默认为id */ primaryField?: string; + + /** + * 是否开启Query信息转换,开启后将会对url中的Query进行转换,将字符串格式的布尔值转化为同位类型 + */ + parsePrimitiveQuery?: boolean; } export type CRUD2CardsSchema = CRUD2CommonSchema & { @@ -252,8 +267,10 @@ export default class CRUD2 extends React.Component { 'showSelection', 'headerToolbarClassName', 'footerToolbarClassName', - 'primaryField' + 'primaryField', + 'parsePrimitiveQuery' ]; + static defaultProps = { toolbarInline: true, syncLocation: true, @@ -263,7 +280,8 @@ export default class CRUD2 extends React.Component { autoFillHeight: false, showSelection: true, perPage: 10, - primaryField: 'id' + primaryField: 'id', + parsePrimitiveQuery: true }; control: any; @@ -279,20 +297,27 @@ export default class CRUD2 extends React.Component { constructor(props: CRUD2Props) { super(props); - const {location, store, syncLocation, pageField, perPageField} = props; + const { + location, + store, + syncLocation, + pageField, + perPageField, + parsePrimitiveQuery + } = props; this.mounted = true; if (syncLocation && location && (location.query || location.search)) { store.updateQuery( - parseQuery(location), + parseQuery(location, {parsePrimitive: parsePrimitiveQuery}), undefined, pageField, perPageField ); } else if (syncLocation && !location && window.location.search) { store.updateQuery( - parseQuery(window.location), + parseQuery(window.location, {parsePrimitive: parsePrimitiveQuery}), undefined, pageField, perPageField @@ -339,6 +364,8 @@ export default class CRUD2 extends React.Component { componentDidUpdate(prevProps: CRUD2Props) { const props = this.props; const store = prevProps.store; + const {parsePrimitiveQuery} = props; + if (prevProps.columns !== props.columns) { store.updateColumns(props.columns); } @@ -362,7 +389,7 @@ export default class CRUD2 extends React.Component { ) { // 同步地址栏,那么直接检测 query 是否变了,变了就重新拉数据 store.updateQuery( - parseQuery(props.location), + parseQuery(props.location, {parsePrimitive: parsePrimitiveQuery}), undefined, props.pageField, props.perPageField @@ -438,7 +465,8 @@ export default class CRUD2 extends React.Component { ...store.query }, replaceQuery: this.props.initFetch !== false, - loadMore: loadType === 'more' + loadMore: loadType === 'more', + resetPage: false }); // 保留一次用于重置查询条件 @@ -463,14 +491,28 @@ export default class CRUD2 extends React.Component { resetQuery?: boolean; replaceQuery?: boolean; loadMore?: boolean; + /** 是否重置当页码到首页 */ + resetPage?: boolean; }) { - const {store, syncLocation, env, pageField, perPageField} = this.props; - let {query, resetQuery, replaceQuery, loadMore} = data || {}; + const { + store, + syncLocation, + env, + pageField, + perPageField, + parsePrimitiveQuery + } = this.props; + let {query, resetQuery, replaceQuery, loadMore, resetPage} = data || {}; query = syncLocation && query ? qsparse(qsstringify(query, undefined, true)) - : query; + : query || {}; + + /** 把布尔值反解出来 */ + if (parsePrimitiveQuery) { + query = parsePrimitiveQueryString(query); + } store.updateQuery( resetQuery ? this.props.store.pristineQuery : query, @@ -481,7 +523,10 @@ export default class CRUD2 extends React.Component { perPageField, replaceQuery ); - store.changePage(1); + + if (resetPage) { + store.changePage(1); + } this.lastQuery = store.query; this.getData(undefined, undefined, undefined, loadMore ?? false); @@ -637,7 +682,7 @@ export default class CRUD2 extends React.Component { pageField, perPageField ); - + store.changePage(page, perPage); this.getData(); if (autoJumpToTopOnPagerChange && this.control) { @@ -1110,15 +1155,18 @@ export default class CRUD2 extends React.Component { ); } - renderFilter(filter: SchemaObject[] | SchemaObject) { - if (!filter || (Array.isArray(filter) && filter.length === 0)) { + renderFilter(filterSchema: SchemaObject[] | SchemaObject) { + if ( + !filterSchema || + (Array.isArray(filterSchema) && filterSchema.length === 0) + ) { return null; } - const filterSchemas = Array.isArray(filter) - ? filter - : isObject(filter) && filter.type != null - ? [filter] + const filterSchemas = Array.isArray(filterSchema) + ? filterSchema + : isObject(filterSchema) && filterSchema.type != null + ? [filterSchema] : []; if (filterSchemas.length < 1) { @@ -1129,11 +1177,13 @@ export default class CRUD2 extends React.Component { this.renderChild(`filter/${index}`, item, { key: index + 'filter', data: this.props.store.filterData, - onSubmit: (data: any) => this.handleSearch({query: data}), + onSubmit: (data: any) => + this.handleSearch({query: data, resetPage: true}), onReset: () => this.handleSearch({ resetQuery: true, - replaceQuery: true + replaceQuery: true, + resetPage: true }) }) ); @@ -1198,7 +1248,7 @@ export default class CRUD2 extends React.Component { className, style, bodyClassName, - filter, + filter: filterSchema, render, store, mode = 'table2', @@ -1241,7 +1291,9 @@ export default class CRUD2 extends React.Component { })} style={style} > -
{this.renderFilter(filter)}
+
+ {this.renderFilter(filterSchema)} +
{this.renderToolbar('headerToolbar', headerToolbar)} @@ -1270,7 +1322,7 @@ export default class CRUD2 extends React.Component { key: 'body', className: cx('Crud2-body', bodyClassName), ref: this.controlRef, - autoGenerateFilter: !filter && autoGenerateFilter, + autoGenerateFilter: !filterSchema && autoGenerateFilter, autoFillHeight: autoFillHeight, checkAll: false, // 不使用组件的全选,因为不在工具栏里 selectable: !!(selectable ?? pickerMode),