移除react-router-dom 对pageheader和errorpage 进行调整

This commit is contained in:
Wang Kejun 2023-09-27 13:14:17 +08:00
parent c4c5663dee
commit 62e7891a81
37 changed files with 594 additions and 359 deletions

View File

@ -1,2 +1,12 @@
declare const _default: string;
import { EntityDict } from '../../../oak-app-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
import { ECode } from '../../../types/ErrorPage';
declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(props: ReactComponentProps<ED2, T2, false, {
code: ECode;
title?: string | undefined;
desc?: string | undefined;
children?: React.ReactNode;
icon?: React.ReactNode;
}>) => React.ReactElement;
export default _default;

View File

@ -1,12 +1,4 @@
var ECode;
(function (ECode) {
ECode["forbidden"] = "403";
ECode["notFound"] = "404";
ECode["error"] = "500";
ECode["networkError"] = "network-error";
ECode["maintenance"] = "maintenance";
})(ECode || (ECode = {}));
;
import { ECode } from '../../../types/ErrorPage';
const DefaultErrorInfo = {
[ECode.forbidden]: {
title: '403 Forbidden',
@ -33,36 +25,45 @@ const DefaultErrorInfo = {
desc: '系统维护中,请稍后再试。',
imagePath: './assets/svg/assets-result-maintenance.svg',
},
[ECode.browserIncompatible]: {
title: '浏览器版本低',
desc: '抱歉,您正在使用的浏览器版本过低,无法打开当前网页。',
imagePath: './assets/svg/assets-result-browser-incompatible.svg',
},
};
export default Component({
export default OakComponent({
isList: false,
properties: {
code: String,
title: String,
desc: String,
icon: String,
imagePath: String,
code: '',
title: '',
desc: '',
icon: '',
imagePath: '', //小程序独有
},
lifetimes: {
ready() {
const { title, desc, code, imagePath } = this.data;
let title2 = title;
if (code) {
this.setData({
desc: desc || DefaultErrorInfo[code].desc,
imagePath: imagePath || DefaultErrorInfo[code].imagePath,
});
if (!title2) {
title2 = DefaultErrorInfo[code].title;
if (process.env.OAK_PLATFORM === 'wechatMp') {
const { title, desc, code, imagePath } = this.props;
let title2 = title;
if (code) {
this.setState({
desc: desc || DefaultErrorInfo[code].desc,
imagePath: imagePath ||
DefaultErrorInfo[code].imagePath,
});
if (!title2) {
title2 = DefaultErrorInfo[code].title;
}
wx.setNavigationBarTitle({
title: title2,
});
}
wx.setNavigationBarTitle({
title: title2,
});
}
}
},
},
methods: {
goBack() {
wx.navigateBack();
}
}
goBack(delta) {
this.navigateBack(delta);
},
},
});

View File

@ -1,13 +1,8 @@
import React from 'react';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import { ECode } from '../../../types/ErrorPage';
import './web.less';
export declare enum ECode {
forbidden = "403",
notFound = "404",
error = "500",
networkError = "network-error",
browserIncompatible = "browser-incompatible",
maintenance = "maintenance"
}
interface IErrorPageProps {
code: ECode;
title?: string;
@ -15,5 +10,7 @@ interface IErrorPageProps {
children?: React.ReactNode;
icon?: React.ReactNode;
}
declare function ErrorPage(props: IErrorPageProps): import("react/jsx-runtime").JSX.Element;
export default ErrorPage;
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, IErrorPageProps, {
goBack: (delta?: number) => void;
}>): import("react/jsx-runtime").JSX.Element;
export {};

View File

@ -1,7 +1,6 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Button } from 'antd';
// @ts-ignore
import { useNavigate } from 'react-router-dom';
import { ECode } from '../../../types/ErrorPage';
import { ReactComponent as Light403Icon } from './assets/svg/assets-result-403.svg';
import { ReactComponent as Light404Icon } from './assets/svg/assets-result-404.svg';
import { ReactComponent as Light500Icon } from './assets/svg/assets-result-500.svg';
@ -9,15 +8,6 @@ import { ReactComponent as LightMaintenanceIcon } from './assets/svg/assets-resu
import { ReactComponent as LightBrowserIncompatibleIcon } from './assets/svg/assets-result-browser-incompatible.svg';
import { ReactComponent as LightNetworkErrorIcon } from './assets/svg/assets-result-network-error.svg';
import './web.less';
export var ECode;
(function (ECode) {
ECode["forbidden"] = "403";
ECode["notFound"] = "404";
ECode["error"] = "500";
ECode["networkError"] = "network-error";
ECode["browserIncompatible"] = "browser-incompatible";
ECode["maintenance"] = "maintenance";
})(ECode || (ECode = {}));
const errorInfo = {
[ECode.forbidden]: {
title: '403 Forbidden',
@ -50,13 +40,12 @@ const errorInfo = {
icon: _jsx(LightMaintenanceIcon, {}),
},
};
function ErrorPage(props) {
const navigate = useNavigate();
const { code } = props;
export default function Render(props) {
const { code, icon, title, desc, children } = props.data;
const { t, goBack } = props.methods;
const info = errorInfo[code];
const prefixCls = 'oak';
return (_jsxs("div", { className: `${prefixCls}-errorBox`, children: [props.icon || info?.icon, _jsx("div", { className: `${prefixCls}-errorBox__title`, children: props.title || info?.title }), _jsx("div", { className: `${prefixCls}-errorBox__description`, children: props.desc || info?.desc }), props.children || (_jsx(Button, { type: "primary", onClick: () => {
navigate(-1);
return (_jsxs("div", { className: `${prefixCls}-errorBox`, children: [icon || info?.icon, _jsx("div", { className: `${prefixCls}-errorBox__title`, children: title || info?.title }), _jsx("div", { className: `${prefixCls}-errorBox__description`, children: desc || info?.desc }), children || (_jsx(Button, { type: "primary", onClick: () => {
goBack();
}, children: "\u8FD4\u56DE" }))] }));
}
export default ErrorPage;

View File

@ -1,21 +1,22 @@
import React from 'react';
import './index.less';
type PageHeaderProps = {
style?: React.CSSProperties;
className?: string;
/// <reference types="react" />
import { EntityDict } from '../../../oak-app-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(props: ReactComponentProps<ED2, T2, false, {
style?: import("react").CSSProperties | undefined;
className?: string | undefined;
title?: React.ReactNode;
showBack?: boolean;
onBack?: () => void;
showBack?: boolean | undefined;
onBack?: (() => void) | undefined;
backIcon?: React.ReactNode;
delta?: number;
delta?: number | undefined;
extra?: React.ReactNode;
subTitle?: React.ReactNode;
contentMargin?: boolean;
contentStyle?: React.CSSProperties;
contentClassName?: string;
contentMargin?: boolean | undefined;
contentStyle?: import("react").CSSProperties | undefined;
contentClassName?: string | undefined;
tags?: React.ReactNode;
children?: React.ReactNode;
showHeader?: boolean;
};
declare const _default: React.MemoExoticComponent<(props: PageHeaderProps) => import("react/jsx-runtime").JSX.Element>;
showHeader?: boolean | undefined;
}>) => React.ReactElement;
export default _default;

View File

@ -1,22 +1,8 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { memo } from 'react';
// @ts-ignore
import { useNavigate } from 'react-router-dom';
import { Row, Col, Button } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import './index.less';
export default memo((props) => {
const { style, className, children, title, subTitle, extra, showBack = false, onBack, backIcon, delta, contentMargin = true, contentStyle, contentClassName, tags, showHeader = true, } = props;
const prefixCls = 'oak';
const navigate = useNavigate();
return (_jsxs("div", { style: style, className: classNames(`${prefixCls}-pageHeader`, className), children: [showHeader && (title || showBack || subTitle || tags || extra) && (_jsx("div", { className: `${prefixCls}-pageHeader-header`, children: _jsxs(Row, { justify: "center", children: [_jsxs(Col, { flex: "auto", className: `${prefixCls}-pageHeader-header-col`, children: [showBack && (_jsx(Button, { type: "text", className: `${prefixCls}-pageHeader-header-back`, onClick: () => {
if (typeof onBack === 'function') {
onBack();
return;
}
navigate(delta || -1);
}, children: backIcon || (_jsx(ArrowLeftOutlined, { className: `${prefixCls}-pageHeader-header-backIcon` })) })), title && (_jsx("span", { className: `${prefixCls}-pageHeader-header-title`, children: title })), subTitle && (_jsx("span", { className: `${prefixCls}-pageHeader-header-subTitle`, children: subTitle })), tags] }), _jsx(Col, { flex: "auto", children: extra })] }) })), _jsx("div", { style: contentStyle, className: classNames(`${prefixCls}-pageHeader-content`, contentClassName, {
[`${prefixCls}-pageHeader-content-margin`]: contentMargin,
}), children: children })] }));
export default OakComponent({
isList: false,
methods: {
goBack(delta) {
this.navigateBack(delta);
},
},
});

View File

@ -0,0 +1,25 @@
import React from 'react';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import './index.less';
type PageHeaderProps = {
style?: React.CSSProperties;
className?: string;
title?: React.ReactNode;
showBack?: boolean;
onBack?: () => void;
backIcon?: React.ReactNode;
delta?: number;
extra?: React.ReactNode;
subTitle?: React.ReactNode;
contentMargin?: boolean;
contentStyle?: React.CSSProperties;
contentClassName?: string;
tags?: React.ReactNode;
children?: React.ReactNode;
showHeader?: boolean;
};
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, PageHeaderProps, {
goBack: (delta?: number) => void;
}>): import("react/jsx-runtime").JSX.Element;
export {};

View File

@ -0,0 +1,19 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Row, Col, Button } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import './index.less';
export default function Render(props) {
const { style, className, children, title, subTitle, extra, showBack = false, onBack, backIcon, delta, contentMargin = true, contentStyle, contentClassName, tags, showHeader = true, } = props.data;
const { t, goBack } = props.methods;
const prefixCls = 'oak';
return (_jsxs("div", { style: style, className: classNames(`${prefixCls}-pageHeader`, className), children: [showHeader && (title || showBack || subTitle || tags || extra) && (_jsx("div", { className: `${prefixCls}-pageHeader-header`, children: _jsxs(Row, { justify: "center", children: [_jsxs(Col, { flex: "auto", className: `${prefixCls}-pageHeader-header-col`, children: [showBack && (_jsx(Button, { type: "text", className: `${prefixCls}-pageHeader-header-back`, onClick: () => {
if (typeof onBack === 'function') {
onBack();
return;
}
goBack(delta);
}, children: backIcon || (_jsx(ArrowLeftOutlined, { className: `${prefixCls}-pageHeader-header-backIcon` })) })), title && (_jsx("span", { className: `${prefixCls}-pageHeader-header-title`, children: title })), subTitle && (_jsx("span", { className: `${prefixCls}-pageHeader-header-subTitle`, children: subTitle })), tags] }), _jsx(Col, { flex: "auto", children: extra })] }) })), _jsx("div", { style: contentStyle, className: classNames(`${prefixCls}-pageHeader-content`, contentClassName, {
[`${prefixCls}-pageHeader-content-margin`]: contentMargin,
}), children: children })] }));
}

View File

@ -3,21 +3,26 @@ import { List, Avatar, Tag, Button, Input } from 'antd-mobile';
import { UserCircleOutline } from 'antd-mobile-icons';
import Style from './mobile.module.less';
export default function Render(props) {
const { t, goUpsert, goUpdate, addNamedFilter, refresh, removeNamedFilterByName } = props.methods;
const { t, goUpsert, goUpdate, addNamedFilter, refresh, removeNamedFilterByName, } = props.methods;
const { entity, users, searchValue } = props.data;
return (_jsxs("div", { className: Style.container, children: [_jsxs("span", { className: Style.header, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(Input, { placeholder: t('search'), value: searchValue, onChange: value => {
return (_jsxs("div", { className: Style.container, children: [_jsxs("span", { className: Style.header, children: [_jsx("div", { style: { flex: 1 }, children: _jsx(Input, { placeholder: t('search'), value: searchValue, onChange: (value) => {
addNamedFilter({
'#name': 'name',
filter: {
$text: {
$search: value,
}
}
},
},
}, false);
}, onEnterPress: () => refresh(), clearable: true, onClear: () => removeNamedFilterByName('name') }) }), _jsx(Button, { size: 'small', color: 'primary', onClick: () => goUpsert(), children: t('common::action.create') })] }), _jsx(List, { children: users?.map((ele, index) => {
return (_jsx(List.Item, { prefix: ele.avatar ? _jsx(Avatar, { className: Style.avatar, src: ele.avatar }) : _jsx(UserCircleOutline, { className: Style.avatar }), extra: ele.mobile || '--', description: _jsx("div", { style: {
}, onEnterPress: () => refresh(), clearable: true, onClear: () => removeNamedFilterByName('name') }) }), _jsx(Button, { size: "small", color: "primary", onClick: () => goUpsert(), children: t('common::action.create') })] }), _jsx(List, { children: users?.map((ele, index) => {
return (_jsx(List.Item, { prefix: ele.avatar ? (_jsx(Avatar, { className: Style.avatar, src: ele.avatar })) : (_jsx(UserCircleOutline, { className: Style.avatar })), extra: ele.mobile || '--', description: _jsx("div", { style: {
display: 'flex',
flexWrap: 'wrap',
}, children: ele.userRelation$user?.map((ele2, index2) => (_jsx(Tag, { fill: "outline", children: ele2.relation?.name ? t(entity + ':r.' + ele2.relation.name) : ele2.relation?.display }, index))) }), onClick: () => goUpdate(ele.id), children: ele.name || ele.nickname || '--' }));
}, children: ele.userRelation$user?.map((ele2, index2) => (_jsx(Tag, { fill: "outline", children: ele2.relation?.name
? t(entity +
':r.' +
ele2.relation
.name)
: ele2.relation?.display }, index))) }), onClick: () => goUpdate(ele.id), children: ele.name || ele.nickname || '--' }));
}) })] }));
}

View File

@ -7,6 +7,7 @@ import { AppType } from '../oak-app-domain/Application/Schema';
import AspectDict from '../aspects/AspectDict';
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
import { FrontendRuntimeContext } from '../context/FrontendRuntimeContext';
import { MediaType, MediaVideoDescription } from '../types/WeChat';
export declare class Application<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>, FrontCxt extends FrontendRuntimeContext<ED, Cxt, AD>, AD extends AspectDict<ED, Cxt> & CommonAspectDict<ED, Cxt>> extends Feature {
private type;
private domain;
@ -22,5 +23,11 @@ export declare class Application<ED extends EntityDict, Cxt extends BackendRunti
initialize(appId?: string | null, projection?: EntityDict['application']['Selection']['data']): Promise<void>;
getApplication(): Partial<import("../oak-app-domain/Application/Schema").Schema> | undefined;
getApplicationId(): string | undefined;
uploadWechatMedia(formData: FormData): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["uploadWechatMedia"]>>;
uploadWechatMedia(params: {
applicationId: string;
file: File;
type: MediaType;
isPermanent?: boolean;
description?: MediaVideoDescription;
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["uploadWechatMedia"]>>;
}

View File

@ -77,15 +77,18 @@ export class Application extends Feature {
getApplicationId() {
return this.applicationId;
}
async uploadWechatMedia(
// params: {
// applicationId: string;
// file: any;
// type: MediaType;
// isPermanent?: boolean; //上传临时素材 或永久素材
// description?: MediaVideoDescription;
// }
formData) {
async uploadWechatMedia(params) {
const { applicationId, type, file, description, isPermanent = false, } = params;
const formData = new FormData();
formData.append('applicationId', applicationId);
formData.append('type', type);
formData.append('file', file);
if (description) {
formData.append('description', JSON.stringify(description));
}
if (isPermanent) {
formData.append('isPermanent', `${isPermanent}`);
}
const callBack = await this.cache.exec('uploadWechatMedia', formData);
return callBack.result;
}

View File

@ -24,6 +24,6 @@ export function initialize(basicFeatures, type, domain) {
config,
weiXinJsSdk,
theme,
wechatMenu
wechatMenu,
};
}

8
es/types/ErrorPage.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
export declare enum ECode {
forbidden = "403",
notFound = "404",
error = "500",
networkError = "network-error",
browserIncompatible = "browser-incompatible",
maintenance = "maintenance"
}

9
es/types/ErrorPage.js Normal file
View File

@ -0,0 +1,9 @@
export var ECode;
(function (ECode) {
ECode["forbidden"] = "403";
ECode["notFound"] = "404";
ECode["error"] = "500";
ECode["networkError"] = "network-error";
ECode["browserIncompatible"] = "browser-incompatible";
ECode["maintenance"] = "maintenance";
})(ECode || (ECode = {}));

View File

@ -1,2 +1,12 @@
declare const _default: string;
import { EntityDict } from '../../../oak-app-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
import { ECode } from '../../../types/ErrorPage';
declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(props: ReactComponentProps<ED2, T2, false, {
code: ECode;
title?: string | undefined;
desc?: string | undefined;
children?: React.ReactNode;
icon?: React.ReactNode;
}>) => React.ReactElement;
export default _default;

View File

@ -1,70 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ECode;
(function (ECode) {
ECode["forbidden"] = "403";
ECode["notFound"] = "404";
ECode["error"] = "500";
ECode["networkError"] = "network-error";
ECode["maintenance"] = "maintenance";
})(ECode || (ECode = {}));
;
const ErrorPage_1 = require("../../../types/ErrorPage");
const DefaultErrorInfo = {
[ECode.forbidden]: {
[ErrorPage_1.ECode.forbidden]: {
title: '403 Forbidden',
desc: '抱歉,您无权限访问此页面',
imagePath: './assets/svg/assets-result-403.svg',
},
[ECode.notFound]: {
[ErrorPage_1.ECode.notFound]: {
title: '404 Not Found',
desc: '抱歉,您访问的页面不存在。',
imagePath: './assets/svg/assets-result-404.svg',
},
[ECode.error]: {
[ErrorPage_1.ECode.error]: {
title: '500 Internal Server Error',
desc: '抱歉,服务器出错啦!',
imagePath: './assets/svg/assets-result-500.svg',
},
[ECode.networkError]: {
[ErrorPage_1.ECode.networkError]: {
title: '网络异常',
desc: '网络异常,请稍后再试',
imagePath: './assets/svg/assets-result-network-error.svg',
},
[ECode.maintenance]: {
[ErrorPage_1.ECode.maintenance]: {
title: '系统维护中',
desc: '系统维护中,请稍后再试。',
imagePath: './assets/svg/assets-result-maintenance.svg',
},
[ErrorPage_1.ECode.browserIncompatible]: {
title: '浏览器版本低',
desc: '抱歉,您正在使用的浏览器版本过低,无法打开当前网页。',
imagePath: './assets/svg/assets-result-browser-incompatible.svg',
},
};
exports.default = Component({
exports.default = OakComponent({
isList: false,
properties: {
code: String,
title: String,
desc: String,
icon: String,
imagePath: String,
code: '',
title: '',
desc: '',
icon: '',
imagePath: '', //小程序独有
},
lifetimes: {
ready() {
const { title, desc, code, imagePath } = this.data;
let title2 = title;
if (code) {
this.setData({
desc: desc || DefaultErrorInfo[code].desc,
imagePath: imagePath || DefaultErrorInfo[code].imagePath,
});
if (!title2) {
title2 = DefaultErrorInfo[code].title;
if (process.env.OAK_PLATFORM === 'wechatMp') {
const { title, desc, code, imagePath } = this.props;
let title2 = title;
if (code) {
this.setState({
desc: desc || DefaultErrorInfo[code].desc,
imagePath: imagePath ||
DefaultErrorInfo[code].imagePath,
});
if (!title2) {
title2 = DefaultErrorInfo[code].title;
}
wx.setNavigationBarTitle({
title: title2,
});
}
wx.setNavigationBarTitle({
title: title2,
});
}
}
},
},
methods: {
goBack() {
wx.navigateBack();
}
}
goBack(delta) {
this.navigateBack(delta);
},
},
});

View File

@ -1,13 +1,8 @@
import React from 'react';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import { ECode } from '../../../types/ErrorPage';
import './web.less';
export declare enum ECode {
forbidden = "403",
notFound = "404",
error = "500",
networkError = "network-error",
browserIncompatible = "browser-incompatible",
maintenance = "maintenance"
}
interface IErrorPageProps {
code: ECode;
title?: string;
@ -15,5 +10,7 @@ interface IErrorPageProps {
children?: React.ReactNode;
icon?: React.ReactNode;
}
declare function ErrorPage(props: IErrorPageProps): import("react/jsx-runtime").JSX.Element;
export default ErrorPage;
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, IErrorPageProps, {
goBack: (delta?: number) => void;
}>): import("react/jsx-runtime").JSX.Element;
export {};

View File

@ -1,10 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ECode = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const antd_1 = require("antd");
// @ts-ignore
const react_router_dom_1 = require("react-router-dom");
const ErrorPage_1 = require("../../../types/ErrorPage");
const assets_result_403_svg_1 = require("./assets/svg/assets-result-403.svg");
const assets_result_404_svg_1 = require("./assets/svg/assets-result-404.svg");
const assets_result_500_svg_1 = require("./assets/svg/assets-result-500.svg");
@ -12,54 +10,45 @@ const assets_result_maintenance_svg_1 = require("./assets/svg/assets-result-main
const assets_result_browser_incompatible_svg_1 = require("./assets/svg/assets-result-browser-incompatible.svg");
const assets_result_network_error_svg_1 = require("./assets/svg/assets-result-network-error.svg");
require("./web.less");
var ECode;
(function (ECode) {
ECode["forbidden"] = "403";
ECode["notFound"] = "404";
ECode["error"] = "500";
ECode["networkError"] = "network-error";
ECode["browserIncompatible"] = "browser-incompatible";
ECode["maintenance"] = "maintenance";
})(ECode || (exports.ECode = ECode = {}));
const errorInfo = {
[ECode.forbidden]: {
[ErrorPage_1.ECode.forbidden]: {
title: '403 Forbidden',
desc: '抱歉,您无权限访问此页面',
icon: (0, jsx_runtime_1.jsx)(assets_result_403_svg_1.ReactComponent, {}),
},
[ECode.notFound]: {
[ErrorPage_1.ECode.notFound]: {
title: '404 Not Found',
desc: '抱歉,您访问的页面不存在。',
icon: (0, jsx_runtime_1.jsx)(assets_result_404_svg_1.ReactComponent, {}),
},
[ECode.error]: {
[ErrorPage_1.ECode.error]: {
title: '500 Internal Server Error',
desc: '抱歉,服务器出错啦!',
icon: (0, jsx_runtime_1.jsx)(assets_result_500_svg_1.ReactComponent, {}),
},
[ECode.networkError]: {
[ErrorPage_1.ECode.networkError]: {
title: '网络异常',
desc: '网络异常,请稍后再试',
icon: (0, jsx_runtime_1.jsx)(assets_result_network_error_svg_1.ReactComponent, {}),
},
[ECode.browserIncompatible]: {
[ErrorPage_1.ECode.browserIncompatible]: {
title: '浏览器版本低',
desc: '抱歉,您正在使用的浏览器版本过低,无法打开当前网页。',
icon: (0, jsx_runtime_1.jsx)(assets_result_browser_incompatible_svg_1.ReactComponent, {}),
},
[ECode.maintenance]: {
[ErrorPage_1.ECode.maintenance]: {
title: '系统维护中',
desc: '系统维护中,请稍后再试。',
icon: (0, jsx_runtime_1.jsx)(assets_result_maintenance_svg_1.ReactComponent, {}),
},
};
function ErrorPage(props) {
const navigate = (0, react_router_dom_1.useNavigate)();
const { code } = props;
function Render(props) {
const { code, icon, title, desc, children } = props.data;
const { t, goBack } = props.methods;
const info = errorInfo[code];
const prefixCls = 'oak';
return ((0, jsx_runtime_1.jsxs)("div", { className: `${prefixCls}-errorBox`, children: [props.icon || info?.icon, (0, jsx_runtime_1.jsx)("div", { className: `${prefixCls}-errorBox__title`, children: props.title || info?.title }), (0, jsx_runtime_1.jsx)("div", { className: `${prefixCls}-errorBox__description`, children: props.desc || info?.desc }), props.children || ((0, jsx_runtime_1.jsx)(antd_1.Button, { type: "primary", onClick: () => {
navigate(-1);
return ((0, jsx_runtime_1.jsxs)("div", { className: `${prefixCls}-errorBox`, children: [icon || info?.icon, (0, jsx_runtime_1.jsx)("div", { className: `${prefixCls}-errorBox__title`, children: title || info?.title }), (0, jsx_runtime_1.jsx)("div", { className: `${prefixCls}-errorBox__description`, children: desc || info?.desc }), children || ((0, jsx_runtime_1.jsx)(antd_1.Button, { type: "primary", onClick: () => {
goBack();
}, children: "\u8FD4\u56DE" }))] }));
}
exports.default = ErrorPage;
exports.default = Render;

View File

@ -1,21 +1,22 @@
import React from 'react';
import './index.less';
type PageHeaderProps = {
style?: React.CSSProperties;
className?: string;
/// <reference types="react" />
import { EntityDict } from '../../../oak-app-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(props: ReactComponentProps<ED2, T2, false, {
style?: import("react").CSSProperties | undefined;
className?: string | undefined;
title?: React.ReactNode;
showBack?: boolean;
onBack?: () => void;
showBack?: boolean | undefined;
onBack?: (() => void) | undefined;
backIcon?: React.ReactNode;
delta?: number;
delta?: number | undefined;
extra?: React.ReactNode;
subTitle?: React.ReactNode;
contentMargin?: boolean;
contentStyle?: React.CSSProperties;
contentClassName?: string;
contentMargin?: boolean | undefined;
contentStyle?: import("react").CSSProperties | undefined;
contentClassName?: string | undefined;
tags?: React.ReactNode;
children?: React.ReactNode;
showHeader?: boolean;
};
declare const _default: React.MemoExoticComponent<(props: PageHeaderProps) => import("react/jsx-runtime").JSX.Element>;
showHeader?: boolean | undefined;
}>) => React.ReactElement;
export default _default;

View File

@ -1,25 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
// @ts-ignore
const react_router_dom_1 = require("react-router-dom");
const antd_1 = require("antd");
const icons_1 = require("@ant-design/icons");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
require("./index.less");
exports.default = (0, react_1.memo)((props) => {
const { style, className, children, title, subTitle, extra, showBack = false, onBack, backIcon, delta, contentMargin = true, contentStyle, contentClassName, tags, showHeader = true, } = props;
const prefixCls = 'oak';
const navigate = (0, react_router_dom_1.useNavigate)();
return ((0, jsx_runtime_1.jsxs)("div", { style: style, className: (0, classnames_1.default)(`${prefixCls}-pageHeader`, className), children: [showHeader && (title || showBack || subTitle || tags || extra) && ((0, jsx_runtime_1.jsx)("div", { className: `${prefixCls}-pageHeader-header`, children: (0, jsx_runtime_1.jsxs)(antd_1.Row, { justify: "center", children: [(0, jsx_runtime_1.jsxs)(antd_1.Col, { flex: "auto", className: `${prefixCls}-pageHeader-header-col`, children: [showBack && ((0, jsx_runtime_1.jsx)(antd_1.Button, { type: "text", className: `${prefixCls}-pageHeader-header-back`, onClick: () => {
if (typeof onBack === 'function') {
onBack();
return;
}
navigate(delta || -1);
}, children: backIcon || ((0, jsx_runtime_1.jsx)(icons_1.ArrowLeftOutlined, { className: `${prefixCls}-pageHeader-header-backIcon` })) })), title && ((0, jsx_runtime_1.jsx)("span", { className: `${prefixCls}-pageHeader-header-title`, children: title })), subTitle && ((0, jsx_runtime_1.jsx)("span", { className: `${prefixCls}-pageHeader-header-subTitle`, children: subTitle })), tags] }), (0, jsx_runtime_1.jsx)(antd_1.Col, { flex: "auto", children: extra })] }) })), (0, jsx_runtime_1.jsx)("div", { style: contentStyle, className: (0, classnames_1.default)(`${prefixCls}-pageHeader-content`, contentClassName, {
[`${prefixCls}-pageHeader-content-margin`]: contentMargin,
}), children: children })] }));
exports.default = OakComponent({
isList: false,
methods: {
goBack(delta) {
this.navigateBack(delta);
},
},
});

View File

@ -0,0 +1,25 @@
import React from 'react';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import './index.less';
type PageHeaderProps = {
style?: React.CSSProperties;
className?: string;
title?: React.ReactNode;
showBack?: boolean;
onBack?: () => void;
backIcon?: React.ReactNode;
delta?: number;
extra?: React.ReactNode;
subTitle?: React.ReactNode;
contentMargin?: boolean;
contentStyle?: React.CSSProperties;
contentClassName?: string;
tags?: React.ReactNode;
children?: React.ReactNode;
showHeader?: boolean;
};
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, PageHeaderProps, {
goBack: (delta?: number) => void;
}>): import("react/jsx-runtime").JSX.Element;
export {};

View File

@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const antd_1 = require("antd");
const icons_1 = require("@ant-design/icons");
const classnames_1 = tslib_1.__importDefault(require("classnames"));
require("./index.less");
function Render(props) {
const { style, className, children, title, subTitle, extra, showBack = false, onBack, backIcon, delta, contentMargin = true, contentStyle, contentClassName, tags, showHeader = true, } = props.data;
const { t, goBack } = props.methods;
const prefixCls = 'oak';
return ((0, jsx_runtime_1.jsxs)("div", { style: style, className: (0, classnames_1.default)(`${prefixCls}-pageHeader`, className), children: [showHeader && (title || showBack || subTitle || tags || extra) && ((0, jsx_runtime_1.jsx)("div", { className: `${prefixCls}-pageHeader-header`, children: (0, jsx_runtime_1.jsxs)(antd_1.Row, { justify: "center", children: [(0, jsx_runtime_1.jsxs)(antd_1.Col, { flex: "auto", className: `${prefixCls}-pageHeader-header-col`, children: [showBack && ((0, jsx_runtime_1.jsx)(antd_1.Button, { type: "text", className: `${prefixCls}-pageHeader-header-back`, onClick: () => {
if (typeof onBack === 'function') {
onBack();
return;
}
goBack(delta);
}, children: backIcon || ((0, jsx_runtime_1.jsx)(icons_1.ArrowLeftOutlined, { className: `${prefixCls}-pageHeader-header-backIcon` })) })), title && ((0, jsx_runtime_1.jsx)("span", { className: `${prefixCls}-pageHeader-header-title`, children: title })), subTitle && ((0, jsx_runtime_1.jsx)("span", { className: `${prefixCls}-pageHeader-header-subTitle`, children: subTitle })), tags] }), (0, jsx_runtime_1.jsx)(antd_1.Col, { flex: "auto", children: extra })] }) })), (0, jsx_runtime_1.jsx)("div", { style: contentStyle, className: (0, classnames_1.default)(`${prefixCls}-pageHeader-content`, contentClassName, {
[`${prefixCls}-pageHeader-content-margin`]: contentMargin,
}), children: children })] }));
}
exports.default = Render;

View File

@ -6,22 +6,27 @@ const antd_mobile_1 = require("antd-mobile");
const antd_mobile_icons_1 = require("antd-mobile-icons");
const mobile_module_less_1 = tslib_1.__importDefault(require("./mobile.module.less"));
function Render(props) {
const { t, goUpsert, goUpdate, addNamedFilter, refresh, removeNamedFilterByName } = props.methods;
const { t, goUpsert, goUpdate, addNamedFilter, refresh, removeNamedFilterByName, } = props.methods;
const { entity, users, searchValue } = props.data;
return ((0, jsx_runtime_1.jsxs)("div", { className: mobile_module_less_1.default.container, children: [(0, jsx_runtime_1.jsxs)("span", { className: mobile_module_less_1.default.header, children: [(0, jsx_runtime_1.jsx)("div", { style: { flex: 1 }, children: (0, jsx_runtime_1.jsx)(antd_mobile_1.Input, { placeholder: t('search'), value: searchValue, onChange: value => {
return ((0, jsx_runtime_1.jsxs)("div", { className: mobile_module_less_1.default.container, children: [(0, jsx_runtime_1.jsxs)("span", { className: mobile_module_less_1.default.header, children: [(0, jsx_runtime_1.jsx)("div", { style: { flex: 1 }, children: (0, jsx_runtime_1.jsx)(antd_mobile_1.Input, { placeholder: t('search'), value: searchValue, onChange: (value) => {
addNamedFilter({
'#name': 'name',
filter: {
$text: {
$search: value,
}
}
},
},
}, false);
}, onEnterPress: () => refresh(), clearable: true, onClear: () => removeNamedFilterByName('name') }) }), (0, jsx_runtime_1.jsx)(antd_mobile_1.Button, { size: 'small', color: 'primary', onClick: () => goUpsert(), children: t('common::action.create') })] }), (0, jsx_runtime_1.jsx)(antd_mobile_1.List, { children: users?.map((ele, index) => {
return ((0, jsx_runtime_1.jsx)(antd_mobile_1.List.Item, { prefix: ele.avatar ? (0, jsx_runtime_1.jsx)(antd_mobile_1.Avatar, { className: mobile_module_less_1.default.avatar, src: ele.avatar }) : (0, jsx_runtime_1.jsx)(antd_mobile_icons_1.UserCircleOutline, { className: mobile_module_less_1.default.avatar }), extra: ele.mobile || '--', description: (0, jsx_runtime_1.jsx)("div", { style: {
}, onEnterPress: () => refresh(), clearable: true, onClear: () => removeNamedFilterByName('name') }) }), (0, jsx_runtime_1.jsx)(antd_mobile_1.Button, { size: "small", color: "primary", onClick: () => goUpsert(), children: t('common::action.create') })] }), (0, jsx_runtime_1.jsx)(antd_mobile_1.List, { children: users?.map((ele, index) => {
return ((0, jsx_runtime_1.jsx)(antd_mobile_1.List.Item, { prefix: ele.avatar ? ((0, jsx_runtime_1.jsx)(antd_mobile_1.Avatar, { className: mobile_module_less_1.default.avatar, src: ele.avatar })) : ((0, jsx_runtime_1.jsx)(antd_mobile_icons_1.UserCircleOutline, { className: mobile_module_less_1.default.avatar })), extra: ele.mobile || '--', description: (0, jsx_runtime_1.jsx)("div", { style: {
display: 'flex',
flexWrap: 'wrap',
}, children: ele.userRelation$user?.map((ele2, index2) => ((0, jsx_runtime_1.jsx)(antd_mobile_1.Tag, { fill: "outline", children: ele2.relation?.name ? t(entity + ':r.' + ele2.relation.name) : ele2.relation?.display }, index))) }), onClick: () => goUpdate(ele.id), children: ele.name || ele.nickname || '--' }));
}, children: ele.userRelation$user?.map((ele2, index2) => ((0, jsx_runtime_1.jsx)(antd_mobile_1.Tag, { fill: "outline", children: ele2.relation?.name
? t(entity +
':r.' +
ele2.relation
.name)
: ele2.relation?.display }, index))) }), onClick: () => goUpdate(ele.id), children: ele.name || ele.nickname || '--' }));
}) })] }));
}
exports.default = Render;

View File

@ -7,6 +7,7 @@ import { AppType } from '../oak-app-domain/Application/Schema';
import AspectDict from '../aspects/AspectDict';
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
import { FrontendRuntimeContext } from '../context/FrontendRuntimeContext';
import { MediaType, MediaVideoDescription } from '../types/WeChat';
export declare class Application<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>, FrontCxt extends FrontendRuntimeContext<ED, Cxt, AD>, AD extends AspectDict<ED, Cxt> & CommonAspectDict<ED, Cxt>> extends Feature {
private type;
private domain;
@ -22,5 +23,11 @@ export declare class Application<ED extends EntityDict, Cxt extends BackendRunti
initialize(appId?: string | null, projection?: EntityDict['application']['Selection']['data']): Promise<void>;
getApplication(): Partial<import("../oak-app-domain/Application/Schema").Schema> | undefined;
getApplicationId(): string | undefined;
uploadWechatMedia(formData: FormData): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["uploadWechatMedia"]>>;
uploadWechatMedia(params: {
applicationId: string;
file: File;
type: MediaType;
isPermanent?: boolean;
description?: MediaVideoDescription;
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["uploadWechatMedia"]>>;
}

View File

@ -80,15 +80,18 @@ class Application extends oak_frontend_base_1.Feature {
getApplicationId() {
return this.applicationId;
}
async uploadWechatMedia(
// params: {
// applicationId: string;
// file: any;
// type: MediaType;
// isPermanent?: boolean; //上传临时素材 或永久素材
// description?: MediaVideoDescription;
// }
formData) {
async uploadWechatMedia(params) {
const { applicationId, type, file, description, isPermanent = false, } = params;
const formData = new FormData();
formData.append('applicationId', applicationId);
formData.append('type', type);
formData.append('file', file);
if (description) {
formData.append('description', JSON.stringify(description));
}
if (isPermanent) {
formData.append('isPermanent', `${isPermanent}`);
}
const callBack = await this.cache.exec('uploadWechatMedia', formData);
return callBack.result;
}

View File

@ -28,7 +28,7 @@ function initialize(basicFeatures, type, domain) {
config,
weiXinJsSdk,
theme,
wechatMenu
wechatMenu,
};
}
exports.initialize = initialize;

8
lib/types/ErrorPage.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
export declare enum ECode {
forbidden = "403",
notFound = "404",
error = "500",
networkError = "network-error",
browserIncompatible = "browser-incompatible",
maintenance = "maintenance"
}

12
lib/types/ErrorPage.js Normal file
View File

@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ECode = void 0;
var ECode;
(function (ECode) {
ECode["forbidden"] = "403";
ECode["notFound"] = "404";
ECode["error"] = "500";
ECode["networkError"] = "network-error";
ECode["browserIncompatible"] = "browser-incompatible";
ECode["maintenance"] = "maintenance";
})(ECode || (exports.ECode = ECode = {}));

View File

@ -70,7 +70,6 @@
"cross-spawn": "^6.0.5",
"fs-extra": "^10.0.0",
"mocha": "^8.2.1",
"react-router-dom": "^6.13.0",
"rimraf": "^3.0.2",
"svg-captcha": "^1.4.0",
"ts-node": "^10.9.1",

View File

@ -1,13 +1,7 @@
enum ECode {
forbidden = '403',
notFound = '404',
error = '500',
networkError = 'network-error',
maintenance = 'maintenance',
};
import { EntityDict } from '../../../oak-app-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
import { ECode } from '../../../types/ErrorPage';
const DefaultErrorInfo = {
[ECode.forbidden]: {
@ -35,37 +29,60 @@ const DefaultErrorInfo = {
desc: '系统维护中,请稍后再试。',
imagePath: './assets/svg/assets-result-maintenance.svg',
},
[ECode.browserIncompatible]: {
title: '浏览器版本低',
desc: '抱歉,您正在使用的浏览器版本过低,无法打开当前网页。',
imagePath: './assets/svg/assets-result-browser-incompatible.svg',
},
};
export default Component({
export default OakComponent({
isList: false,
properties: {
code: String,
title: String,
desc: String,
icon: String,
imagePath: String,
code: '',
title: '',
desc: '',
icon: '', //web独有
imagePath: '', //小程序独有
},
lifetimes: {
ready() {
const { title, desc, code, imagePath } = this.data;
let title2 = title;
if (code) {
this.setData({
desc: desc || DefaultErrorInfo[code as ECode].desc,
imagePath: imagePath || DefaultErrorInfo[code as ECode].imagePath,
});
if (!title2) {
title2 = DefaultErrorInfo[code as ECode].title;
if (process.env.OAK_PLATFORM === 'wechatMp') {
const { title, desc, code, imagePath } = this.props;
let title2 = title;
if (code) {
this.setState({
desc: desc || DefaultErrorInfo[code as ECode].desc,
imagePath:
imagePath ||
DefaultErrorInfo[code as ECode].imagePath,
});
if (!title2) {
title2 = DefaultErrorInfo[code as ECode].title;
}
wx.setNavigationBarTitle({
title: title2,
});
}
wx.setNavigationBarTitle({
title: title2,
});
}
}
},
},
methods: {
goBack() {
wx.navigateBack();
goBack(delta?: number) {
this.navigateBack(delta);
},
},
}) as <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(
props: ReactComponentProps<
ED2,
T2,
false,
{
code: ECode;
title?: string;
desc?: string;
children?: React.ReactNode;
icon?: React.ReactNode;
}
}
});
>
) => React.ReactElement;

View File

@ -1,8 +1,9 @@
import React from 'react';
import { Button } from 'antd';
// @ts-ignore
import { useNavigate } from 'react-router-dom';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import { ECode } from '../../../types/ErrorPage';
import { ReactComponent as Light403Icon } from './assets/svg/assets-result-403.svg';
import { ReactComponent as Light404Icon } from './assets/svg/assets-result-404.svg';
@ -12,16 +13,6 @@ import { ReactComponent as LightBrowserIncompatibleIcon } from './assets/svg/ass
import { ReactComponent as LightNetworkErrorIcon } from './assets/svg/assets-result-network-error.svg';
import './web.less';
export enum ECode {
forbidden = '403',
notFound = '404',
error = '500',
networkError = 'network-error',
browserIncompatible = 'browser-incompatible',
maintenance = 'maintenance',
}
interface IErrorPageProps {
code: ECode;
title?: string;
@ -63,28 +54,36 @@ const errorInfo = {
},
};
function ErrorPage(props: IErrorPageProps) {
const navigate = useNavigate();
const { code } = props;
export default function Render(
props: WebComponentProps<
EntityDict,
keyof EntityDict,
false,
IErrorPageProps,
{
goBack: (delta?: number) => void;
}
>
) {
const { code, icon, title, desc, children } = props.data;
const { t, goBack } = props.methods;
const info = errorInfo[code];
const prefixCls = 'oak';
return (
<div className={`${prefixCls}-errorBox`}>
{props.icon || info?.icon}
{icon || info?.icon}
<div className={`${prefixCls}-errorBox__title`}>
{props.title || info?.title}
{title || info?.title}
</div>
<div className={`${prefixCls}-errorBox__description`}>
{props.desc || info?.desc}
{desc || info?.desc}
</div>
{props.children || (
{children || (
<Button
type="primary"
onClick={() => {
navigate(-1);
goBack();
}}
>
@ -93,5 +92,3 @@ function ErrorPage(props: IErrorPageProps) {
</div>
);
}
export default ErrorPage;

View File

@ -0,0 +1,35 @@
import { EntityDict } from '../../../oak-app-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
import { ReactComponentProps } from 'oak-frontend-base';
export default OakComponent({
isList: false,
methods: {
goBack(delta?: number) {
this.navigateBack(delta);
},
},
}) as <ED2 extends EntityDict & BaseEntityDict, T2 extends keyof ED2>(
props: ReactComponentProps<
ED2,
T2,
false,
{
style?: React.CSSProperties;
className?: string;
title?: React.ReactNode;
showBack?: boolean;
onBack?: () => void;
backIcon?: React.ReactNode;
delta?: number; //有返回按钮时,返回第几层
extra?: React.ReactNode;
subTitle?: React.ReactNode;
contentMargin?: boolean; // 设置内容是否有边距 默认true 边距为20px
contentStyle?: React.CSSProperties;
contentClassName?: string;
tags?: React.ReactNode;
children?: React.ReactNode;
showHeader?: boolean; //默认true 显示头部
}
>
) => React.ReactElement;

View File

@ -1,9 +1,9 @@
import React, { memo } from 'react';
// @ts-ignore
import { useNavigate } from 'react-router-dom';
import { Row, Col, Button } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import './index.less';
@ -25,7 +25,17 @@ type PageHeaderProps = {
showHeader?: boolean; //默认true 显示头部
};
export default memo((props: PageHeaderProps) => {
export default function Render(
props: WebComponentProps<
EntityDict,
keyof EntityDict,
false,
PageHeaderProps,
{
goBack: (delta?: number) => void;
}
>
) {
const {
style,
className,
@ -42,9 +52,9 @@ export default memo((props: PageHeaderProps) => {
contentClassName,
tags,
showHeader = true,
} = props;
} = props.data;
const { t, goBack } = props.methods;
const prefixCls = 'oak';
const navigate = useNavigate();
return (
<div
@ -67,7 +77,7 @@ export default memo((props: PageHeaderProps) => {
onBack();
return;
}
navigate(delta || -1);
goBack(delta);
}}
>
{backIcon || (
@ -113,4 +123,4 @@ export default memo((props: PageHeaderProps) => {
</div>
</div>
);
});
}

View File

@ -8,22 +8,40 @@ import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function Render(props: WebComponentProps<EntityDict, 'user', true, {
users: (EntityDict['user']['Schema'] & { avatar?: string, mobile?: string })[];
searchValue?: string;
pagination: {
pageSize: number;
total: number;
currentPage: number;
},
entity: string;
entityId: string;
}, {
goUpsert: () => void;
confirmDelete: (id: string) => Promise<void>;
goUpdate: (id: string) => void;
}>) {
const { t, goUpsert, goUpdate, addNamedFilter, refresh, removeNamedFilterByName } = props.methods;
export default function Render(
props: WebComponentProps<
EntityDict,
'user',
true,
{
users: (EntityDict['user']['Schema'] & {
avatar?: string;
mobile?: string;
})[];
searchValue?: string;
pagination: {
pageSize: number;
total: number;
currentPage: number;
};
entity: string;
entityId: string;
},
{
goUpsert: () => void;
confirmDelete: (id: string) => Promise<void>;
goUpdate: (id: string) => void;
}
>
) {
const {
t,
goUpsert,
goUpdate,
addNamedFilter,
refresh,
removeNamedFilterByName,
} = props.methods;
const { entity, users, searchValue } = props.data;
return (
<div className={Style.container}>
@ -32,26 +50,25 @@ export default function Render(props: WebComponentProps<EntityDict, 'user', true
<Input
placeholder={t('search')}
value={searchValue}
onChange={value => {
addNamedFilter({
'#name': 'name',
filter: {
$text: {
$search: value,
}
}
}, false);
onChange={(value) => {
addNamedFilter(
{
'#name': 'name',
filter: {
$text: {
$search: value,
},
},
},
false
);
}}
onEnterPress={() => refresh()}
clearable
onClear={() => removeNamedFilterByName('name')}
/>
</div>
<Button
size='small'
color='primary'
onClick={() => goUpsert()}
>
<Button size="small" color="primary" onClick={() => goUpsert()}>
{t('common::action.create')}
</Button>
</span>
@ -60,12 +77,16 @@ export default function Render(props: WebComponentProps<EntityDict, 'user', true
return (
<List.Item
prefix={
ele.avatar ? <Avatar
className={Style.avatar}
src={ele.avatar}
/> : <UserCircleOutline
className={Style.avatar}
/>
ele.avatar ? (
<Avatar
className={Style.avatar}
src={ele.avatar}
/>
) : (
<UserCircleOutline
className={Style.avatar}
/>
)
}
extra={ele.mobile || '--'}
description={
@ -75,15 +96,20 @@ export default function Render(props: WebComponentProps<EntityDict, 'user', true
flexWrap: 'wrap',
}}
>
{
ele.userRelation$user?.map(
(ele2, index2) => (
<Tag key={index} fill="outline">
{ele2.relation?.name ? t(entity + ':r.' + ele2.relation!.name) : ele2.relation?.display}
</Tag>
)
{ele.userRelation$user?.map(
(ele2, index2) => (
<Tag key={index} fill="outline">
{ele2.relation?.name
? t(
entity +
':r.' +
ele2.relation!
.name
)
: ele2.relation?.display}
</Tag>
)
}
)}
</div>
}
onClick={() => goUpdate(ele.id)}

View File

@ -119,16 +119,30 @@ export class Application<
return this.applicationId;
}
async uploadWechatMedia(
// params: {
// applicationId: string;
// file: any;
// type: MediaType;
// isPermanent?: boolean; //上传临时素材 或永久素材
// description?: MediaVideoDescription;
// }
formData: FormData
) {
async uploadWechatMedia(params: {
applicationId: string;
file: File;
type: MediaType;
isPermanent?: boolean; //上传临时素材 或永久素材
description?: MediaVideoDescription;
}) {
const {
applicationId,
type,
file,
description,
isPermanent = false,
} = params;
const formData = new FormData();
formData.append('applicationId', applicationId);
formData.append('type', type);
formData.append('file', file);
if (description) {
formData.append('description', JSON.stringify(description));
}
if (isPermanent) {
formData.append('isPermanent', `${isPermanent}`);
}
const callBack = await this.cache.exec('uploadWechatMedia', formData);
return callBack.result;
}

View File

@ -60,7 +60,7 @@ export function initialize<
config,
weiXinJsSdk,
theme,
wechatMenu
wechatMenu,
};
}

11
src/types/ErrorPage.ts Normal file
View File

@ -0,0 +1,11 @@
export enum ECode {
forbidden = '403',
notFound = '404',
error = '500',
networkError = 'network-error',
browserIncompatible = 'browser-incompatible',
maintenance = 'maintenance',
}