修改注册银行账户 地址以及 融合样式改动
This commit is contained in:
35
src/components/Authorized/Authorized.tsx
Normal file
35
src/components/Authorized/Authorized.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { Result } from 'antd';
|
||||
import check from './CheckPermissions';
|
||||
import type { IAuthorityType } from './CheckPermissions';
|
||||
import type AuthorizedRoute from './AuthorizedRoute';
|
||||
import type Secured from './Secured';
|
||||
|
||||
type AuthorizedProps = {
|
||||
authority: IAuthorityType;
|
||||
noMatch?: React.ReactNode;
|
||||
};
|
||||
|
||||
type IAuthorizedType = React.FunctionComponent<AuthorizedProps> & {
|
||||
Secured: typeof Secured;
|
||||
check: typeof check;
|
||||
AuthorizedRoute: typeof AuthorizedRoute;
|
||||
};
|
||||
|
||||
const Authorized: React.FunctionComponent<AuthorizedProps> = ({
|
||||
children,
|
||||
authority,
|
||||
noMatch = (
|
||||
<Result
|
||||
status="403"
|
||||
title="403"
|
||||
subTitle="Sorry, you are not authorized to access this page."
|
||||
/>
|
||||
),
|
||||
}) => {
|
||||
const childrenRender: React.ReactNode = typeof children === 'undefined' ? null : children;
|
||||
const dom = check(authority, childrenRender, noMatch);
|
||||
return <>{dom}</>;
|
||||
};
|
||||
|
||||
export default Authorized as IAuthorizedType;
|
33
src/components/Authorized/AuthorizedRoute.tsx
Normal file
33
src/components/Authorized/AuthorizedRoute.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { Redirect, Route } from 'umi';
|
||||
|
||||
import React from 'react';
|
||||
import Authorized from './Authorized';
|
||||
import type { IAuthorityType } from './CheckPermissions';
|
||||
|
||||
type AuthorizedRouteProps = {
|
||||
currentAuthority: string;
|
||||
component: React.ComponentClass<any, any>;
|
||||
render: (props: any) => React.ReactNode;
|
||||
redirectPath: string;
|
||||
authority: IAuthorityType;
|
||||
};
|
||||
|
||||
const AuthorizedRoute: React.SFC<AuthorizedRouteProps> = ({
|
||||
component: Component,
|
||||
render,
|
||||
authority,
|
||||
redirectPath,
|
||||
...rest
|
||||
}) => (
|
||||
<Authorized
|
||||
authority={authority}
|
||||
noMatch={<Route {...rest} render={() => <Redirect to={{ pathname: redirectPath }} />} />}
|
||||
>
|
||||
<Route
|
||||
{...rest}
|
||||
render={(props: any) => (Component ? <Component {...props} /> : render(props))}
|
||||
/>
|
||||
</Authorized>
|
||||
);
|
||||
|
||||
export default AuthorizedRoute;
|
88
src/components/Authorized/CheckPermissions.tsx
Normal file
88
src/components/Authorized/CheckPermissions.tsx
Normal file
@ -0,0 +1,88 @@
|
||||
import React from 'react';
|
||||
import { CURRENT } from './renderAuthorize';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import PromiseRender from './PromiseRender';
|
||||
|
||||
export type IAuthorityType =
|
||||
| undefined
|
||||
| string
|
||||
| string[]
|
||||
| Promise<boolean>
|
||||
| ((currentAuthority: string | string[]) => IAuthorityType);
|
||||
|
||||
/**
|
||||
* @en-US
|
||||
* General permission check method
|
||||
* Common check permissions method
|
||||
* @param {Permission judgment} authority
|
||||
* @param {Your permission | Your permission description} currentAuthority
|
||||
* @param {Passing components} target
|
||||
* @param {no pass components | no pass components} Exception
|
||||
* -------------------------------------------------------
|
||||
* @zh-CN
|
||||
* 通用权限检查方法 Common check permissions method
|
||||
*
|
||||
* @param { 权限判定 | Permission judgment } authority
|
||||
* @param { 你的权限 | Your permission description } currentAuthority
|
||||
* @param { 通过的组件 | Passing components } target
|
||||
* @param { 未通过的组件 | no pass components } Exception
|
||||
*/
|
||||
const checkPermissions = <T, K>(
|
||||
authority: IAuthorityType,
|
||||
currentAuthority: string | string[],
|
||||
target: T,
|
||||
Exception: K,
|
||||
): T | K | React.ReactNode => {
|
||||
// No judgment permission. View all by default
|
||||
// Retirement authority, return target;
|
||||
if (!authority) {
|
||||
return target;
|
||||
}
|
||||
// Array processing
|
||||
if (Array.isArray(authority)) {
|
||||
if (Array.isArray(currentAuthority)) {
|
||||
if (currentAuthority.some((item) => authority.includes(item))) {
|
||||
return target;
|
||||
}
|
||||
} else if (authority.includes(currentAuthority)) {
|
||||
return target;
|
||||
}
|
||||
return Exception;
|
||||
}
|
||||
// Deal with string
|
||||
if (typeof authority === 'string') {
|
||||
if (Array.isArray(currentAuthority)) {
|
||||
if (currentAuthority.some((item) => authority === item)) {
|
||||
return target;
|
||||
}
|
||||
} else if (authority === currentAuthority) {
|
||||
return target;
|
||||
}
|
||||
return Exception;
|
||||
}
|
||||
// Deal with promise
|
||||
if (authority instanceof Promise) {
|
||||
return <PromiseRender<T, K> ok={target} error={Exception} promise={authority} />;
|
||||
}
|
||||
// Deal with function
|
||||
if (typeof authority === 'function') {
|
||||
const bool = authority(currentAuthority);
|
||||
// The return value after the function is executed is Promise
|
||||
if (bool instanceof Promise) {
|
||||
return <PromiseRender<T, K> ok={target} error={Exception} promise={bool} />;
|
||||
}
|
||||
if (bool) {
|
||||
return target;
|
||||
}
|
||||
return Exception;
|
||||
}
|
||||
throw new Error('unsupported parameters');
|
||||
};
|
||||
|
||||
export { checkPermissions };
|
||||
|
||||
function check<T, K>(authority: IAuthorityType, target: T, Exception: K): T | K | React.ReactNode {
|
||||
return checkPermissions<T, K>(authority, CURRENT, target, Exception);
|
||||
}
|
||||
|
||||
export default check;
|
96
src/components/Authorized/PromiseRender.tsx
Normal file
96
src/components/Authorized/PromiseRender.tsx
Normal file
@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import { Spin } from 'antd';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { isComponentClass } from './Secured';
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
|
||||
type PromiseRenderProps<T, K> = {
|
||||
ok: T;
|
||||
error: K;
|
||||
promise: Promise<boolean>;
|
||||
};
|
||||
|
||||
type PromiseRenderState = {
|
||||
component: React.ComponentClass | React.FunctionComponent;
|
||||
};
|
||||
|
||||
export default class PromiseRender<T, K> extends React.Component<
|
||||
PromiseRenderProps<T, K>,
|
||||
PromiseRenderState
|
||||
> {
|
||||
state: PromiseRenderState = {
|
||||
component: () => null,
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
this.setRenderComponent(this.props);
|
||||
}
|
||||
|
||||
shouldComponentUpdate = (
|
||||
nextProps: PromiseRenderProps<T, K>,
|
||||
nextState: PromiseRenderState,
|
||||
): boolean => {
|
||||
const { component } = this.state;
|
||||
if (!isEqual(nextProps, this.props)) {
|
||||
this.setRenderComponent(nextProps);
|
||||
}
|
||||
if (nextState.component !== component) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
// set render Component : ok or error
|
||||
setRenderComponent(props: PromiseRenderProps<T, K>): void {
|
||||
const ok = this.checkIsInstantiation(props.ok);
|
||||
const error = this.checkIsInstantiation(props.error);
|
||||
props.promise
|
||||
.then(() => {
|
||||
this.setState({
|
||||
component: ok,
|
||||
});
|
||||
return true;
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({
|
||||
component: error,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Determine whether the incoming component has been instantiated
|
||||
// AuthorizedRoute is already instantiated
|
||||
// Authorized render is already instantiated, children is no instantiated
|
||||
// Secured is not instantiated
|
||||
checkIsInstantiation = (
|
||||
target: React.ReactNode | React.ComponentClass,
|
||||
): React.FunctionComponent => {
|
||||
if (isComponentClass(target)) {
|
||||
const Target = target as React.ComponentClass;
|
||||
return (props: any) => <Target {...props} />;
|
||||
}
|
||||
if (React.isValidElement(target)) {
|
||||
return (props: any) => React.cloneElement(target, props);
|
||||
}
|
||||
return () => target as React.ReactNode & null;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { component: Component } = this.state;
|
||||
const { ok, error, promise, ...rest } = this.props;
|
||||
|
||||
return Component ? (
|
||||
<Component {...rest} />
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: 'auto',
|
||||
paddingTop: 50,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
80
src/components/Authorized/Secured.tsx
Normal file
80
src/components/Authorized/Secured.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import CheckPermissions from './CheckPermissions';
|
||||
|
||||
/**
|
||||
* @en-US No pages can be accessed by default,default is "NULL"
|
||||
* @zh-CN 默认不能访问任何页面 default is "NULL"
|
||||
* */
|
||||
const Exception403 = () => 403;
|
||||
|
||||
export const isComponentClass = (component: React.ComponentClass | React.ReactNode): boolean => {
|
||||
if (!component) return false;
|
||||
const proto = Object.getPrototypeOf(component);
|
||||
if (proto === React.Component || proto === Function.prototype) return true;
|
||||
return isComponentClass(proto);
|
||||
};
|
||||
|
||||
// Determine whether the incoming component has been instantiated
|
||||
// AuthorizedRoute is already instantiated
|
||||
// Authorized render is already instantiated, children is no instantiated
|
||||
// Secured is not instantiated
|
||||
const checkIsInstantiation = (target: React.ComponentClass | React.ReactNode) => {
|
||||
if (isComponentClass(target)) {
|
||||
const Target = target as React.ComponentClass;
|
||||
return (props: any) => <Target {...props} />;
|
||||
}
|
||||
if (React.isValidElement(target)) {
|
||||
return (props: any) => React.cloneElement(target, props);
|
||||
}
|
||||
return () => target;
|
||||
};
|
||||
|
||||
/**
|
||||
* @en-US
|
||||
* Used to determine whether you have permission to access this view permission
|
||||
* authority supports incoming string, () => boolean | Promise
|
||||
* e.g.'user' Only user user can access
|
||||
* e.g.'user,admin' user and admin can access
|
||||
* e.g. ()=>boolean return true to access, return false to not access
|
||||
* e.g. Promise then can be accessed, catch can not be accessed
|
||||
* e.g. authority support incoming string, () => boolean | Promise
|
||||
* e.g.'user' only user user can access
|
||||
* e.g.'user, admin' user and admin can access
|
||||
* e.g. () => boolean true to be able to visit, return false can not be accessed
|
||||
* e.g. Promise then can not access the visit to catch
|
||||
*-------------------------------------------------------------
|
||||
* @zh-CN
|
||||
* 用于判断是否拥有权限访问此 view 权限 authority 支持传入 string, () => boolean | Promise e.g. 'user' 只有 user 用户能访问
|
||||
* e.g. 'user,admin' user 和 admin 都能访问 e.g. ()=>boolean 返回true能访问,返回false不能访问 e.g. Promise then 能访问
|
||||
* catch不能访问 e.g. authority support incoming string, () => boolean | Promise e.g. 'user' only user
|
||||
* user can access e.g. 'user, admin' user and admin can access e.g. () => boolean true to be able
|
||||
* to visit, return false can not be accessed e.g. Promise then can not access the visit to catch
|
||||
*
|
||||
* @param {string | function | Promise} authority
|
||||
* @param {ReactNode} error non-required parameter
|
||||
*/
|
||||
const authorize = (authority: string, error?: React.ReactNode) => {
|
||||
/**
|
||||
* @en-US
|
||||
* conversion into a class
|
||||
* Prevent the staticContext from being found to cause an error when the string is passed in
|
||||
* String parameters can cause staticContext not found error
|
||||
*-------------------------------------------------------------
|
||||
* @zh-CN
|
||||
* Conversion into a class 防止传入字符串时找不到staticContext造成报错 String parameters can cause staticContext
|
||||
* not found error
|
||||
*/
|
||||
let classError: boolean | React.FunctionComponent = false;
|
||||
if (error) {
|
||||
classError = (() => error) as React.FunctionComponent;
|
||||
}
|
||||
if (!authority) {
|
||||
throw new Error('authority is required');
|
||||
}
|
||||
return function decideAuthority(target: React.ComponentClass | React.ReactNode) {
|
||||
const component = CheckPermissions(authority, target, classError || Exception403);
|
||||
return checkIsInstantiation(component);
|
||||
};
|
||||
};
|
||||
|
||||
export default authorize;
|
11
src/components/Authorized/index.tsx
Normal file
11
src/components/Authorized/index.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import Authorized from './Authorized';
|
||||
import Secured from './Secured';
|
||||
import check from './CheckPermissions';
|
||||
import renderAuthorize from './renderAuthorize';
|
||||
|
||||
Authorized.Secured = Secured;
|
||||
Authorized.check = check;
|
||||
|
||||
const RenderAuthorize = renderAuthorize(Authorized);
|
||||
|
||||
export default RenderAuthorize;
|
31
src/components/Authorized/renderAuthorize.ts
Normal file
31
src/components/Authorized/renderAuthorize.ts
Normal file
@ -0,0 +1,31 @@
|
||||
/* eslint-disable eslint-comments/disable-enable-pair */
|
||||
/* eslint-disable import/no-mutable-exports */
|
||||
let CURRENT: string | string[] = 'NULL';
|
||||
|
||||
type CurrentAuthorityType = string | string[] | (() => typeof CURRENT);
|
||||
/**
|
||||
* Use authority or getAuthority
|
||||
*
|
||||
* @param {string|()=>String} currentAuthority
|
||||
*/
|
||||
const renderAuthorize = <T>(Authorized: T): ((currentAuthority: CurrentAuthorityType) => T) => (
|
||||
currentAuthority: CurrentAuthorityType,
|
||||
): T => {
|
||||
if (currentAuthority) {
|
||||
if (typeof currentAuthority === 'function') {
|
||||
CURRENT = currentAuthority();
|
||||
}
|
||||
if (
|
||||
Object.prototype.toString.call(currentAuthority) === '[object String]' ||
|
||||
Array.isArray(currentAuthority)
|
||||
) {
|
||||
CURRENT = currentAuthority as string[];
|
||||
}
|
||||
} else {
|
||||
CURRENT = 'NULL';
|
||||
}
|
||||
return Authorized;
|
||||
};
|
||||
|
||||
export { CURRENT };
|
||||
export default <T>(Authorized: T) => renderAuthorize<T>(Authorized);
|
Reference in New Issue
Block a user