contextMenuFactory menus中action支持数组

This commit is contained in:
wkj 2024-01-19 09:53:29 +08:00
parent fcb720eb79
commit 1d4b59bda5
18 changed files with 188 additions and 86 deletions

View File

@ -62,7 +62,7 @@ export default function Render(props) {
tfColumns.forEach((column, index) => { tfColumns.forEach((column, index) => {
const { colSpan } = column; const { colSpan } = column;
const colSpan2 = getSpan(colSpan || 1, mergedColumn); const colSpan2 = getSpan(colSpan || 1, mergedColumn);
const item = (<Col span={gridColumn * colSpan2}> const item = (<Col key={`c_filterPanel_col_${index}`} span={gridColumn * colSpan2}>
<Filter column={column} entity={entity} oakPath={oakFullpath}/> <Filter column={column} entity={entity} oakPath={oakFullpath}/>
</Col>); </Col>);
if (index === 0) { if (index === 0) {
@ -120,7 +120,7 @@ export default function Render(props) {
} }
} }
else { else {
if (width === 'xs') { if (width === 'xs' && !!firstItem) {
items.push(firstItem); items.push(firstItem);
} }
} }
@ -137,7 +137,7 @@ export default function Render(props) {
const buttonItemLayout = formLayout === 'horizontal' const buttonItemLayout = formLayout === 'horizontal'
? { wrapperCol: { span: 18, offset: 6 } } ? { wrapperCol: { span: 18, offset: 6 } }
: null; : null;
items.push(<Col span={_gridColumn}> items.push(<Col key={`c_filterPanel_buttons`} span={_gridColumn}>
<Form.Item {...buttonItemLayout}> <Form.Item {...buttonItemLayout}>
<Space className={Style.actionBox}> <Space className={Style.actionBox}>
<Badge count={count}> <Badge count={count}>
@ -162,7 +162,9 @@ export default function Render(props) {
setOpen(!open); setOpen(!open);
}}> }}>
<Space> <Space>
{open ? t('common::shrink') : t('common::expand')} {open
? t('common::shrink')
: t('common::expand')}
{open ? <UpOutlined /> : <DownOutlined />} {open ? <UpOutlined /> : <DownOutlined />}
</Space> </Space>

View File

@ -1,8 +1,7 @@
import React from 'react'; import React from 'react';
import { EntityDict } from 'oak-domain/lib/types/Entity'; import { EntityDict } from 'oak-domain/lib/types/Entity';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; import { ListButtonProps, ED } from '../../../types/AbstractComponent';
import { ListButtonProps } from '../../../types/AbstractComponent';
import { WebComponentProps } from '../../../types/Page'; import { WebComponentProps } from '../../../types/Page';
export default function Render(props: WebComponentProps<EntityDict & BaseEntityDict, keyof EntityDict, false, { export default function Render(props: WebComponentProps<ED, keyof EntityDict, false, {
items: ListButtonProps[]; items: ListButtonProps[];
}, {}>): React.JSX.Element; }, {}>): React.JSX.Element | null;

View File

@ -4,13 +4,15 @@ import { FloatButton } from 'antd';
import { BarsOutlined, } from '@ant-design/icons'; import { BarsOutlined, } from '@ant-design/icons';
export default function Render(props) { export default function Render(props) {
const { methods, data } = props; const { methods, data } = props;
const { t } = methods;
const { items } = data; const { items } = data;
if (items && items.length === 1) { if (!items || items.length === 0) {
return null;
}
if (items?.length === 1) {
const item = items[0]; const item = items[0];
return (<FloatButton shape="circle" type="primary" style={{ right: 24 }} icon={item.icon} description={item.icon ? null : item.label} onClick={() => item.onClick()}/>); return (<FloatButton shape="circle" type="primary" style={{ right: 24 }} icon={item.icon} description={item.icon ? null : item.label} onClick={() => item.onClick()}/>);
} }
return (<FloatButton.Group shape='circle' trigger="click" type="primary" style={{ right: 24 }} icon={<BarsOutlined />}> return (<FloatButton.Group shape="circle" trigger="click" type="primary" style={{ right: 24 }} icon={<BarsOutlined />}>
{items && items.map((ele) => (<FloatButton icon={ele.icon} description={ele.icon ? null : ele.label} onClick={() => ele.onClick()}/>))} {items?.map((ele, index) => (<FloatButton key={`c_buttonGroup_${index}`} icon={ele.icon} description={ele.icon ? null : ele.label} onClick={() => ele.onClick()}/>))}
</FloatButton.Group>); </FloatButton.Group>);
} }

View File

@ -1,8 +1,7 @@
import React from 'react'; import React from 'react';
import { EntityDict } from 'oak-domain/lib/types/Entity'; import { EntityDict } from 'oak-domain/lib/types/Entity';
import { WebComponentProps } from '../../../types/Page'; import { WebComponentProps } from '../../../types/Page';
import { ListButtonProps } from '../../../types/AbstractComponent'; import { ListButtonProps, ED } from '../../../types/AbstractComponent';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; export default function Render(props: WebComponentProps<ED, keyof EntityDict, false, {
export default function Render(props: WebComponentProps<EntityDict & BaseEntityDict, keyof EntityDict, false, {
items: ListButtonProps[]; items: ListButtonProps[];
}, {}>): React.JSX.Element; }, {}>): React.JSX.Element | null;

View File

@ -1,12 +1,15 @@
import React from 'react'; import React from 'react';
import { Space, Button } from 'antd'; import { Space, Button } from 'antd';
export default function Render(props) { export default function Render(props) {
const { methods, data: oakData } = props; const { methods, data } = props;
const { items } = oakData; const { items } = data;
// 为了i18更新时能够重新渲染 if (!items || items.length === 0) {
return null;
}
return (<Space> return (<Space>
{items.filter((ele) => ele.show).map((ele) => (<Button type={ele.type} onClick={ele.onClick}> {items?.filter((ele) => ele.show)
{ele.label} .map((ele, index) => (<Button key={`c_buttonGroup_${index}`} type={ele.type} onClick={ele.onClick}>
</Button>))} {ele.label}
</Button>))}
</Space>); </Space>);
} }

View File

@ -5,7 +5,7 @@ export default OakComponent({
properties: { properties: {
entity: '', entity: '',
extraActions: [], extraActions: [],
onAction: (() => undefined), onAction: (() => { }),
disabledOp: false, disabledOp: false,
attributes: [], attributes: [],
data: [], data: [],

View File

@ -9,7 +9,7 @@ import { RelationAuth } from './relationAuth';
interface IMenu<ED extends EntityDict & BaseEntityDict, T extends keyof ED> { interface IMenu<ED extends EntityDict & BaseEntityDict, T extends keyof ED> {
name: string; name: string;
entity: T; entity: T;
action: ED[T]['Action']; action: ED[T]['Action'] | ED[T]['Action'][];
paths: string[]; paths: string[];
} }
export declare class ContextMenuFactory<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt> & Record<string, Aspect<ED, Cxt>>> extends Feature { export declare class ContextMenuFactory<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt> & Record<string, Aspect<ED, Cxt>>> extends Feature {

View File

@ -28,9 +28,9 @@ export class ContextMenuFactory extends Feature {
} }
return; return;
} }
const pathhh = path.split('.'); const pathArr = path.split('.');
const judgeIter = (e2, idx) => { const judgeIter = (e2, idx) => {
const attr = pathhh[idx]; const attr = pathArr[idx];
const rel = judgeRelation(schema, e2, attr); const rel = judgeRelation(schema, e2, attr);
let e3 = e2; let e3 = e2;
if (typeof rel === 'string') { if (typeof rel === 'string') {
@ -43,14 +43,14 @@ export class ContextMenuFactory extends Feature {
assert(rel instanceof Array); assert(rel instanceof Array);
e3 = rel[0]; e3 = rel[0];
} }
if (idx === pathhh.length - 1) { if (idx === pathArr.length - 1) {
if (e3 === 'user') { if (e3 === 'user') {
// 用user连接说明一定满足 // 用user连接说明一定满足
return true; return true;
} }
if (e3 === entity) { if (e3 === entity) {
const filter = {}; const filter = {};
const paths2 = pathhh.slice(0, pathhh.length - 1); const paths2 = pathArr.slice(0, pathArr.length - 1);
if (rel === 2) { if (rel === 2) {
set(filter, paths2.concat('entity'), entity); set(filter, paths2.concat('entity'), entity);
set(filter, paths2.concat('entityId'), entityId); set(filter, paths2.concat('entityId'), entityId);
@ -87,6 +87,28 @@ export class ContextMenuFactory extends Feature {
return true; return true;
} }
// relationAuth和其它的checker现在分开判断 // relationAuth和其它的checker现在分开判断
let result = false;
if (action instanceof Array) {
for (let i = 0; i < action.length; i++) {
// action有一个满足就行了
const checkResult = this.relationAuth.checkRelation(destEntity, {
action: action[i],
data: undefined,
filter,
}) &&
this.cache.checkOperation(destEntity, action[i], undefined, filter, [
'logical',
'relation',
'logicalRelation',
'row',
]);
if (checkResult) {
result = checkResult;
break;
}
}
return result;
}
return (this.relationAuth.checkRelation(destEntity, { return (this.relationAuth.checkRelation(destEntity, {
action, action,
data: undefined, data: undefined,

View File

@ -73,7 +73,9 @@ export function resolvePath(dataSchema, entity, path) {
idx++; idx++;
} }
catch (err) { catch (err) {
console.log(`存在非schema属性${path}`); if (process.env.NODE_ENV === 'development') {
console.warn(`存在非「${_entity}」schema属性: ${path}`);
}
return { return {
entity: 'notExist', entity: 'notExist',
attr: path, attr: path,

View File

@ -9,7 +9,7 @@ import { RelationAuth } from './relationAuth';
interface IMenu<ED extends EntityDict & BaseEntityDict, T extends keyof ED> { interface IMenu<ED extends EntityDict & BaseEntityDict, T extends keyof ED> {
name: string; name: string;
entity: T; entity: T;
action: ED[T]['Action']; action: ED[T]['Action'] | ED[T]['Action'][];
paths: string[]; paths: string[];
} }
export declare class ContextMenuFactory<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt> & Record<string, Aspect<ED, Cxt>>> extends Feature { export declare class ContextMenuFactory<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt> & Record<string, Aspect<ED, Cxt>>> extends Feature {

View File

@ -31,9 +31,9 @@ class ContextMenuFactory extends Feature_1.Feature {
} }
return; return;
} }
const pathhh = path.split('.'); const pathArr = path.split('.');
const judgeIter = (e2, idx) => { const judgeIter = (e2, idx) => {
const attr = pathhh[idx]; const attr = pathArr[idx];
const rel = (0, relation_1.judgeRelation)(schema, e2, attr); const rel = (0, relation_1.judgeRelation)(schema, e2, attr);
let e3 = e2; let e3 = e2;
if (typeof rel === 'string') { if (typeof rel === 'string') {
@ -46,14 +46,14 @@ class ContextMenuFactory extends Feature_1.Feature {
(0, assert_1.assert)(rel instanceof Array); (0, assert_1.assert)(rel instanceof Array);
e3 = rel[0]; e3 = rel[0];
} }
if (idx === pathhh.length - 1) { if (idx === pathArr.length - 1) {
if (e3 === 'user') { if (e3 === 'user') {
// 用user连接说明一定满足 // 用user连接说明一定满足
return true; return true;
} }
if (e3 === entity) { if (e3 === entity) {
const filter = {}; const filter = {};
const paths2 = pathhh.slice(0, pathhh.length - 1); const paths2 = pathArr.slice(0, pathArr.length - 1);
if (rel === 2) { if (rel === 2) {
(0, lodash_1.set)(filter, paths2.concat('entity'), entity); (0, lodash_1.set)(filter, paths2.concat('entity'), entity);
(0, lodash_1.set)(filter, paths2.concat('entityId'), entityId); (0, lodash_1.set)(filter, paths2.concat('entityId'), entityId);
@ -90,6 +90,28 @@ class ContextMenuFactory extends Feature_1.Feature {
return true; return true;
} }
// relationAuth和其它的checker现在分开判断 // relationAuth和其它的checker现在分开判断
let result = false;
if (action instanceof Array) {
for (let i = 0; i < action.length; i++) {
// action有一个满足就行了
const checkResult = this.relationAuth.checkRelation(destEntity, {
action: action[i],
data: undefined,
filter,
}) &&
this.cache.checkOperation(destEntity, action[i], undefined, filter, [
'logical',
'relation',
'logicalRelation',
'row',
]);
if (checkResult) {
result = checkResult;
break;
}
}
return result;
}
return (this.relationAuth.checkRelation(destEntity, { return (this.relationAuth.checkRelation(destEntity, {
action, action,
data: undefined, data: undefined,

View File

@ -78,7 +78,9 @@ function resolvePath(dataSchema, entity, path) {
idx++; idx++;
} }
catch (err) { catch (err) {
console.log(`存在非schema属性${path}`); if (process.env.NODE_ENV === 'development') {
console.warn(`存在非「${_entity}」schema属性: ${path}`);
}
return { return {
entity: 'notExist', entity: 'notExist',
attr: path, attr: path,

View File

@ -111,7 +111,7 @@ export default function Render<ED2 extends ED>(
); );
const count = filters2?.length || 0; //查询条件个数 const count = filters2?.length || 0; //查询条件个数
const items: any = []; const items: React.JSX.Element[] = [];
let rowSum = 0; let rowSum = 0;
let rowSum2 = 0; let rowSum2 = 0;
let rows2 = 1; let rows2 = 1;
@ -122,7 +122,10 @@ export default function Render<ED2 extends ED>(
const colSpan2 = getSpan(colSpan || 1, mergedColumn); const colSpan2 = getSpan(colSpan || 1, mergedColumn);
const item = ( const item = (
<Col span={gridColumn * colSpan2}> <Col
key={`c_filterPanel_col_${index}`}
span={gridColumn * colSpan2}
>
<Filter <Filter
column={column as ColumnProps<ED, keyof ED>} column={column as ColumnProps<ED, keyof ED>}
entity={entity} entity={entity}
@ -183,7 +186,7 @@ export default function Render<ED2 extends ED>(
_gridColumn = gridColumn * (mergedColumn - rowSum); _gridColumn = gridColumn * (mergedColumn - rowSum);
} }
} else { } else {
if (width === 'xs') { if (width === 'xs' && !!firstItem) {
items.push(firstItem); items.push(firstItem);
} }
} }
@ -204,7 +207,7 @@ export default function Render<ED2 extends ED>(
? { wrapperCol: { span: 18, offset: 6 } } ? { wrapperCol: { span: 18, offset: 6 } }
: null; : null;
items.push( items.push(
<Col span={_gridColumn}> <Col key={`c_filterPanel_buttons`} span={_gridColumn}>
<Form.Item {...buttonItemLayout}> <Form.Item {...buttonItemLayout}>
<Space className={Style.actionBox}> <Space className={Style.actionBox}>
<Badge count={count}> <Badge count={count}>
@ -241,7 +244,9 @@ export default function Render<ED2 extends ED>(
}} }}
> >
<Space> <Space>
{open ? t('common::shrink') : t('common::expand')} {open
? t('common::shrink')
: t('common::expand')}
{open ? <UpOutlined /> : <DownOutlined />} {open ? <UpOutlined /> : <DownOutlined />}
</Space> </Space>

View File

@ -2,36 +2,36 @@ import React from 'react';
import { Space, Button } from 'antd'; import { Space, Button } from 'antd';
import { EntityDict } from 'oak-domain/lib/types/Entity'; import { EntityDict } from 'oak-domain/lib/types/Entity';
import { WebComponentProps } from '../../../types/Page'; import { WebComponentProps } from '../../../types/Page';
import { ListButtonProps } from '../../../types/AbstractComponent'; import { ListButtonProps, ED } from '../../../types/AbstractComponent';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
type ED = EntityDict & BaseEntityDict;
export default function Render( export default function Render(
props: WebComponentProps< props: WebComponentProps<
EntityDict & BaseEntityDict, ED,
keyof EntityDict, keyof EntityDict,
false, false,
{ {
items: ListButtonProps[]; items: ListButtonProps[];
}, },
{ {}
}
> >
) { ) {
const { methods, data: oakData } = props; const { methods, data } = props;
const { const { items } = data;
items if (!items || items.length === 0) {
} = oakData; return null;
// 为了i18更新时能够重新渲染 }
return ( return (
<Space> <Space>
{items.filter((ele) => ele.show).map((ele) => ( {items?.filter((ele) => ele.show)
<Button type={ele.type} onClick={ele.onClick}> .map((ele, index) => (
{ele.label} <Button
</Button> key={`c_buttonGroup_${index}`}
))} type={ele.type}
onClick={ele.onClick}
>
{ele.label}
</Button>
))}
</Space> </Space>
); );
} }

View File

@ -3,33 +3,30 @@ import React from 'react';
import { FloatButton } from 'antd'; import { FloatButton } from 'antd';
import { EntityDict } from 'oak-domain/lib/types/Entity'; import { EntityDict } from 'oak-domain/lib/types/Entity';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; import { ListButtonProps, ED } from '../../../types/AbstractComponent';
import { ListButtonProps } from '../../../types/AbstractComponent';
import { WebComponentProps } from '../../../types/Page'; import { WebComponentProps } from '../../../types/Page';
import { import {
BarsOutlined, BarsOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
type ED = EntityDict & BaseEntityDict;
export default function Render( export default function Render(
props: WebComponentProps< props: WebComponentProps<
EntityDict & BaseEntityDict, ED,
keyof EntityDict, keyof EntityDict,
false, false,
{ {
items: ListButtonProps[]; items: ListButtonProps[];
}, },
{ {}
}
> >
) { ) {
const { methods, data } = props; const { methods, data } = props;
const { t } = methods; const { items } = data;
const { if (!items || items.length === 0) {
items return null;
} = data; }
if (items && items.length === 1) { if (items?.length === 1) {
const item = items[0]; const item = items[0];
return ( return (
<FloatButton <FloatButton
@ -40,18 +37,19 @@ export default function Render(
description={item.icon ? null : item.label} description={item.icon ? null : item.label}
onClick={() => item.onClick()} onClick={() => item.onClick()}
/> />
) );
} }
return ( return (
<FloatButton.Group <FloatButton.Group
shape='circle' shape="circle"
trigger="click" trigger="click"
type="primary" type="primary"
style={{ right: 24 }} style={{ right: 24 }}
icon={<BarsOutlined />} icon={<BarsOutlined />}
> >
{items && items.map((ele) => ( {items?.map((ele, index) => (
<FloatButton <FloatButton
key={`c_buttonGroup_${index}`}
icon={ele.icon} icon={ele.icon}
description={ele.icon ? null : ele.label} description={ele.icon ? null : ele.label}
onClick={() => ele.onClick()} onClick={() => ele.onClick()}

View File

@ -1,15 +1,17 @@
import { CardDef, ED, OakAbsAttrDef, onActionFnDef, OakExtraActionProps, ListButtonProps, OakAbsAttrJudgeDef } from '../../types/AbstractComponent'; import { ED, OakAbsAttrDef, onActionFnDef, OakExtraActionProps, OakAbsAttrJudgeDef } from '../../types/AbstractComponent';
import { analyzeAttrMobileForCard, translateAttributes } from '../../utils/usefulFn'; import { analyzeAttrMobileForCard, translateAttributes } from '../../utils/usefulFn';
import { assert } from 'oak-domain/lib/utils/assert'; import { assert } from 'oak-domain/lib/utils/assert';
import { TableProps, PaginationProps } from 'antd'; import { TableProps } from 'antd';
import { RowWithActions, ReactComponentProps } from '../../types/Page'; import { RowWithActions, ReactComponentProps } from '../../types/Page';
export default OakComponent({ export default OakComponent({
isList: false, isList: false,
properties: { properties: {
entity: '' as keyof ED, entity: '' as keyof ED,
extraActions: [] as OakExtraActionProps[] | ((row: any) => OakExtraActionProps[]), extraActions: [] as
onAction: (() => undefined) as Function, | OakExtraActionProps[]
| ((row: RowWithActions<ED, keyof ED>) => OakExtraActionProps[]),
onAction: (() => {}) as Function,
disabledOp: false, disabledOp: false,
attributes: [] as OakAbsAttrDef[], attributes: [] as OakAbsAttrDef[],
data: [] as RowWithActions<ED, keyof ED>[], data: [] as RowWithActions<ED, keyof ED>[],
@ -40,7 +42,7 @@ export default OakComponent({
return {}; return {};
}, },
data: { data: {
converter: (data: any) => <any>[], converter: (data: RowWithActions<ED, keyof ED>[]) => <any>[],
judgeAttributes: [] as OakAbsAttrJudgeDef[], judgeAttributes: [] as OakAbsAttrJudgeDef[],
}, },
listeners: { listeners: {
@ -62,9 +64,13 @@ export default OakComponent({
schema, schema,
entity, entity,
ttt, ttt,
attributes!, attributes!
);
const judgeAttributes = translateAttributes(
schema,
entity,
attributes!
); );
const judgeAttributes = translateAttributes(schema, entity, attributes!);
this.setState({ this.setState({
converter, converter,
schema, schema,
@ -92,7 +98,9 @@ export default OakComponent({
false, false,
{ {
entity: T2; entity: T2;
extraActions: OakExtraActionProps[] | ((row: ED2[T2]['Schema']) => OakExtraActionProps[]); extraActions:
| OakExtraActionProps[]
| ((row: ED2[T2]['Schema']) => OakExtraActionProps[]);
onAction: onActionFnDef; onAction: onActionFnDef;
disabledOp: boolean; disabledOp: boolean;
attributes: OakAbsAttrDef[]; attributes: OakAbsAttrDef[];

View File

@ -13,7 +13,7 @@ import { RelationAuth } from './relationAuth';
interface IMenu<ED extends EntityDict & BaseEntityDict, T extends keyof ED> { interface IMenu<ED extends EntityDict & BaseEntityDict, T extends keyof ED> {
name: string; name: string;
entity: T; entity: T;
action: ED[T]['Action']; action: ED[T]['Action'] | ED[T]['Action'][];
paths: string[]; paths: string[];
} }
@ -60,13 +60,13 @@ export class ContextMenuFactory<
} }
return; return;
} }
const pathhh = path.split('.'); const pathArr = path.split('.');
const judgeIter = ( const judgeIter = (
e2: keyof ED, e2: keyof ED,
idx: number idx: number
): true | undefined | ED[keyof ED]['Selection']['filter'] => { ): true | undefined | ED[keyof ED]['Selection']['filter'] => {
const attr = pathhh[idx]; const attr = pathArr[idx];
const rel = judgeRelation(schema, e2, attr); const rel = judgeRelation(schema, e2, attr);
let e3 = e2; let e3 = e2;
if (typeof rel === 'string') { if (typeof rel === 'string') {
@ -77,7 +77,7 @@ export class ContextMenuFactory<
assert(rel instanceof Array); assert(rel instanceof Array);
e3 = rel[0]; e3 = rel[0];
} }
if (idx === pathhh.length - 1) { if (idx === pathArr.length - 1) {
if (e3 === 'user') { if (e3 === 'user') {
// 用user连接说明一定满足 // 用user连接说明一定满足
return true; return true;
@ -85,7 +85,7 @@ export class ContextMenuFactory<
if (e3 === entity) { if (e3 === entity) {
const filter: ED[keyof ED]['Selection']['filter'] = const filter: ED[keyof ED]['Selection']['filter'] =
{}; {};
const paths2 = pathhh.slice(0, pathhh.length - 1); const paths2 = pathArr.slice(0, pathArr.length - 1);
if (rel === 2) { if (rel === 2) {
set(filter, paths2.concat('entity'), entity); set(filter, paths2.concat('entity'), entity);
set( set(
@ -140,6 +140,42 @@ export class ContextMenuFactory<
return true; return true;
} }
// relationAuth和其它的checker现在分开判断 // relationAuth和其它的checker现在分开判断
let result = false;
if (action instanceof Array) {
for (let i = 0; i < action.length; i++) {
// action有一个满足就行了
const checkResult =
this.relationAuth.checkRelation(
destEntity,
{
action: action[i],
data: undefined as any,
filter,
} as Omit<
ED[keyof ED]['Operation'],
'id'
>
) &&
this.cache.checkOperation(
destEntity,
action[i],
undefined,
filter,
[
'logical',
'relation',
'logicalRelation',
'row',
]
);
if (checkResult) {
result = checkResult;
break;
}
}
return result;
}
return ( return (
this.relationAuth.checkRelation(destEntity, { this.relationAuth.checkRelation(destEntity, {
action, action,

View File

@ -111,7 +111,9 @@ export function resolvePath<ED extends EntityDict & BaseEntityDict>(
} }
idx++; idx++;
} catch (err) { } catch (err) {
console.log(`存在非schema属性${path}`); if (process.env.NODE_ENV === 'development') {
console.warn(`存在非「${_entity as string}」schema属性: ${path}`);
}
return { return {
entity: 'notExist', entity: 'notExist',
attr: path, attr: path,