J<3MQsNhOEYodj;5({(pE0$4P!F$)xqVIwo83~69g=48RK+49na7Q(C
zC7>Jw*DbzEje?QUe|LGt3nX|7Uz)%oP2zR&b4Op@R)(SMB<|5c3@$a63w&>G*}**C7T$?5!b=
z&nPVm(<;~Sw_*kJlio|*qhI8#F?9y#@jvQ4Y?j2~r_a^)YoQ-co4WFOwF)i5mFnrV
zp3rz^`K|nrI`guQ$X^%JuCI5qSS(}Tc|%+~o}P6dC={o1Q&<)3lnFnXE=l2Po$K4W
zYZ0|2<3Cp|&)NE>;p=Muwg#BLXuboTJ(mwtjLbtdOE_A4n^}l29p9@>4vpS+t*^qG
zb2Uo-W$@vKeR}iztf6tJTUh8=^kh_EBe^3f?1b(p_oBq&dpqW$pAyBB**bIt4BhwK
zX02JE@mc}FExq0q+5_8B#EP&@;6-lx4t~)@$HBEBXnIqX0E$mhb$(}
zt|vYUzekLn0SQ;Cd)J1
zXF3gv$u52+$>oQVvh7DxPpKeWD4yJgdWQQ`D#($Z=j%Df!iAxvR)-y7Ie5nI39+zG
z4a3_4mE;SBh@MK8p%(n|yGj>Ao>j51ETLI#vuUt#g|%FDZG}&kbEb(|*9!RyL&U?|
zvNnv+oEL_*R{Mw_;x+O`vNWUXL6>@M)sQr_lmlng7?sCaDH0YaGf%+R1ZM}9#$j$3
zi}N01^7uoRgvG74Fxi{415}={tg=gDHuqwR$1?9qlK<#~
zLG@an>_SlEY6+k8PD+S)C&NU7!~`$+Sin{JS2aLn_Jm#q|8H%OnLqt&n-f~C7KW9K
z>QxTE1D!cV+(E>-8N#r>Aw98T*8=odDM_y2&?=ag7-=Rj&p%xvU
zq=o{%T2@T(b@VqinV#`~IN4t3^z$HE=3~ZiDQ=xP6Gt)g;q1Wv2N&CBx=Ndw5
z6U*fS@;@VBF^MGsyag~+Eq&2UZ@5SG$!SM2ckBL!E1lBg>*t^{Lqn=cK^-Rhc#S(%
zuAqbI(^+PqN#)t&5xr~v&*Y$qZ$3Yz)nRe`ZZcJUU8hd=)9$7
z6n-k7p||Esq}igp(IoxtD&_5A!OwcTvM3p-HHJGcVh|>N13O;!W%RXd{Y6@BEp1Jz
zHCH!~H~lR%<3E0b>}>_dD6Ef8r_)LSp}O5L`DerkKk|Jc@n6*BmU&r@TKhG$-x=>`wv*Vj%M=6<7!P7~3+)?^D>AA~&^F+{mzBAMLh
zuTiItS}IqcPpj-t;W15ahnBV9rHnrShN-@GCY+EyXV6Gass&4cM~^;F?z{3+SXKe7
zX8rBU7Fc!Kr5M!K@lDd)Bl)VMR)yb6;AHxpH?Q1Bx14XQy~`&ggyC$4u>az;q|C7G
ziTI-A3y9BZbxP7rW4_G!ju{^(NOZstl}tvVR+j8_B`~)2cWn2~;amI9u@_9oSC+Xc
z_+DcYbc7S~MIl7Fjk6qEWXDo6>n5U0O4P_k15Z^c%P@0?*Oaj8%BIU*uy|Vgi@eqH
zPKZqrW$wXWQ9=QoQrY4VBCFzACRJhEv+U(FOmx1_uwVirtukLVbyF&%?xKU6D>Yot
zj6ZW-1$@|ASwJlAu1;!K9!5uPdov-?7RK^;L%bs%6z9abcvP!i20^{1|g}`{&O=}R+#D;J+z#Fj(x6k%xY0!5_DrzSsTCn;pu^6
zIZV~_c4b?yxFutJZTc`BT4+(N21dx%Bxx5_=*+^Gl`PCmvS7QnNZUr>RqS>smtAo7
z%1fV4h6YI+Y2X$?ZuQmeFj!XWfPJxAc1<0;;3C|?V?=BITB{AnSkYW;+Vbas9ODwo
zC?uf|l|KjLdt@iP*&!CGbh&OT1l3&s3RD|7knGOc{T%o)WLqmqSnTE5-M^OKN+8ct1C(XwQJJg%OozV)cJ^w#
zVxbg~z7OMwn+eEPaBRR0KIDX14Kb^G-Strc8r6QmoINnF;F1;|U5n3%rdT9(U0dcP
zI*}ZU>2wFp1u1KmK2cwSwk|=oZ8?l*@yIPBD3BPN(BINzFh#VAKBpVxZ71*JgwpWXLZfS%KkGa_tQn0bX5)h8
z6Q7LGdb=)NQ}a}>SD{8~!ga|bE*aS_Nxg_+ojhQ1{b@sVzaX)Z{rV-1%Qa*ioSy65
zb4ke$#&Mf>xuBg{&aCGNbhbOGbN4XT4?qQpRW^!2z;9eCH6fH7)+qpWe;n~*tCIq=
z&w&jc@_tBWRiS3IyovPwt~fl#1Z-%o%T_B%)sO*FrOIkz-1r$#mr+&N2J06a?u1<~QB}EoR?wnU)c32Ew0(EP^w=K@<
zM;7MeoWTwa-$09MwD#{-p5K@kGTM6q@*9`~NBz#snAQt$W%fZr`qk|A%IEM4|B(?x
zOpx+g1-*Q?a%JHpKf|Cs>MCBj^^EmKDb?*U1(_uF({whek67oi^wL)^XH3=`&u$U^
z*K&AEIc$ISs)O2r7emK9XW_i^6Jxw-Ug6tIn{3gqAYG+j_U1<)>HovW7l7Z>STIh4
z7OH$pfQM^<6ZPN`%FY^PFKzq89tYsIi0BGroup 28 Copy 5Created with Sketch.
\ No newline at end of file
diff --git a/public/pro_icon.svg b/public/pro_icon.svg
new file mode 100644
index 0000000..e075b78
--- /dev/null
+++ b/public/pro_icon.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/public/scripts/loading.js b/public/scripts/loading.js
new file mode 100644
index 0000000..c1ced54
--- /dev/null
+++ b/public/scripts/loading.js
@@ -0,0 +1,202 @@
+/**
+ * loading 占位
+ * 解决首次加载时白屏的问题
+ */
+ (function () {
+ const _root = document.querySelector('#root');
+ if (_root && _root.innerHTML === '') {
+ _root.innerHTML = `
+
+
+
+
+
+ 正在加载资源
+
+
+ 初次加载资源可能需要较多时间 请耐心等待
+
+
+ `;
+ }
+})();
diff --git a/src/access.ts b/src/access.ts
new file mode 100644
index 0000000..e823e24
--- /dev/null
+++ b/src/access.ts
@@ -0,0 +1,9 @@
+/**
+ * @see https://umijs.org/zh-CN/plugins/plugin-access
+ * */
+export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) {
+ const { currentUser } = initialState ?? {};
+ return {
+ canAdmin: currentUser && currentUser.access === 'admin',
+ };
+}
diff --git a/src/app.tsx b/src/app.tsx
new file mode 100644
index 0000000..024f261
--- /dev/null
+++ b/src/app.tsx
@@ -0,0 +1,136 @@
+import Footer from '@/components/Footer';
+import { Question, SelectLang } from '@/components/RightContent';
+import { LinkOutlined } from '@ant-design/icons';
+import type { Settings as LayoutSettings } from '@ant-design/pro-components';
+import { SettingDrawer } from '@ant-design/pro-components';
+import type { RunTimeLayoutConfig } from '@umijs/max';
+import { history, Link } from '@umijs/max';
+import defaultSettings from '../config/defaultSettings';
+import { errorConfig } from './requestErrorConfig';
+import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
+import React from 'react';
+import { AvatarDropdown, AvatarName } from './components/RightContent/AvatarDropdown';
+const isDev = process.env.NODE_ENV === 'development';
+const loginPath = '/user/login';
+
+/**
+ * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
+ * */
+export async function getInitialState(): Promise<{
+ settings?: Partial;
+ currentUser?: API.CurrentUser;
+ loading?: boolean;
+ fetchUserInfo?: () => Promise;
+}> {
+ const fetchUserInfo = async () => {
+ try {
+ const msg = await queryCurrentUser({
+ skipErrorHandler: true,
+ });
+ return msg.data;
+ } catch (error) {
+ history.push(loginPath);
+ }
+ return undefined;
+ };
+ // 如果不是登录页面,执行
+ const { location } = history;
+ if (location.pathname !== loginPath) {
+ const currentUser = await fetchUserInfo();
+ return {
+ fetchUserInfo,
+ currentUser,
+ settings: defaultSettings as Partial,
+ };
+ }
+ return {
+ fetchUserInfo,
+ settings: defaultSettings as Partial,
+ };
+}
+
+// ProLayout 支持的api https://procomponents.ant.design/components/layout
+export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
+ return {
+ actionsRender: () => [, ],
+ avatarProps: {
+ src: initialState?.currentUser?.avatar,
+ title: ,
+ render: (_, avatarChildren) => {
+ return {avatarChildren};
+ },
+ },
+ waterMarkProps: {
+ content: initialState?.currentUser?.name,
+ },
+ footerRender: () => ,
+ onPageChange: () => {
+ const { location } = history;
+ // 如果没有登录,重定向到 login
+ if (!initialState?.currentUser && location.pathname !== loginPath) {
+ history.push(loginPath);
+ }
+ },
+ layoutBgImgList: [
+ {
+ src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/D2LWSqNny4sAAAAAAAAAAAAAFl94AQBr',
+ left: 85,
+ bottom: 100,
+ height: '303px',
+ },
+ {
+ src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/C2TWRpJpiC0AAAAAAAAAAAAAFl94AQBr',
+ bottom: -68,
+ right: -45,
+ height: '303px',
+ },
+ {
+ src: 'https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/F6vSTbj8KpYAAAAAAAAAAAAAFl94AQBr',
+ bottom: 0,
+ left: 0,
+ width: '331px',
+ },
+ ],
+ links: isDev
+ ? [
+
+
+ OpenAPI 文档
+ ,
+ ]
+ : [],
+ menuHeaderRender: undefined,
+ // 自定义 403 页面
+ // unAccessible: unAccessible
,
+ // 增加一个 loading 的状态
+ childrenRender: (children) => {
+ // if (initialState?.loading) return ;
+ return (
+ <>
+ {children}
+ {
+ setInitialState((preInitialState) => ({
+ ...preInitialState,
+ settings,
+ }));
+ }}
+ />
+ >
+ );
+ },
+ ...initialState?.settings,
+ };
+};
+
+/**
+ * @name request 配置,可以配置错误处理
+ * 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
+ * @doc https://umijs.org/docs/max/request#配置
+ */
+export const request = {
+ ...errorConfig,
+};
diff --git a/src/components/Footer/index.tsx b/src/components/Footer/index.tsx
new file mode 100644
index 0000000..03ac146
--- /dev/null
+++ b/src/components/Footer/index.tsx
@@ -0,0 +1,45 @@
+import { GithubOutlined } from '@ant-design/icons';
+import { DefaultFooter } from '@ant-design/pro-components';
+import { useIntl } from '@umijs/max';
+import React from 'react';
+
+const Footer: React.FC = () => {
+ const intl = useIntl();
+ const defaultMessage = intl.formatMessage({
+ id: 'app.copyright.produced',
+ defaultMessage: '蚂蚁集团体验技术部出品',
+ });
+
+ const currentYear = new Date().getFullYear();
+
+ return (
+ ,
+ href: 'https://github.com/ant-design/ant-design-pro',
+ blankTarget: true,
+ },
+ {
+ key: 'Ant Design',
+ title: 'Ant Design',
+ href: 'https://ant.design',
+ blankTarget: true,
+ },
+ ]}
+ />
+ );
+};
+
+export default Footer;
diff --git a/src/components/HeaderDropdown/index.tsx b/src/components/HeaderDropdown/index.tsx
new file mode 100644
index 0000000..52a2036
--- /dev/null
+++ b/src/components/HeaderDropdown/index.tsx
@@ -0,0 +1,23 @@
+import { Dropdown } from 'antd';
+import type { DropDownProps } from 'antd/es/dropdown';
+import React from 'react';
+import { useEmotionCss } from '@ant-design/use-emotion-css';
+import classNames from 'classnames';
+
+export type HeaderDropdownProps = {
+ overlayClassName?: string;
+ placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight' | 'bottomCenter';
+} & Omit;
+
+const HeaderDropdown: React.FC = ({ overlayClassName: cls, ...restProps }) => {
+ const className = useEmotionCss(({ token }) => {
+ return {
+ [`@media screen and (max-width: ${token.screenXS})`]: {
+ width: '100%',
+ },
+ };
+ });
+ return ;
+};
+
+export default HeaderDropdown;
diff --git a/src/components/RightContent/AvatarDropdown.tsx b/src/components/RightContent/AvatarDropdown.tsx
new file mode 100644
index 0000000..c4c6415
--- /dev/null
+++ b/src/components/RightContent/AvatarDropdown.tsx
@@ -0,0 +1,133 @@
+import { outLogin } from '@/services/ant-design-pro/api';
+import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
+import { useEmotionCss } from '@ant-design/use-emotion-css';
+import { history, useModel } from '@umijs/max';
+import { Spin } from 'antd';
+import { stringify } from 'querystring';
+import type { MenuInfo } from 'rc-menu/lib/interface';
+import React, { useCallback } from 'react';
+import { flushSync } from 'react-dom';
+import HeaderDropdown from '../HeaderDropdown';
+
+export type GlobalHeaderRightProps = {
+ menu?: boolean;
+ children?: React.ReactNode;
+};
+
+export const AvatarName = () => {
+ const { initialState } = useModel('@@initialState');
+ const { currentUser } = initialState || {};
+ return {currentUser?.name};
+};
+
+export const AvatarDropdown: React.FC = ({ menu, children }) => {
+ /**
+ * 退出登录,并且将当前的 url 保存
+ */
+ const loginOut = async () => {
+ await outLogin();
+ const { search, pathname } = window.location;
+ const urlParams = new URL(window.location.href).searchParams;
+ /** 此方法会跳转到 redirect 参数所在的位置 */
+ const redirect = urlParams.get('redirect');
+ // Note: There may be security issues, please note
+ if (window.location.pathname !== '/user/login' && !redirect) {
+ history.replace({
+ pathname: '/user/login',
+ search: stringify({
+ redirect: pathname + search,
+ }),
+ });
+ }
+ };
+ const actionClassName = useEmotionCss(({ token }) => {
+ return {
+ display: 'flex',
+ height: '48px',
+ marginLeft: 'auto',
+ overflow: 'hidden',
+ alignItems: 'center',
+ padding: '0 8px',
+ cursor: 'pointer',
+ borderRadius: token.borderRadius,
+ '&:hover': {
+ backgroundColor: token.colorBgTextHover,
+ },
+ };
+ });
+ const { initialState, setInitialState } = useModel('@@initialState');
+
+ const onMenuClick = useCallback(
+ (event: MenuInfo) => {
+ const { key } = event;
+ if (key === 'logout') {
+ flushSync(() => {
+ setInitialState((s) => ({ ...s, currentUser: undefined }));
+ });
+ loginOut();
+ return;
+ }
+ history.push(`/account/${key}`);
+ },
+ [setInitialState],
+ );
+
+ const loading = (
+
+
+
+ );
+
+ if (!initialState) {
+ return loading;
+ }
+
+ const { currentUser } = initialState;
+
+ if (!currentUser || !currentUser.name) {
+ return loading;
+ }
+
+ const menuItems = [
+ ...(menu
+ ? [
+ {
+ key: 'center',
+ icon: ,
+ label: '个人中心',
+ },
+ {
+ key: 'settings',
+ icon: ,
+ label: '个人设置',
+ },
+ {
+ type: 'divider' as const,
+ },
+ ]
+ : []),
+ {
+ key: 'logout',
+ icon: ,
+ label: '退出登录',
+ },
+ ];
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/components/RightContent/index.tsx b/src/components/RightContent/index.tsx
new file mode 100644
index 0000000..20a7831
--- /dev/null
+++ b/src/components/RightContent/index.tsx
@@ -0,0 +1,31 @@
+import { QuestionCircleOutlined } from '@ant-design/icons';
+import { SelectLang as UmiSelectLang } from '@umijs/max';
+import React from 'react';
+
+export type SiderTheme = 'light' | 'dark';
+
+export const SelectLang = () => {
+ return (
+
+ );
+};
+
+export const Question = () => {
+ return (
+ {
+ window.open('https://pro.ant.design/docs/getting-started');
+ }}
+ >
+
+
+ );
+};
diff --git a/src/global.less b/src/global.less
new file mode 100644
index 0000000..a9a0c51
--- /dev/null
+++ b/src/global.less
@@ -0,0 +1,53 @@
+html,
+body,
+#root {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
+ 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+ 'Noto Color Emoji';
+}
+
+.colorWeak {
+ filter: invert(80%);
+}
+
+.ant-layout {
+ min-height: 100vh;
+}
+.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
+ left: unset;
+}
+
+canvas {
+ display: block;
+}
+
+body {
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+ul,
+ol {
+ list-style: none;
+}
+
+@media (max-width: 768px) {
+ .ant-table {
+ width: 100%;
+ overflow-x: auto;
+ &-thead > tr,
+ &-tbody > tr {
+ > th,
+ > td {
+ white-space: pre;
+ > span {
+ display: block;
+ }
+ }
+ }
+ }
+}
diff --git a/src/global.tsx b/src/global.tsx
new file mode 100644
index 0000000..afa1fab
--- /dev/null
+++ b/src/global.tsx
@@ -0,0 +1,91 @@
+import { useIntl } from '@umijs/max';
+import { Button, message, notification } from 'antd';
+import defaultSettings from '../config/defaultSettings';
+
+const { pwa } = defaultSettings;
+const isHttps = document.location.protocol === 'https:';
+
+const clearCache = () => {
+ // remove all caches
+ if (window.caches) {
+ caches
+ .keys()
+ .then((keys) => {
+ keys.forEach((key) => {
+ caches.delete(key);
+ });
+ })
+ .catch((e) => console.log(e));
+ }
+};
+
+// if pwa is true
+if (pwa) {
+ // Notify user if offline now
+ window.addEventListener('sw.offline', () => {
+ message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' }));
+ });
+
+ // Pop up a prompt on the page asking the user if they want to use the latest version
+ window.addEventListener('sw.updated', (event: Event) => {
+ const e = event as CustomEvent;
+ const reloadSW = async () => {
+ // Check if there is sw whose state is waiting in ServiceWorkerRegistration
+ // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
+ const worker = e.detail && e.detail.waiting;
+ if (!worker) {
+ return true;
+ }
+ // Send skip-waiting event to waiting SW with MessageChannel
+ await new Promise((resolve, reject) => {
+ const channel = new MessageChannel();
+ channel.port1.onmessage = (msgEvent) => {
+ if (msgEvent.data.error) {
+ reject(msgEvent.data.error);
+ } else {
+ resolve(msgEvent.data);
+ }
+ };
+ worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
+ });
+
+ clearCache();
+ window.location.reload();
+ return true;
+ };
+ const key = `open${Date.now()}`;
+ const btn = (
+
+ );
+ notification.open({
+ message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }),
+ description: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }),
+ btn,
+ key,
+ onClose: async () => null,
+ });
+ });
+} else if ('serviceWorker' in navigator && isHttps) {
+ // unregister service worker
+ const { serviceWorker } = navigator;
+ if (serviceWorker.getRegistrations) {
+ serviceWorker.getRegistrations().then((sws) => {
+ sws.forEach((sw) => {
+ sw.unregister();
+ });
+ });
+ }
+ serviceWorker.getRegistration().then((sw) => {
+ if (sw) sw.unregister();
+ });
+
+ clearCache();
+}
diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts
new file mode 100644
index 0000000..acb0f42
--- /dev/null
+++ b/src/locales/en-US.ts
@@ -0,0 +1,25 @@
+import component from './en-US/component';
+import globalHeader from './en-US/globalHeader';
+import menu from './en-US/menu';
+import pages from './en-US/pages';
+import pwa from './en-US/pwa';
+import settingDrawer from './en-US/settingDrawer';
+import settings from './en-US/settings';
+
+export default {
+ 'navBar.lang': 'Languages',
+ 'layout.user.link.help': 'Help',
+ 'layout.user.link.privacy': 'Privacy',
+ 'layout.user.link.terms': 'Terms',
+ 'app.copyright.produced': 'Produced by Ant Financial Experience Department',
+ 'app.preview.down.block': 'Download this page to your local project',
+ 'app.welcome.link.fetch-blocks': 'Get all block',
+ 'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
+ ...globalHeader,
+ ...menu,
+ ...settingDrawer,
+ ...settings,
+ ...pwa,
+ ...component,
+ ...pages,
+};
diff --git a/src/locales/en-US/component.ts b/src/locales/en-US/component.ts
new file mode 100644
index 0000000..3ba7eed
--- /dev/null
+++ b/src/locales/en-US/component.ts
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': 'Expand',
+ 'component.tagSelect.collapse': 'Collapse',
+ 'component.tagSelect.all': 'All',
+};
diff --git a/src/locales/en-US/globalHeader.ts b/src/locales/en-US/globalHeader.ts
new file mode 100644
index 0000000..60b6d4e
--- /dev/null
+++ b/src/locales/en-US/globalHeader.ts
@@ -0,0 +1,17 @@
+export default {
+ 'component.globalHeader.search': 'Search',
+ 'component.globalHeader.search.example1': 'Search example 1',
+ 'component.globalHeader.search.example2': 'Search example 2',
+ 'component.globalHeader.search.example3': 'Search example 3',
+ 'component.globalHeader.help': 'Help',
+ 'component.globalHeader.notification': 'Notification',
+ 'component.globalHeader.notification.empty': 'You have viewed all notifications.',
+ 'component.globalHeader.message': 'Message',
+ 'component.globalHeader.message.empty': 'You have viewed all messsages.',
+ 'component.globalHeader.event': 'Event',
+ 'component.globalHeader.event.empty': 'You have viewed all events.',
+ 'component.noticeIcon.clear': 'Clear',
+ 'component.noticeIcon.cleared': 'Cleared',
+ 'component.noticeIcon.empty': 'No notifications',
+ 'component.noticeIcon.view-more': 'View more',
+};
diff --git a/src/locales/en-US/menu.ts b/src/locales/en-US/menu.ts
new file mode 100644
index 0000000..eae3e53
--- /dev/null
+++ b/src/locales/en-US/menu.ts
@@ -0,0 +1,52 @@
+export default {
+ 'menu.welcome': 'Welcome',
+ 'menu.more-blocks': 'More Blocks',
+ 'menu.home': 'Home',
+ 'menu.admin': 'Admin',
+ 'menu.admin.sub-page': 'Sub-Page',
+ 'menu.login': 'Login',
+ 'menu.register': 'Register',
+ 'menu.register-result': 'Register Result',
+ 'menu.dashboard': 'Dashboard',
+ 'menu.dashboard.analysis': 'Analysis',
+ 'menu.dashboard.monitor': 'Monitor',
+ 'menu.dashboard.workplace': 'Workplace',
+ 'menu.exception.403': '403',
+ 'menu.exception.404': '404',
+ 'menu.exception.500': '500',
+ 'menu.form': 'Form',
+ 'menu.form.basic-form': 'Basic Form',
+ 'menu.form.step-form': 'Step Form',
+ 'menu.form.step-form.info': 'Step Form(write transfer information)',
+ 'menu.form.step-form.confirm': 'Step Form(confirm transfer information)',
+ 'menu.form.step-form.result': 'Step Form(finished)',
+ 'menu.form.advanced-form': 'Advanced Form',
+ 'menu.list': 'List',
+ 'menu.list.table-list': 'Search Table',
+ 'menu.list.basic-list': 'Basic List',
+ 'menu.list.card-list': 'Card List',
+ 'menu.list.search-list': 'Search List',
+ 'menu.list.search-list.articles': 'Search List(articles)',
+ 'menu.list.search-list.projects': 'Search List(projects)',
+ 'menu.list.search-list.applications': 'Search List(applications)',
+ 'menu.profile': 'Profile',
+ 'menu.profile.basic': 'Basic Profile',
+ 'menu.profile.advanced': 'Advanced Profile',
+ 'menu.result': 'Result',
+ 'menu.result.success': 'Success',
+ 'menu.result.fail': 'Fail',
+ 'menu.exception': 'Exception',
+ 'menu.exception.not-permission': '403',
+ 'menu.exception.not-find': '404',
+ 'menu.exception.server-error': '500',
+ 'menu.exception.trigger': 'Trigger',
+ 'menu.account': 'Account',
+ 'menu.account.center': 'Account Center',
+ 'menu.account.settings': 'Account Settings',
+ 'menu.account.trigger': 'Trigger Error',
+ 'menu.account.logout': 'Logout',
+ 'menu.editor': 'Graphic Editor',
+ 'menu.editor.flow': 'Flow Editor',
+ 'menu.editor.mind': 'Mind Editor',
+ 'menu.editor.koni': 'Koni Editor',
+};
diff --git a/src/locales/en-US/pages.ts b/src/locales/en-US/pages.ts
new file mode 100644
index 0000000..486f5e8
--- /dev/null
+++ b/src/locales/en-US/pages.ts
@@ -0,0 +1,68 @@
+export default {
+ 'pages.layouts.userLayout.title':
+ 'Ant Design is the most influential web design specification in Xihu district',
+ 'pages.login.accountLogin.tab': 'Account Login',
+ 'pages.login.accountLogin.errorMessage': 'Incorrect username/password(admin/ant.design)',
+ 'pages.login.failure': 'Login failed, please try again!',
+ 'pages.login.success': 'Login successful!',
+ 'pages.login.username.placeholder': 'Username: admin or user',
+ 'pages.login.username.required': 'Please input your username!',
+ 'pages.login.password.placeholder': 'Password: ant.design',
+ 'pages.login.password.required': 'Please input your password!',
+ 'pages.login.phoneLogin.tab': 'Phone Login',
+ 'pages.login.phoneLogin.errorMessage': 'Verification Code Error',
+ 'pages.login.phoneNumber.placeholder': 'Phone Number',
+ 'pages.login.phoneNumber.required': 'Please input your phone number!',
+ 'pages.login.phoneNumber.invalid': 'Phone number is invalid!',
+ 'pages.login.captcha.placeholder': 'Verification Code',
+ 'pages.login.captcha.required': 'Please input verification code!',
+ 'pages.login.phoneLogin.getVerificationCode': 'Get Code',
+ 'pages.getCaptchaSecondText': 'sec(s)',
+ 'pages.login.rememberMe': 'Remember me',
+ 'pages.login.forgotPassword': 'Forgot Password ?',
+ 'pages.login.submit': 'Login',
+ 'pages.login.loginWith': 'Login with :',
+ 'pages.login.registerAccount': 'Register Account',
+ 'pages.welcome.link': 'Welcome',
+ 'pages.welcome.alertMessage': 'Faster and stronger heavy-duty components have been released.',
+ 'pages.admin.subPage.title': 'This page can only be viewed by Admin',
+ 'pages.admin.subPage.alertMessage':
+ 'Umi ui is now released, welcome to use npm run ui to start the experience.',
+ 'pages.searchTable.createForm.newRule': 'New Rule',
+ 'pages.searchTable.updateForm.ruleConfig': 'Rule configuration',
+ 'pages.searchTable.updateForm.basicConfig': 'Basic Information',
+ 'pages.searchTable.updateForm.ruleName.nameLabel': 'Rule Name',
+ 'pages.searchTable.updateForm.ruleName.nameRules': 'Please enter the rule name!',
+ 'pages.searchTable.updateForm.ruleDesc.descLabel': 'Rule Description',
+ 'pages.searchTable.updateForm.ruleDesc.descPlaceholder': 'Please enter at least five characters',
+ 'pages.searchTable.updateForm.ruleDesc.descRules':
+ 'Please enter a rule description of at least five characters!',
+ 'pages.searchTable.updateForm.ruleProps.title': 'Configure Properties',
+ 'pages.searchTable.updateForm.object': 'Monitoring Object',
+ 'pages.searchTable.updateForm.ruleProps.templateLabel': 'Rule Template',
+ 'pages.searchTable.updateForm.ruleProps.typeLabel': 'Rule Type',
+ 'pages.searchTable.updateForm.schedulingPeriod.title': 'Set Scheduling Period',
+ 'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Starting Time',
+ 'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'Please choose a start time!',
+ 'pages.searchTable.titleDesc': 'Description',
+ 'pages.searchTable.ruleName': 'Rule name is required',
+ 'pages.searchTable.titleCallNo': 'Number of Service Calls',
+ 'pages.searchTable.titleStatus': 'Status',
+ 'pages.searchTable.nameStatus.default': 'default',
+ 'pages.searchTable.nameStatus.running': 'running',
+ 'pages.searchTable.nameStatus.online': 'online',
+ 'pages.searchTable.nameStatus.abnormal': 'abnormal',
+ 'pages.searchTable.titleUpdatedAt': 'Last Scheduled at',
+ 'pages.searchTable.exception': 'Please enter the reason for the exception!',
+ 'pages.searchTable.titleOption': 'Option',
+ 'pages.searchTable.config': 'Configuration',
+ 'pages.searchTable.subscribeAlert': 'Subscribe to alerts',
+ 'pages.searchTable.title': 'Enquiry Form',
+ 'pages.searchTable.new': 'New',
+ 'pages.searchTable.chosen': 'chosen',
+ 'pages.searchTable.item': 'item',
+ 'pages.searchTable.totalServiceCalls': 'Total Number of Service Calls',
+ 'pages.searchTable.tenThousand': '0000',
+ 'pages.searchTable.batchDeletion': 'batch deletion',
+ 'pages.searchTable.batchApproval': 'batch approval',
+};
diff --git a/src/locales/en-US/pwa.ts b/src/locales/en-US/pwa.ts
new file mode 100644
index 0000000..ed8d199
--- /dev/null
+++ b/src/locales/en-US/pwa.ts
@@ -0,0 +1,6 @@
+export default {
+ 'app.pwa.offline': 'You are offline now',
+ 'app.pwa.serviceworker.updated': 'New content is available',
+ 'app.pwa.serviceworker.updated.hint': 'Please press the "Refresh" button to reload current page',
+ 'app.pwa.serviceworker.updated.ok': 'Refresh',
+};
diff --git a/src/locales/en-US/settingDrawer.ts b/src/locales/en-US/settingDrawer.ts
new file mode 100644
index 0000000..a644905
--- /dev/null
+++ b/src/locales/en-US/settingDrawer.ts
@@ -0,0 +1,31 @@
+export default {
+ 'app.setting.pagestyle': 'Page style setting',
+ 'app.setting.pagestyle.dark': 'Dark style',
+ 'app.setting.pagestyle.light': 'Light style',
+ 'app.setting.content-width': 'Content Width',
+ 'app.setting.content-width.fixed': 'Fixed',
+ 'app.setting.content-width.fluid': 'Fluid',
+ 'app.setting.themecolor': 'Theme Color',
+ 'app.setting.themecolor.dust': 'Dust Red',
+ 'app.setting.themecolor.volcano': 'Volcano',
+ 'app.setting.themecolor.sunset': 'Sunset Orange',
+ 'app.setting.themecolor.cyan': 'Cyan',
+ 'app.setting.themecolor.green': 'Polar Green',
+ 'app.setting.themecolor.daybreak': 'Daybreak Blue (default)',
+ 'app.setting.themecolor.geekblue': 'Geek Glue',
+ 'app.setting.themecolor.purple': 'Golden Purple',
+ 'app.setting.navigationmode': 'Navigation Mode',
+ 'app.setting.sidemenu': 'Side Menu Layout',
+ 'app.setting.topmenu': 'Top Menu Layout',
+ 'app.setting.fixedheader': 'Fixed Header',
+ 'app.setting.fixedsidebar': 'Fixed Sidebar',
+ 'app.setting.fixedsidebar.hint': 'Works on Side Menu Layout',
+ 'app.setting.hideheader': 'Hidden Header when scrolling',
+ 'app.setting.hideheader.hint': 'Works when Hidden Header is enabled',
+ 'app.setting.othersettings': 'Other Settings',
+ 'app.setting.weakmode': 'Weak Mode',
+ 'app.setting.copy': 'Copy Setting',
+ 'app.setting.copyinfo': 'copy success,please replace defaultSettings in src/models/setting.js',
+ 'app.setting.production.hint':
+ 'Setting panel shows in development environment only, please manually modify',
+};
diff --git a/src/locales/en-US/settings.ts b/src/locales/en-US/settings.ts
new file mode 100644
index 0000000..822dd00
--- /dev/null
+++ b/src/locales/en-US/settings.ts
@@ -0,0 +1,60 @@
+export default {
+ 'app.settings.menuMap.basic': 'Basic Settings',
+ 'app.settings.menuMap.security': 'Security Settings',
+ 'app.settings.menuMap.binding': 'Account Binding',
+ 'app.settings.menuMap.notification': 'New Message Notification',
+ 'app.settings.basic.avatar': 'Avatar',
+ 'app.settings.basic.change-avatar': 'Change avatar',
+ 'app.settings.basic.email': 'Email',
+ 'app.settings.basic.email-message': 'Please input your email!',
+ 'app.settings.basic.nickname': 'Nickname',
+ 'app.settings.basic.nickname-message': 'Please input your Nickname!',
+ 'app.settings.basic.profile': 'Personal profile',
+ 'app.settings.basic.profile-message': 'Please input your personal profile!',
+ 'app.settings.basic.profile-placeholder': 'Brief introduction to yourself',
+ 'app.settings.basic.country': 'Country/Region',
+ 'app.settings.basic.country-message': 'Please input your country!',
+ 'app.settings.basic.geographic': 'Province or city',
+ 'app.settings.basic.geographic-message': 'Please input your geographic info!',
+ 'app.settings.basic.address': 'Street Address',
+ 'app.settings.basic.address-message': 'Please input your address!',
+ 'app.settings.basic.phone': 'Phone Number',
+ 'app.settings.basic.phone-message': 'Please input your phone!',
+ 'app.settings.basic.update': 'Update Information',
+ 'app.settings.security.strong': 'Strong',
+ 'app.settings.security.medium': 'Medium',
+ 'app.settings.security.weak': 'Weak',
+ 'app.settings.security.password': 'Account Password',
+ 'app.settings.security.password-description': 'Current password strength',
+ 'app.settings.security.phone': 'Security Phone',
+ 'app.settings.security.phone-description': 'Bound phone',
+ 'app.settings.security.question': 'Security Question',
+ 'app.settings.security.question-description':
+ 'The security question is not set, and the security policy can effectively protect the account security',
+ 'app.settings.security.email': 'Backup Email',
+ 'app.settings.security.email-description': 'Bound Email',
+ 'app.settings.security.mfa': 'MFA Device',
+ 'app.settings.security.mfa-description':
+ 'Unbound MFA device, after binding, can be confirmed twice',
+ 'app.settings.security.modify': 'Modify',
+ 'app.settings.security.set': 'Set',
+ 'app.settings.security.bind': 'Bind',
+ 'app.settings.binding.taobao': 'Binding Taobao',
+ 'app.settings.binding.taobao-description': 'Currently unbound Taobao account',
+ 'app.settings.binding.alipay': 'Binding Alipay',
+ 'app.settings.binding.alipay-description': 'Currently unbound Alipay account',
+ 'app.settings.binding.dingding': 'Binding DingTalk',
+ 'app.settings.binding.dingding-description': 'Currently unbound DingTalk account',
+ 'app.settings.binding.bind': 'Bind',
+ 'app.settings.notification.password': 'Account Password',
+ 'app.settings.notification.password-description':
+ 'Messages from other users will be notified in the form of a station letter',
+ 'app.settings.notification.messages': 'System Messages',
+ 'app.settings.notification.messages-description':
+ 'System messages will be notified in the form of a station letter',
+ 'app.settings.notification.todo': 'To-do Notification',
+ 'app.settings.notification.todo-description':
+ 'The to-do list will be notified in the form of a letter from the station',
+ 'app.settings.open': 'Open',
+ 'app.settings.close': 'Close',
+};
diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts
new file mode 100644
index 0000000..7691489
--- /dev/null
+++ b/src/locales/zh-CN.ts
@@ -0,0 +1,25 @@
+import component from './zh-CN/component';
+import globalHeader from './zh-CN/globalHeader';
+import menu from './zh-CN/menu';
+import pages from './zh-CN/pages';
+import pwa from './zh-CN/pwa';
+import settingDrawer from './zh-CN/settingDrawer';
+import settings from './zh-CN/settings';
+
+export default {
+ 'navBar.lang': '语言',
+ 'layout.user.link.help': '帮助',
+ 'layout.user.link.privacy': '隐私',
+ 'layout.user.link.terms': '条款',
+ 'app.copyright.produced': '蚂蚁集团体验技术部出品',
+ 'app.preview.down.block': '下载此页面到本地项目',
+ 'app.welcome.link.fetch-blocks': '获取全部区块',
+ 'app.welcome.link.block-list': '基于 block 开发,快速构建标准页面',
+ ...pages,
+ ...globalHeader,
+ ...menu,
+ ...settingDrawer,
+ ...settings,
+ ...pwa,
+ ...component,
+};
diff --git a/src/locales/zh-CN/component.ts b/src/locales/zh-CN/component.ts
new file mode 100644
index 0000000..1f1fead
--- /dev/null
+++ b/src/locales/zh-CN/component.ts
@@ -0,0 +1,5 @@
+export default {
+ 'component.tagSelect.expand': '展开',
+ 'component.tagSelect.collapse': '收起',
+ 'component.tagSelect.all': '全部',
+};
diff --git a/src/locales/zh-CN/globalHeader.ts b/src/locales/zh-CN/globalHeader.ts
new file mode 100644
index 0000000..9fd66a5
--- /dev/null
+++ b/src/locales/zh-CN/globalHeader.ts
@@ -0,0 +1,17 @@
+export default {
+ 'component.globalHeader.search': '站内搜索',
+ 'component.globalHeader.search.example1': '搜索提示一',
+ 'component.globalHeader.search.example2': '搜索提示二',
+ 'component.globalHeader.search.example3': '搜索提示三',
+ 'component.globalHeader.help': '使用文档',
+ 'component.globalHeader.notification': '通知',
+ 'component.globalHeader.notification.empty': '你已查看所有通知',
+ 'component.globalHeader.message': '消息',
+ 'component.globalHeader.message.empty': '您已读完所有消息',
+ 'component.globalHeader.event': '待办',
+ 'component.globalHeader.event.empty': '你已完成所有待办',
+ 'component.noticeIcon.clear': '清空',
+ 'component.noticeIcon.cleared': '清空了',
+ 'component.noticeIcon.empty': '暂无数据',
+ 'component.noticeIcon.view-more': '查看更多',
+};
diff --git a/src/locales/zh-CN/menu.ts b/src/locales/zh-CN/menu.ts
new file mode 100644
index 0000000..47442c6
--- /dev/null
+++ b/src/locales/zh-CN/menu.ts
@@ -0,0 +1,53 @@
+export default {
+ 'menu.welcome': '欢迎',
+ 'menu.more-blocks': '更多区块',
+ 'menu.home': '首页',
+ 'menu.admin': '管理页',
+ 'menu.admin.sub-page': '二级管理页',
+ 'menu.admin.sub-page2': '二级管理页2',
+ 'menu.login': '登录',
+ 'menu.register': '注册',
+ 'menu.register-result': '注册结果',
+ 'menu.dashboard': 'Dashboard',
+ 'menu.dashboard.analysis': '分析页',
+ 'menu.dashboard.monitor': '监控页',
+ 'menu.dashboard.workplace': '工作台',
+ 'menu.exception.403': '403',
+ 'menu.exception.404': '404',
+ 'menu.exception.500': '500',
+ 'menu.form': '表单页',
+ 'menu.form.basic-form': '基础表单',
+ 'menu.form.step-form': '分步表单',
+ 'menu.form.step-form.info': '分步表单(填写转账信息)',
+ 'menu.form.step-form.confirm': '分步表单(确认转账信息)',
+ 'menu.form.step-form.result': '分步表单(完成)',
+ 'menu.form.advanced-form': '高级表单',
+ 'menu.list': '列表页',
+ 'menu.list.table-list': '查询表格',
+ 'menu.list.basic-list': '标准列表',
+ 'menu.list.card-list': '卡片列表',
+ 'menu.list.search-list': '搜索列表',
+ 'menu.list.search-list.articles': '搜索列表(文章)',
+ 'menu.list.search-list.projects': '搜索列表(项目)',
+ 'menu.list.search-list.applications': '搜索列表(应用)',
+ 'menu.profile': '详情页',
+ 'menu.profile.basic': '基础详情页',
+ 'menu.profile.advanced': '高级详情页',
+ 'menu.result': '结果页',
+ 'menu.result.success': '成功页',
+ 'menu.result.fail': '失败页',
+ 'menu.exception': '异常页',
+ 'menu.exception.not-permission': '403',
+ 'menu.exception.not-find': '404',
+ 'menu.exception.server-error': '500',
+ 'menu.exception.trigger': '触发错误',
+ 'menu.account': '个人页',
+ 'menu.account.center': '个人中心',
+ 'menu.account.settings': '个人设置',
+ 'menu.account.trigger': '触发报错',
+ 'menu.account.logout': '退出登录',
+ 'menu.editor': '图形编辑器',
+ 'menu.editor.flow': '流程编辑器',
+ 'menu.editor.mind': '脑图编辑器',
+ 'menu.editor.koni': '拓扑编辑器',
+};
diff --git a/src/locales/zh-CN/pages.ts b/src/locales/zh-CN/pages.ts
new file mode 100644
index 0000000..7fa751f
--- /dev/null
+++ b/src/locales/zh-CN/pages.ts
@@ -0,0 +1,65 @@
+export default {
+ 'pages.layouts.userLayout.title': 'Ant Design 是西湖区最具影响力的 Web 设计规范',
+ 'pages.login.accountLogin.tab': '账户密码登录',
+ 'pages.login.accountLogin.errorMessage': '错误的用户名和密码(admin/ant.design)',
+ 'pages.login.failure': '登录失败,请重试!',
+ 'pages.login.success': '登录成功!',
+ 'pages.login.username.placeholder': '用户名: admin or user',
+ 'pages.login.username.required': '用户名是必填项!',
+ 'pages.login.password.placeholder': '密码: ant.design',
+ 'pages.login.password.required': '密码是必填项!',
+ 'pages.login.phoneLogin.tab': '手机号登录',
+ 'pages.login.phoneLogin.errorMessage': '验证码错误',
+ 'pages.login.phoneNumber.placeholder': '请输入手机号!',
+ 'pages.login.phoneNumber.required': '手机号是必填项!',
+ 'pages.login.phoneNumber.invalid': '不合法的手机号!',
+ 'pages.login.captcha.placeholder': '请输入验证码!',
+ 'pages.login.captcha.required': '验证码是必填项!',
+ 'pages.login.phoneLogin.getVerificationCode': '获取验证码',
+ 'pages.getCaptchaSecondText': '秒后重新获取',
+ 'pages.login.rememberMe': '自动登录',
+ 'pages.login.forgotPassword': '忘记密码 ?',
+ 'pages.login.submit': '登录',
+ 'pages.login.loginWith': '其他登录方式 :',
+ 'pages.login.registerAccount': '注册账户',
+ 'pages.welcome.link': '欢迎使用',
+ 'pages.welcome.alertMessage': '更快更强的重型组件,已经发布。',
+ 'pages.admin.subPage.title': ' 这个页面只有 admin 权限才能查看',
+ 'pages.admin.subPage.alertMessage': 'umi ui 现已发布,欢迎使用 npm run ui 启动体验。',
+ 'pages.searchTable.createForm.newRule': '新建规则',
+ 'pages.searchTable.updateForm.ruleConfig': '规则配置',
+ 'pages.searchTable.updateForm.basicConfig': '基本信息',
+ 'pages.searchTable.updateForm.ruleName.nameLabel': '规则名称',
+ 'pages.searchTable.updateForm.ruleName.nameRules': '请输入规则名称!',
+ 'pages.searchTable.updateForm.ruleDesc.descLabel': '规则描述',
+ 'pages.searchTable.updateForm.ruleDesc.descPlaceholder': '请输入至少五个字符',
+ 'pages.searchTable.updateForm.ruleDesc.descRules': '请输入至少五个字符的规则描述!',
+ 'pages.searchTable.updateForm.ruleProps.title': '配置规则属性',
+ 'pages.searchTable.updateForm.object': '监控对象',
+ 'pages.searchTable.updateForm.ruleProps.templateLabel': '规则模板',
+ 'pages.searchTable.updateForm.ruleProps.typeLabel': '规则类型',
+ 'pages.searchTable.updateForm.schedulingPeriod.title': '设定调度周期',
+ 'pages.searchTable.updateForm.schedulingPeriod.timeLabel': '开始时间',
+ 'pages.searchTable.updateForm.schedulingPeriod.timeRules': '请选择开始时间!',
+ 'pages.searchTable.titleDesc': '描述',
+ 'pages.searchTable.ruleName': '规则名称为必填项',
+ 'pages.searchTable.titleCallNo': '服务调用次数',
+ 'pages.searchTable.titleStatus': '状态',
+ 'pages.searchTable.nameStatus.default': '关闭',
+ 'pages.searchTable.nameStatus.running': '运行中',
+ 'pages.searchTable.nameStatus.online': '已上线',
+ 'pages.searchTable.nameStatus.abnormal': '异常',
+ 'pages.searchTable.titleUpdatedAt': '上次调度时间',
+ 'pages.searchTable.exception': '请输入异常原因!',
+ 'pages.searchTable.titleOption': '操作',
+ 'pages.searchTable.config': '配置',
+ 'pages.searchTable.subscribeAlert': '订阅警报',
+ 'pages.searchTable.title': '查询表格',
+ 'pages.searchTable.new': '新建',
+ 'pages.searchTable.chosen': '已选择',
+ 'pages.searchTable.item': '项',
+ 'pages.searchTable.totalServiceCalls': '服务调用次数总计',
+ 'pages.searchTable.tenThousand': '万',
+ 'pages.searchTable.batchDeletion': '批量删除',
+ 'pages.searchTable.batchApproval': '批量审批',
+};
diff --git a/src/locales/zh-CN/pwa.ts b/src/locales/zh-CN/pwa.ts
new file mode 100644
index 0000000..e950484
--- /dev/null
+++ b/src/locales/zh-CN/pwa.ts
@@ -0,0 +1,6 @@
+export default {
+ 'app.pwa.offline': '当前处于离线状态',
+ 'app.pwa.serviceworker.updated': '有新内容',
+ 'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面',
+ 'app.pwa.serviceworker.updated.ok': '刷新',
+};
diff --git a/src/locales/zh-CN/settingDrawer.ts b/src/locales/zh-CN/settingDrawer.ts
new file mode 100644
index 0000000..3f44958
--- /dev/null
+++ b/src/locales/zh-CN/settingDrawer.ts
@@ -0,0 +1,31 @@
+export default {
+ 'app.setting.pagestyle': '整体风格设置',
+ 'app.setting.pagestyle.dark': '暗色菜单风格',
+ 'app.setting.pagestyle.light': '亮色菜单风格',
+ 'app.setting.content-width': '内容区域宽度',
+ 'app.setting.content-width.fixed': '定宽',
+ 'app.setting.content-width.fluid': '流式',
+ 'app.setting.themecolor': '主题色',
+ 'app.setting.themecolor.dust': '薄暮',
+ 'app.setting.themecolor.volcano': '火山',
+ 'app.setting.themecolor.sunset': '日暮',
+ 'app.setting.themecolor.cyan': '明青',
+ 'app.setting.themecolor.green': '极光绿',
+ 'app.setting.themecolor.daybreak': '拂晓蓝(默认)',
+ 'app.setting.themecolor.geekblue': '极客蓝',
+ 'app.setting.themecolor.purple': '酱紫',
+ 'app.setting.navigationmode': '导航模式',
+ 'app.setting.sidemenu': '侧边菜单布局',
+ 'app.setting.topmenu': '顶部菜单布局',
+ 'app.setting.fixedheader': '固定 Header',
+ 'app.setting.fixedsidebar': '固定侧边菜单',
+ 'app.setting.fixedsidebar.hint': '侧边菜单布局时可配置',
+ 'app.setting.hideheader': '下滑时隐藏 Header',
+ 'app.setting.hideheader.hint': '固定 Header 时可配置',
+ 'app.setting.othersettings': '其他设置',
+ 'app.setting.weakmode': '色弱模式',
+ 'app.setting.copy': '拷贝设置',
+ 'app.setting.copyinfo': '拷贝成功,请到 config/defaultSettings.js 中替换默认配置',
+ 'app.setting.production.hint':
+ '配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件',
+};
diff --git a/src/locales/zh-CN/settings.ts b/src/locales/zh-CN/settings.ts
new file mode 100644
index 0000000..df8af43
--- /dev/null
+++ b/src/locales/zh-CN/settings.ts
@@ -0,0 +1,55 @@
+export default {
+ 'app.settings.menuMap.basic': '基本设置',
+ 'app.settings.menuMap.security': '安全设置',
+ 'app.settings.menuMap.binding': '账号绑定',
+ 'app.settings.menuMap.notification': '新消息通知',
+ 'app.settings.basic.avatar': '头像',
+ 'app.settings.basic.change-avatar': '更换头像',
+ 'app.settings.basic.email': '邮箱',
+ 'app.settings.basic.email-message': '请输入您的邮箱!',
+ 'app.settings.basic.nickname': '昵称',
+ 'app.settings.basic.nickname-message': '请输入您的昵称!',
+ 'app.settings.basic.profile': '个人简介',
+ 'app.settings.basic.profile-message': '请输入个人简介!',
+ 'app.settings.basic.profile-placeholder': '个人简介',
+ 'app.settings.basic.country': '国家/地区',
+ 'app.settings.basic.country-message': '请输入您的国家或地区!',
+ 'app.settings.basic.geographic': '所在省市',
+ 'app.settings.basic.geographic-message': '请输入您的所在省市!',
+ 'app.settings.basic.address': '街道地址',
+ 'app.settings.basic.address-message': '请输入您的街道地址!',
+ 'app.settings.basic.phone': '联系电话',
+ 'app.settings.basic.phone-message': '请输入您的联系电话!',
+ 'app.settings.basic.update': '更新基本信息',
+ 'app.settings.security.strong': '强',
+ 'app.settings.security.medium': '中',
+ 'app.settings.security.weak': '弱',
+ 'app.settings.security.password': '账户密码',
+ 'app.settings.security.password-description': '当前密码强度',
+ 'app.settings.security.phone': '密保手机',
+ 'app.settings.security.phone-description': '已绑定手机',
+ 'app.settings.security.question': '密保问题',
+ 'app.settings.security.question-description': '未设置密保问题,密保问题可有效保护账户安全',
+ 'app.settings.security.email': '备用邮箱',
+ 'app.settings.security.email-description': '已绑定邮箱',
+ 'app.settings.security.mfa': 'MFA 设备',
+ 'app.settings.security.mfa-description': '未绑定 MFA 设备,绑定后,可以进行二次确认',
+ 'app.settings.security.modify': '修改',
+ 'app.settings.security.set': '设置',
+ 'app.settings.security.bind': '绑定',
+ 'app.settings.binding.taobao': '绑定淘宝',
+ 'app.settings.binding.taobao-description': '当前未绑定淘宝账号',
+ 'app.settings.binding.alipay': '绑定支付宝',
+ 'app.settings.binding.alipay-description': '当前未绑定支付宝账号',
+ 'app.settings.binding.dingding': '绑定钉钉',
+ 'app.settings.binding.dingding-description': '当前未绑定钉钉账号',
+ 'app.settings.binding.bind': '绑定',
+ 'app.settings.notification.password': '账户密码',
+ 'app.settings.notification.password-description': '其他用户的消息将以站内信的形式通知',
+ 'app.settings.notification.messages': '系统消息',
+ 'app.settings.notification.messages-description': '系统消息将以站内信的形式通知',
+ 'app.settings.notification.todo': '待办任务',
+ 'app.settings.notification.todo-description': '待办任务将以站内信的形式通知',
+ 'app.settings.open': '开',
+ 'app.settings.close': '关',
+};
diff --git a/src/manifest.json b/src/manifest.json
new file mode 100644
index 0000000..839bc5b
--- /dev/null
+++ b/src/manifest.json
@@ -0,0 +1,22 @@
+{
+ "name": "Ant Design Pro",
+ "short_name": "Ant Design Pro",
+ "display": "standalone",
+ "start_url": "./?utm_source=homescreen",
+ "theme_color": "#002140",
+ "background_color": "#001529",
+ "icons": [
+ {
+ "src": "icons/icon-192x192.png",
+ "sizes": "192x192"
+ },
+ {
+ "src": "icons/icon-128x128.png",
+ "sizes": "128x128"
+ },
+ {
+ "src": "icons/icon-512x512.png",
+ "sizes": "512x512"
+ }
+ ]
+}
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
new file mode 100644
index 0000000..0263687
--- /dev/null
+++ b/src/pages/404.tsx
@@ -0,0 +1,18 @@
+import { history } from '@umijs/max';
+import { Button, Result } from 'antd';
+import React from 'react';
+
+const NoFoundPage: React.FC = () => (
+ history.push('/')}>
+ Back Home
+
+ }
+ />
+);
+
+export default NoFoundPage;
diff --git a/src/pages/Admin.tsx b/src/pages/Admin.tsx
new file mode 100644
index 0000000..2f93986
--- /dev/null
+++ b/src/pages/Admin.tsx
@@ -0,0 +1,45 @@
+import { HeartTwoTone, SmileTwoTone } from '@ant-design/icons';
+import { PageContainer } from '@ant-design/pro-components';
+import { useIntl } from '@umijs/max';
+import { Alert, Card, Typography } from 'antd';
+import React from 'react';
+
+const Admin: React.FC = () => {
+ const intl = useIntl();
+ return (
+
+
+
+
+ Ant Design Pro You
+
+
+
+ Want to add more pages? Please refer to{' '}
+
+ use block
+
+ 。
+
+
+ );
+};
+
+export default Admin;
diff --git a/src/pages/TableList/components/UpdateForm.tsx b/src/pages/TableList/components/UpdateForm.tsx
new file mode 100644
index 0000000..5cd603e
--- /dev/null
+++ b/src/pages/TableList/components/UpdateForm.tsx
@@ -0,0 +1,209 @@
+import {
+ ProFormDateTimePicker,
+ ProFormRadio,
+ ProFormSelect,
+ ProFormText,
+ ProFormTextArea,
+ StepsForm,
+} from '@ant-design/pro-components';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import { Modal } from 'antd';
+import React from 'react';
+
+export type FormValueType = {
+ target?: string;
+ template?: string;
+ type?: string;
+ time?: string;
+ frequency?: string;
+} & Partial;
+
+export type UpdateFormProps = {
+ onCancel: (flag?: boolean, formVals?: FormValueType) => void;
+ onSubmit: (values: FormValueType) => Promise;
+ updateModalOpen: boolean;
+ values: Partial;
+};
+
+const UpdateForm: React.FC = (props) => {
+ const intl = useIntl();
+ return (
+ {
+ return (
+ {
+ props.onCancel();
+ }}
+ >
+ {dom}
+
+ );
+ }}
+ onFinish={props.onSubmit}
+ >
+
+
+ ),
+ },
+ ]}
+ />
+
+ ),
+ min: 5,
+ },
+ ]}
+ />
+
+
+
+
+
+
+
+
+ ),
+ },
+ ]}
+ />
+
+
+
+ );
+};
+
+export default UpdateForm;
diff --git a/src/pages/TableList/index.tsx b/src/pages/TableList/index.tsx
new file mode 100644
index 0000000..c201007
--- /dev/null
+++ b/src/pages/TableList/index.tsx
@@ -0,0 +1,397 @@
+import { addRule, removeRule, rule, updateRule } from '@/services/ant-design-pro/api';
+import { PlusOutlined } from '@ant-design/icons';
+import type { ActionType, ProColumns, ProDescriptionsItemProps } from '@ant-design/pro-components';
+import {
+ FooterToolbar,
+ ModalForm,
+ PageContainer,
+ ProDescriptions,
+ ProFormText,
+ ProFormTextArea,
+ ProTable,
+} from '@ant-design/pro-components';
+import { FormattedMessage, useIntl } from '@umijs/max';
+import { Button, Drawer, Input, message } from 'antd';
+import React, { useRef, useState } from 'react';
+import type { FormValueType } from './components/UpdateForm';
+import UpdateForm from './components/UpdateForm';
+
+/**
+ * @en-US Add node
+ * @zh-CN 添加节点
+ * @param fields
+ */
+const handleAdd = async (fields: API.RuleListItem) => {
+ const hide = message.loading('正在添加');
+ try {
+ await addRule({ ...fields });
+ hide();
+ message.success('Added successfully');
+ return true;
+ } catch (error) {
+ hide();
+ message.error('Adding failed, please try again!');
+ return false;
+ }
+};
+
+/**
+ * @en-US Update node
+ * @zh-CN 更新节点
+ *
+ * @param fields
+ */
+const handleUpdate = async (fields: FormValueType) => {
+ const hide = message.loading('Configuring');
+ try {
+ await updateRule({
+ name: fields.name,
+ desc: fields.desc,
+ key: fields.key,
+ });
+ hide();
+
+ message.success('Configuration is successful');
+ return true;
+ } catch (error) {
+ hide();
+ message.error('Configuration failed, please try again!');
+ return false;
+ }
+};
+
+/**
+ * Delete node
+ * @zh-CN 删除节点
+ *
+ * @param selectedRows
+ */
+const handleRemove = async (selectedRows: API.RuleListItem[]) => {
+ const hide = message.loading('正在删除');
+ if (!selectedRows) return true;
+ try {
+ await removeRule({
+ key: selectedRows.map((row) => row.key),
+ });
+ hide();
+ message.success('Deleted successfully and will refresh soon');
+ return true;
+ } catch (error) {
+ hide();
+ message.error('Delete failed, please try again');
+ return false;
+ }
+};
+
+const TableList: React.FC = () => {
+ /**
+ * @en-US Pop-up window of new window
+ * @zh-CN 新建窗口的弹窗
+ * */
+ const [createModalOpen, handleModalOpen] = useState(false);
+ /**
+ * @en-US The pop-up window of the distribution update window
+ * @zh-CN 分布更新窗口的弹窗
+ * */
+ const [updateModalOpen, handleUpdateModalOpen] = useState(false);
+
+ const [showDetail, setShowDetail] = useState(false);
+
+ const actionRef = useRef();
+ const [currentRow, setCurrentRow] = useState();
+ const [selectedRowsState, setSelectedRows] = useState([]);
+
+ /**
+ * @en-US International configuration
+ * @zh-CN 国际化配置
+ * */
+ const intl = useIntl();
+
+ const columns: ProColumns[] = [
+ {
+ title: (
+
+ ),
+ dataIndex: 'name',
+ tip: 'The rule name is the unique key',
+ render: (dom, entity) => {
+ return (
+ {
+ setCurrentRow(entity);
+ setShowDetail(true);
+ }}
+ >
+ {dom}
+
+ );
+ },
+ },
+ {
+ title: ,
+ dataIndex: 'desc',
+ valueType: 'textarea',
+ },
+ {
+ title: (
+
+ ),
+ dataIndex: 'callNo',
+ sorter: true,
+ hideInForm: true,
+ renderText: (val: string) =>
+ `${val}${intl.formatMessage({
+ id: 'pages.searchTable.tenThousand',
+ defaultMessage: ' 万 ',
+ })}`,
+ },
+ {
+ title: ,
+ dataIndex: 'status',
+ hideInForm: true,
+ valueEnum: {
+ 0: {
+ text: (
+
+ ),
+ status: 'Default',
+ },
+ 1: {
+ text: (
+
+ ),
+ status: 'Processing',
+ },
+ 2: {
+ text: (
+
+ ),
+ status: 'Success',
+ },
+ 3: {
+ text: (
+
+ ),
+ status: 'Error',
+ },
+ },
+ },
+ {
+ title: (
+
+ ),
+ sorter: true,
+ dataIndex: 'updatedAt',
+ valueType: 'dateTime',
+ renderFormItem: (item, { defaultRender, ...rest }, form) => {
+ const status = form.getFieldValue('status');
+ if (`${status}` === '0') {
+ return false;
+ }
+ if (`${status}` === '3') {
+ return (
+
+ );
+ }
+ return defaultRender(item);
+ },
+ },
+ {
+ title: ,
+ dataIndex: 'option',
+ valueType: 'option',
+ render: (_, record) => [
+ {
+ handleUpdateModalOpen(true);
+ setCurrentRow(record);
+ }}
+ >
+
+ ,
+
+
+ ,
+ ],
+ },
+ ];
+
+ return (
+
+
+ headerTitle={intl.formatMessage({
+ id: 'pages.searchTable.title',
+ defaultMessage: 'Enquiry form',
+ })}
+ actionRef={actionRef}
+ rowKey="key"
+ search={{
+ labelWidth: 120,
+ }}
+ toolBarRender={() => [
+ ,
+ ]}
+ request={rule}
+ columns={columns}
+ rowSelection={{
+ onChange: (_, selectedRows) => {
+ setSelectedRows(selectedRows);
+ },
+ }}
+ />
+ {selectedRowsState?.length > 0 && (
+
+ {' '}
+ {selectedRowsState.length}{' '}
+
+
+
+ {' '}
+ {selectedRowsState.reduce((pre, item) => pre + item.callNo!, 0)}{' '}
+
+
+
+ }
+ >
+
+
+
+ )}
+ {
+ const success = await handleAdd(value as API.RuleListItem);
+ if (success) {
+ handleModalOpen(false);
+ if (actionRef.current) {
+ actionRef.current.reload();
+ }
+ }
+ }}
+ >
+
+ ),
+ },
+ ]}
+ width="md"
+ name="name"
+ />
+
+
+ {
+ const success = await handleUpdate(value);
+ if (success) {
+ handleUpdateModalOpen(false);
+ setCurrentRow(undefined);
+ if (actionRef.current) {
+ actionRef.current.reload();
+ }
+ }
+ }}
+ onCancel={() => {
+ handleUpdateModalOpen(false);
+ if (!showDetail) {
+ setCurrentRow(undefined);
+ }
+ }}
+ updateModalOpen={updateModalOpen}
+ values={currentRow || {}}
+ />
+
+ {
+ setCurrentRow(undefined);
+ setShowDetail(false);
+ }}
+ closable={false}
+ >
+ {currentRow?.name && (
+
+ column={2}
+ title={currentRow?.name}
+ request={async () => ({
+ data: currentRow || {},
+ })}
+ params={{
+ id: currentRow?.name,
+ }}
+ columns={columns as ProDescriptionsItemProps[]}
+ />
+ )}
+
+
+ );
+};
+
+export default TableList;
diff --git a/src/pages/User/Login/__snapshots__/login.test.tsx.snap b/src/pages/User/Login/__snapshots__/login.test.tsx.snap
new file mode 100644
index 0000000..af647ff
--- /dev/null
+++ b/src/pages/User/Login/__snapshots__/login.test.tsx.snap
@@ -0,0 +1,1114 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Login Page should login success 1`] = `
+
+
+
+`;
+
+exports[`Login Page should show login form 1`] = `
+
+
+
+`;
diff --git a/src/pages/User/Login/index.tsx b/src/pages/User/Login/index.tsx
new file mode 100644
index 0000000..ef48307
--- /dev/null
+++ b/src/pages/User/Login/index.tsx
@@ -0,0 +1,371 @@
+import Footer from '@/components/Footer';
+import { login } from '@/services/ant-design-pro/api';
+import { getFakeCaptcha } from '@/services/ant-design-pro/login';
+import {
+ AlipayCircleOutlined,
+ LockOutlined,
+ MobileOutlined,
+ TaobaoCircleOutlined,
+ UserOutlined,
+ WeiboCircleOutlined,
+} from '@ant-design/icons';
+import {
+ LoginForm,
+ ProFormCaptcha,
+ ProFormCheckbox,
+ ProFormText,
+} from '@ant-design/pro-components';
+import { useEmotionCss } from '@ant-design/use-emotion-css';
+import { FormattedMessage, history, SelectLang, useIntl, useModel, Helmet } from '@umijs/max';
+import { Alert, message, Tabs } from 'antd';
+import Settings from '../../../../config/defaultSettings';
+import React, { useState } from 'react';
+import { flushSync } from 'react-dom';
+
+const ActionIcons = () => {
+ const langClassName = useEmotionCss(({ token }) => {
+ return {
+ marginLeft: '8px',
+ color: 'rgba(0, 0, 0, 0.2)',
+ fontSize: '24px',
+ verticalAlign: 'middle',
+ cursor: 'pointer',
+ transition: 'color 0.3s',
+ '&:hover': {
+ color: token.colorPrimaryActive,
+ },
+ };
+ });
+
+ return (
+ <>
+
+
+
+ >
+ );
+};
+
+const Lang = () => {
+ const langClassName = useEmotionCss(({ token }) => {
+ return {
+ width: 42,
+ height: 42,
+ lineHeight: '42px',
+ position: 'fixed',
+ right: 16,
+ borderRadius: token.borderRadius,
+ ':hover': {
+ backgroundColor: token.colorBgTextHover,
+ },
+ };
+ });
+
+ return (
+
+ {SelectLang && }
+
+ );
+};
+
+const LoginMessage: React.FC<{
+ content: string;
+}> = ({ content }) => {
+ return (
+
+ );
+};
+
+const Login: React.FC = () => {
+ const [userLoginState, setUserLoginState] = useState({});
+ const [type, setType] = useState('account');
+ const { initialState, setInitialState } = useModel('@@initialState');
+
+ const containerClassName = useEmotionCss(() => {
+ return {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '100vh',
+ overflow: 'auto',
+ backgroundImage:
+ "url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
+ backgroundSize: '100% 100%',
+ };
+ });
+
+ const intl = useIntl();
+
+ const fetchUserInfo = async () => {
+ const userInfo = await initialState?.fetchUserInfo?.();
+ if (userInfo) {
+ flushSync(() => {
+ setInitialState((s) => ({
+ ...s,
+ currentUser: userInfo,
+ }));
+ });
+ }
+ };
+
+ const handleSubmit = async (values: API.LoginParams) => {
+ try {
+ // 登录
+ const msg = await login({ ...values, type });
+ if (msg.status === 'ok') {
+ const defaultLoginSuccessMessage = intl.formatMessage({
+ id: 'pages.login.success',
+ defaultMessage: '登录成功!',
+ });
+ message.success(defaultLoginSuccessMessage);
+ await fetchUserInfo();
+ const urlParams = new URL(window.location.href).searchParams;
+ history.push(urlParams.get('redirect') || '/');
+ return;
+ }
+ console.log(msg);
+ // 如果失败去设置用户错误信息
+ setUserLoginState(msg);
+ } catch (error) {
+ const defaultLoginFailureMessage = intl.formatMessage({
+ id: 'pages.login.failure',
+ defaultMessage: '登录失败,请重试!',
+ });
+ console.log(error);
+ message.error(defaultLoginFailureMessage);
+ }
+ };
+ const { status, type: loginType } = userLoginState;
+
+ return (
+
+
+
+ {intl.formatMessage({
+ id: 'menu.login',
+ defaultMessage: '登录页',
+ })}
+ - {Settings.title}
+
+
+
+
+
}
+ title="Ant Design"
+ subTitle={intl.formatMessage({ id: 'pages.layouts.userLayout.title' })}
+ initialValues={{
+ autoLogin: true,
+ }}
+ actions={[
+
,
+
,
+ ]}
+ onFinish={async (values) => {
+ await handleSubmit(values as API.LoginParams);
+ }}
+ >
+
+
+ {status === 'error' && loginType === 'account' && (
+
+ )}
+ {type === 'account' && (
+ <>
+
,
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.username.placeholder',
+ defaultMessage: '用户名: admin or user',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+
,
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.password.placeholder',
+ defaultMessage: '密码: ant.design',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+ >
+ )}
+
+ {status === 'error' && loginType === 'mobile' &&
}
+ {type === 'mobile' && (
+ <>
+
,
+ }}
+ name="mobile"
+ placeholder={intl.formatMessage({
+ id: 'pages.login.phoneNumber.placeholder',
+ defaultMessage: '手机号',
+ })}
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ {
+ pattern: /^1\d{10}$/,
+ message: (
+
+ ),
+ },
+ ]}
+ />
+
,
+ }}
+ captchaProps={{
+ size: 'large',
+ }}
+ placeholder={intl.formatMessage({
+ id: 'pages.login.captcha.placeholder',
+ defaultMessage: '请输入验证码',
+ })}
+ captchaTextRender={(timing, count) => {
+ if (timing) {
+ return `${count} ${intl.formatMessage({
+ id: 'pages.getCaptchaSecondText',
+ defaultMessage: '获取验证码',
+ })}`;
+ }
+ return intl.formatMessage({
+ id: 'pages.login.phoneLogin.getVerificationCode',
+ defaultMessage: '获取验证码',
+ });
+ }}
+ name="captcha"
+ rules={[
+ {
+ required: true,
+ message: (
+
+ ),
+ },
+ ]}
+ onGetCaptcha={async (phone) => {
+ const result = await getFakeCaptcha({
+ phone,
+ });
+ if (!result) {
+ return;
+ }
+ message.success('获取验证码成功!验证码为:1234');
+ }}
+ />
+ >
+ )}
+
+
+
+
+
+ );
+};
+
+export default Login;
diff --git a/src/pages/User/Login/login.test.tsx b/src/pages/User/Login/login.test.tsx
new file mode 100644
index 0000000..18593f8
--- /dev/null
+++ b/src/pages/User/Login/login.test.tsx
@@ -0,0 +1,96 @@
+import { render, fireEvent, act } from '@testing-library/react';
+import React from 'react';
+import { TestBrowser } from '@@/testBrowser';
+
+// @ts-ignore
+import { startMock } from '@@/requestRecordMock';
+
+const waitTime = (time: number = 100) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(true);
+ }, time);
+ });
+};
+
+let server: {
+ close: () => void;
+};
+
+describe('Login Page', () => {
+ beforeAll(async () => {
+ server = await startMock({
+ port: 8000,
+ scene: 'login',
+ });
+ });
+
+ afterAll(() => {
+ server?.close();
+ });
+
+ it('should show login form', async () => {
+ const historyRef = React.createRef();
+ const rootContainer = render(
+ ,
+ );
+
+ await rootContainer.findAllByText('Ant Design');
+
+ act(() => {
+ historyRef.current?.push('/user/login');
+ });
+
+ expect(rootContainer.baseElement?.querySelector('.ant-pro-form-login-desc')?.textContent).toBe(
+ 'Ant Design is the most influential web design specification in Xihu district',
+ );
+
+ expect(rootContainer.asFragment()).toMatchSnapshot();
+
+ rootContainer.unmount();
+ });
+
+ it('should login success', async () => {
+ const historyRef = React.createRef();
+ const rootContainer = render(
+ ,
+ );
+
+ await rootContainer.findAllByText('Ant Design');
+
+ const userNameInput = await rootContainer.findByPlaceholderText('Username: admin or user');
+
+ act(() => {
+ fireEvent.change(userNameInput, { target: { value: 'admin' } });
+ });
+
+ const passwordInput = await rootContainer.findByPlaceholderText('Password: ant.design');
+
+ act(() => {
+ fireEvent.change(passwordInput, { target: { value: 'ant.design' } });
+ });
+
+ await (await rootContainer.findByText('Login')).click();
+
+ // 等待接口返回结果
+ await waitTime(5000);
+
+ await rootContainer.findAllByText('Ant Design Pro');
+
+ expect(rootContainer.asFragment()).toMatchSnapshot();
+
+ await waitTime(2000);
+
+ rootContainer.unmount();
+ });
+});
diff --git a/src/pages/Welcome.tsx b/src/pages/Welcome.tsx
new file mode 100644
index 0000000..d0c49f7
--- /dev/null
+++ b/src/pages/Welcome.tsx
@@ -0,0 +1,164 @@
+import { PageContainer } from '@ant-design/pro-components';
+import { useModel } from '@umijs/max';
+import { Card, theme } from 'antd';
+import React from 'react';
+
+/**
+ * 每个单独的卡片,为了复用样式抽成了组件
+ * @param param0
+ * @returns
+ */
+const InfoCard: React.FC<{
+ title: string;
+ index: number;
+ desc: string;
+ href: string;
+}> = ({ title, href, index, desc }) => {
+ const { useToken } = theme;
+
+ const { token } = useToken();
+
+ return (
+
+ );
+};
+
+const Welcome: React.FC = () => {
+ const { token } = theme.useToken();
+ const { initialState } = useModel('@@initialState');
+ return (
+
+
+
+
+ 欢迎使用 Ant Design Pro
+
+
+ Ant Design Pro 是一个整合了 umi,Ant Design 和 ProComponents
+ 的脚手架方案。致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Welcome;
diff --git a/src/requestErrorConfig.ts b/src/requestErrorConfig.ts
new file mode 100644
index 0000000..c0c4a6a
--- /dev/null
+++ b/src/requestErrorConfig.ts
@@ -0,0 +1,109 @@
+import type { RequestOptions } from '@@/plugin-request/request';
+import type { RequestConfig } from '@umijs/max';
+import { message, notification } from 'antd';
+
+// 错误处理方案: 错误类型
+enum ErrorShowType {
+ SILENT = 0,
+ WARN_MESSAGE = 1,
+ ERROR_MESSAGE = 2,
+ NOTIFICATION = 3,
+ REDIRECT = 9,
+}
+// 与后端约定的响应数据格式
+interface ResponseStructure {
+ success: boolean;
+ data: any;
+ errorCode?: number;
+ errorMessage?: string;
+ showType?: ErrorShowType;
+}
+
+/**
+ * @name 错误处理
+ * pro 自带的错误处理, 可以在这里做自己的改动
+ * @doc https://umijs.org/docs/max/request#配置
+ */
+export const errorConfig: RequestConfig = {
+ // 错误处理: umi@3 的错误处理方案。
+ errorConfig: {
+ // 错误抛出
+ errorThrower: (res) => {
+ const { success, data, errorCode, errorMessage, showType } =
+ res as unknown as ResponseStructure;
+ if (!success) {
+ const error: any = new Error(errorMessage);
+ error.name = 'BizError';
+ error.info = { errorCode, errorMessage, showType, data };
+ throw error; // 抛出自制的错误
+ }
+ },
+ // 错误接收及处理
+ errorHandler: (error: any, opts: any) => {
+ if (opts?.skipErrorHandler) throw error;
+ // 我们的 errorThrower 抛出的错误。
+ if (error.name === 'BizError') {
+ const errorInfo: ResponseStructure | undefined = error.info;
+ if (errorInfo) {
+ const { errorMessage, errorCode } = errorInfo;
+ switch (errorInfo.showType) {
+ case ErrorShowType.SILENT:
+ // do nothing
+ break;
+ case ErrorShowType.WARN_MESSAGE:
+ message.warning(errorMessage);
+ break;
+ case ErrorShowType.ERROR_MESSAGE:
+ message.error(errorMessage);
+ break;
+ case ErrorShowType.NOTIFICATION:
+ notification.open({
+ description: errorMessage,
+ message: errorCode,
+ });
+ break;
+ case ErrorShowType.REDIRECT:
+ // TODO: redirect
+ break;
+ default:
+ message.error(errorMessage);
+ }
+ }
+ } else if (error.response) {
+ // Axios 的错误
+ // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
+ message.error(`Response status:${error.response.status}`);
+ } else if (error.request) {
+ // 请求已经成功发起,但没有收到响应
+ // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
+ // 而在node.js中是 http.ClientRequest 的实例
+ message.error('None response! Please retry.');
+ } else {
+ // 发送请求时出了点问题
+ message.error('Request error, please retry.');
+ }
+ },
+ },
+
+ // 请求拦截器
+ requestInterceptors: [
+ (config: RequestOptions) => {
+ // 拦截请求配置,进行个性化处理。
+ const url = config?.url?.concat('?token = 123');
+ return { ...config, url };
+ },
+ ],
+
+ // 响应拦截器
+ responseInterceptors: [
+ (response) => {
+ // 拦截响应数据,进行个性化处理
+ const { data } = response as unknown as ResponseStructure;
+
+ if (data?.success === false) {
+ message.error('请求失败!');
+ }
+ return response;
+ },
+ ],
+};
diff --git a/src/service-worker.js b/src/service-worker.js
new file mode 100644
index 0000000..b86726c
--- /dev/null
+++ b/src/service-worker.js
@@ -0,0 +1,65 @@
+/* eslint-disable no-restricted-globals */
+/* eslint-disable no-underscore-dangle */
+/* globals workbox */
+workbox.core.setCacheNameDetails({
+ prefix: 'antd-pro',
+ suffix: 'v5',
+});
+// Control all opened tabs ASAP
+workbox.clientsClaim();
+
+/**
+ * Use precaching list generated by workbox in build process.
+ * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.precaching
+ */
+workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
+
+/**
+ * Register a navigation route.
+ * https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
+ */
+workbox.routing.registerNavigationRoute('/index.html');
+
+/**
+ * Use runtime cache:
+ * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.routing#.registerRoute
+ *
+ * Workbox provides all common caching strategies including CacheFirst, NetworkFirst etc.
+ * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies
+ */
+
+/** Handle API requests */
+workbox.routing.registerRoute(/\/api\//, workbox.strategies.networkFirst());
+
+/** Handle third party requests */
+workbox.routing.registerRoute(
+ /^https:\/\/gw\.alipayobjects\.com\//,
+ workbox.strategies.networkFirst(),
+);
+workbox.routing.registerRoute(
+ /^https:\/\/cdnjs\.cloudflare\.com\//,
+ workbox.strategies.networkFirst(),
+);
+workbox.routing.registerRoute(/\/color.less/, workbox.strategies.networkFirst());
+
+/** Response to client after skipping waiting with MessageChannel */
+addEventListener('message', (event) => {
+ const replyPort = event.ports[0];
+ const message = event.data;
+ if (replyPort && message && message.type === 'skip-waiting') {
+ event.waitUntil(
+ self.skipWaiting().then(
+ () => {
+ replyPort.postMessage({
+ error: null,
+ });
+ },
+ (error) => {
+ replyPort.postMessage({
+ error,
+ });
+ },
+ ),
+ );
+ }
+});
diff --git a/src/services/ant-design-pro/api.ts b/src/services/ant-design-pro/api.ts
new file mode 100644
index 0000000..cbd5961
--- /dev/null
+++ b/src/services/ant-design-pro/api.ts
@@ -0,0 +1,85 @@
+// @ts-ignore
+/* eslint-disable */
+import { request } from '@umijs/max';
+
+/** 获取当前的用户 GET /api/currentUser */
+export async function currentUser(options?: { [key: string]: any }) {
+ return request<{
+ data: API.CurrentUser;
+ }>('/api/currentUser', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+
+/** 退出登录接口 POST /api/login/outLogin */
+export async function outLogin(options?: { [key: string]: any }) {
+ return request>('/api/login/outLogin', {
+ method: 'POST',
+ ...(options || {}),
+ });
+}
+
+/** 登录接口 POST /api/login/account */
+export async function login(body: API.LoginParams, options?: { [key: string]: any }) {
+ return request('/api/login/account', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** 此处后端没有提供注释 GET /api/notices */
+export async function getNotices(options?: { [key: string]: any }) {
+ return request('/api/notices', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+
+/** 获取规则列表 GET /api/rule */
+export async function rule(
+ params: {
+ // query
+ /** 当前的页码 */
+ current?: number;
+ /** 页面的容量 */
+ pageSize?: number;
+ },
+ options?: { [key: string]: any },
+) {
+ return request('/api/rule', {
+ method: 'GET',
+ params: {
+ ...params,
+ },
+ ...(options || {}),
+ });
+}
+
+/** 新建规则 PUT /api/rule */
+export async function updateRule(options?: { [key: string]: any }) {
+ return request('/api/rule', {
+ method: 'PUT',
+ ...(options || {}),
+ });
+}
+
+/** 新建规则 POST /api/rule */
+export async function addRule(options?: { [key: string]: any }) {
+ return request('/api/rule', {
+ method: 'POST',
+ ...(options || {}),
+ });
+}
+
+/** 删除规则 DELETE /api/rule */
+export async function removeRule(options?: { [key: string]: any }) {
+ return request>('/api/rule', {
+ method: 'DELETE',
+ ...(options || {}),
+ });
+}
diff --git a/src/services/ant-design-pro/index.ts b/src/services/ant-design-pro/index.ts
new file mode 100644
index 0000000..1ac489f
--- /dev/null
+++ b/src/services/ant-design-pro/index.ts
@@ -0,0 +1,10 @@
+// @ts-ignore
+/* eslint-disable */
+// API 更新时间:
+// API 唯一标识:
+import * as api from './api';
+import * as login from './login';
+export default {
+ api,
+ login,
+};
diff --git a/src/services/ant-design-pro/login.ts b/src/services/ant-design-pro/login.ts
new file mode 100644
index 0000000..8871ed8
--- /dev/null
+++ b/src/services/ant-design-pro/login.ts
@@ -0,0 +1,21 @@
+// @ts-ignore
+/* eslint-disable */
+import { request } from '@umijs/max';
+
+/** 发送验证码 POST /api/login/captcha */
+export async function getFakeCaptcha(
+ params: {
+ // query
+ /** 手机号 */
+ phone?: string;
+ },
+ options?: { [key: string]: any },
+) {
+ return request('/api/login/captcha', {
+ method: 'GET',
+ params: {
+ ...params,
+ },
+ ...(options || {}),
+ });
+}
diff --git a/src/services/ant-design-pro/typings.d.ts b/src/services/ant-design-pro/typings.d.ts
new file mode 100644
index 0000000..13e5a68
--- /dev/null
+++ b/src/services/ant-design-pro/typings.d.ts
@@ -0,0 +1,101 @@
+// @ts-ignore
+/* eslint-disable */
+
+declare namespace API {
+ type CurrentUser = {
+ name?: string;
+ avatar?: string;
+ userid?: string;
+ email?: string;
+ signature?: string;
+ title?: string;
+ group?: string;
+ tags?: { key?: string; label?: string }[];
+ notifyCount?: number;
+ unreadCount?: number;
+ country?: string;
+ access?: string;
+ geographic?: {
+ province?: { label?: string; key?: string };
+ city?: { label?: string; key?: string };
+ };
+ address?: string;
+ phone?: string;
+ };
+
+ type LoginResult = {
+ status?: string;
+ type?: string;
+ currentAuthority?: string;
+ };
+
+ type PageParams = {
+ current?: number;
+ pageSize?: number;
+ };
+
+ type RuleListItem = {
+ key?: number;
+ disabled?: boolean;
+ href?: string;
+ avatar?: string;
+ name?: string;
+ owner?: string;
+ desc?: string;
+ callNo?: number;
+ status?: number;
+ updatedAt?: string;
+ createdAt?: string;
+ progress?: number;
+ };
+
+ type RuleList = {
+ data?: RuleListItem[];
+ /** 列表的内容总数 */
+ total?: number;
+ success?: boolean;
+ };
+
+ type FakeCaptcha = {
+ code?: number;
+ status?: string;
+ };
+
+ type LoginParams = {
+ username?: string;
+ password?: string;
+ autoLogin?: boolean;
+ type?: string;
+ };
+
+ type ErrorResponse = {
+ /** 业务约定的错误码 */
+ errorCode: string;
+ /** 业务上的错误信息 */
+ errorMessage?: string;
+ /** 业务上的请求是否成功 */
+ success?: boolean;
+ };
+
+ type NoticeIconList = {
+ data?: NoticeIconItem[];
+ /** 列表的内容总数 */
+ total?: number;
+ success?: boolean;
+ };
+
+ type NoticeIconItemType = 'notification' | 'message' | 'event';
+
+ type NoticeIconItem = {
+ id?: string;
+ extra?: string;
+ key?: string;
+ read?: boolean;
+ avatar?: string;
+ title?: string;
+ status?: string;
+ datetime?: string;
+ description?: string;
+ type?: NoticeIconItemType;
+ };
+}
diff --git a/src/services/swagger/index.ts b/src/services/swagger/index.ts
new file mode 100644
index 0000000..83cf97c
--- /dev/null
+++ b/src/services/swagger/index.ts
@@ -0,0 +1,12 @@
+// @ts-ignore
+/* eslint-disable */
+// API 更新时间:
+// API 唯一标识:
+import * as pet from './pet';
+import * as store from './store';
+import * as user from './user';
+export default {
+ pet,
+ store,
+ user,
+};
diff --git a/src/services/swagger/pet.ts b/src/services/swagger/pet.ts
new file mode 100644
index 0000000..b887475
--- /dev/null
+++ b/src/services/swagger/pet.ts
@@ -0,0 +1,153 @@
+// @ts-ignore
+/* eslint-disable */
+import { request } from '@umijs/max';
+
+/** Update an existing pet PUT /pet */
+export async function updatePet(body: API.Pet, options?: { [key: string]: any }) {
+ return request('/pet', {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Add a new pet to the store POST /pet */
+export async function addPet(body: API.Pet, options?: { [key: string]: any }) {
+ return request('/pet', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Find pet by ID Returns a single pet GET /pet/${param0} */
+export async function getPetById(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.getPetByIdParams,
+ options?: { [key: string]: any },
+) {
+ const { petId: param0, ...queryParams } = params;
+ return request(`/pet/${param0}`, {
+ method: 'GET',
+ params: { ...queryParams },
+ ...(options || {}),
+ });
+}
+
+/** Updates a pet in the store with form data POST /pet/${param0} */
+export async function updatePetWithForm(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.updatePetWithFormParams,
+ body: { name?: string; status?: string },
+ options?: { [key: string]: any },
+) {
+ const { petId: param0, ...queryParams } = params;
+ const formData = new FormData();
+
+ Object.keys(body).forEach((ele) => {
+ const item = (body as any)[ele];
+
+ if (item !== undefined && item !== null) {
+ formData.append(
+ ele,
+ typeof item === 'object' && !(item instanceof File) ? JSON.stringify(item) : item,
+ );
+ }
+ });
+
+ return request(`/pet/${param0}`, {
+ method: 'POST',
+ params: { ...queryParams },
+ data: formData,
+ ...(options || {}),
+ });
+}
+
+/** Deletes a pet DELETE /pet/${param0} */
+export async function deletePet(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.deletePetParams & {
+ // header
+ api_key?: string;
+ },
+ options?: { [key: string]: any },
+) {
+ const { petId: param0, ...queryParams } = params;
+ return request(`/pet/${param0}`, {
+ method: 'DELETE',
+ headers: {},
+ params: { ...queryParams },
+ ...(options || {}),
+ });
+}
+
+/** uploads an image POST /pet/${param0}/uploadImage */
+export async function uploadFile(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.uploadFileParams,
+ body: { additionalMetadata?: string; file?: string },
+ file?: File,
+ options?: { [key: string]: any },
+) {
+ const { petId: param0, ...queryParams } = params;
+ const formData = new FormData();
+
+ if (file) {
+ formData.append('file', file);
+ }
+
+ Object.keys(body).forEach((ele) => {
+ const item = (body as any)[ele];
+
+ if (item !== undefined && item !== null) {
+ formData.append(
+ ele,
+ typeof item === 'object' && !(item instanceof File) ? JSON.stringify(item) : item,
+ );
+ }
+ });
+
+ return request(`/pet/${param0}/uploadImage`, {
+ method: 'POST',
+ params: { ...queryParams },
+ data: formData,
+ requestType: 'form',
+ ...(options || {}),
+ });
+}
+
+/** Finds Pets by status Multiple status values can be provided with comma separated strings GET /pet/findByStatus */
+export async function findPetsByStatus(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.findPetsByStatusParams,
+ options?: { [key: string]: any },
+) {
+ return request('/pet/findByStatus', {
+ method: 'GET',
+ params: {
+ ...params,
+ },
+ ...(options || {}),
+ });
+}
+
+/** Finds Pets by tags Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. GET /pet/findByTags */
+export async function findPetsByTags(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.findPetsByTagsParams,
+ options?: { [key: string]: any },
+) {
+ return request('/pet/findByTags', {
+ method: 'GET',
+ params: {
+ ...params,
+ },
+ ...(options || {}),
+ });
+}
diff --git a/src/services/swagger/store.ts b/src/services/swagger/store.ts
new file mode 100644
index 0000000..b9c689a
--- /dev/null
+++ b/src/services/swagger/store.ts
@@ -0,0 +1,48 @@
+// @ts-ignore
+/* eslint-disable */
+import { request } from '@umijs/max';
+
+/** Returns pet inventories by status Returns a map of status codes to quantities GET /store/inventory */
+export async function getInventory(options?: { [key: string]: any }) {
+ return request>('/store/inventory', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
+
+/** Place an order for a pet POST /store/order */
+export async function placeOrder(body: API.Order, options?: { [key: string]: any }) {
+ return request('/store/order', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Find purchase order by ID For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions GET /store/order/${param0} */
+export async function getOrderById(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.getOrderByIdParams,
+ options?: { [key: string]: any },
+) {
+ const { orderId: param0, ...queryParams } = params;
+ return request(`/store/order/${param0}`, {
+ method: 'GET',
+ params: { ...queryParams },
+ ...(options || {}),
+ });
+}
+
+/** Delete purchase order by ID For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors DELETE /store/order/${param0} */
+export async function deleteOrder(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.deleteOrderParams,
+ options?: { [key: string]: any },
+) {
+ const { orderId: param0, ...queryParams } = params;
+ return request(`/store/order/${param0}`, {
+ method: 'DELETE',
+ params: { ...queryParams },
+ ...(options || {}),
+ });
+}
diff --git a/src/services/swagger/typings.d.ts b/src/services/swagger/typings.d.ts
new file mode 100644
index 0000000..d06bcfc
--- /dev/null
+++ b/src/services/swagger/typings.d.ts
@@ -0,0 +1,112 @@
+declare namespace API {
+ type ApiResponse = {
+ code?: number;
+ type?: string;
+ message?: string;
+ };
+
+ type Category = {
+ id?: number;
+ name?: string;
+ };
+
+ type deleteOrderParams = {
+ /** ID of the order that needs to be deleted */
+ orderId: number;
+ };
+
+ type deletePetParams = {
+ api_key?: string;
+ /** Pet id to delete */
+ petId: number;
+ };
+
+ type deleteUserParams = {
+ /** The name that needs to be deleted */
+ username: string;
+ };
+
+ type findPetsByStatusParams = {
+ /** Status values that need to be considered for filter */
+ status: ('available' | 'pending' | 'sold')[];
+ };
+
+ type findPetsByTagsParams = {
+ /** Tags to filter by */
+ tags: string[];
+ };
+
+ type getOrderByIdParams = {
+ /** ID of pet that needs to be fetched */
+ orderId: number;
+ };
+
+ type getPetByIdParams = {
+ /** ID of pet to return */
+ petId: number;
+ };
+
+ type getUserByNameParams = {
+ /** The name that needs to be fetched. Use user1 for testing. */
+ username: string;
+ };
+
+ type loginUserParams = {
+ /** The user name for login */
+ username: string;
+ /** The password for login in clear text */
+ password: string;
+ };
+
+ type Order = {
+ id?: number;
+ petId?: number;
+ quantity?: number;
+ shipDate?: string;
+ /** Order Status */
+ status?: 'placed' | 'approved' | 'delivered';
+ complete?: boolean;
+ };
+
+ type Pet = {
+ id?: number;
+ category?: Category;
+ name: string;
+ photoUrls: string[];
+ tags?: Tag[];
+ /** pet status in the store */
+ status?: 'available' | 'pending' | 'sold';
+ };
+
+ type Tag = {
+ id?: number;
+ name?: string;
+ };
+
+ type updatePetWithFormParams = {
+ /** ID of pet that needs to be updated */
+ petId: number;
+ };
+
+ type updateUserParams = {
+ /** name that need to be updated */
+ username: string;
+ };
+
+ type uploadFileParams = {
+ /** ID of pet to update */
+ petId: number;
+ };
+
+ type User = {
+ id?: number;
+ username?: string;
+ firstName?: string;
+ lastName?: string;
+ email?: string;
+ password?: string;
+ phone?: string;
+ /** User Status */
+ userStatus?: number;
+ };
+}
diff --git a/src/services/swagger/user.ts b/src/services/swagger/user.ts
new file mode 100644
index 0000000..4dd6f42
--- /dev/null
+++ b/src/services/swagger/user.ts
@@ -0,0 +1,100 @@
+// @ts-ignore
+/* eslint-disable */
+import { request } from '@umijs/max';
+
+/** Create user This can only be done by the logged in user. POST /user */
+export async function createUser(body: API.User, options?: { [key: string]: any }) {
+ return request('/user', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Get user by user name GET /user/${param0} */
+export async function getUserByName(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.getUserByNameParams,
+ options?: { [key: string]: any },
+) {
+ const { username: param0, ...queryParams } = params;
+ return request(`/user/${param0}`, {
+ method: 'GET',
+ params: { ...queryParams },
+ ...(options || {}),
+ });
+}
+
+/** Updated user This can only be done by the logged in user. PUT /user/${param0} */
+export async function updateUser(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.updateUserParams,
+ body: API.User,
+ options?: { [key: string]: any },
+) {
+ const { username: param0, ...queryParams } = params;
+ return request(`/user/${param0}`, {
+ method: 'PUT',
+ params: { ...queryParams },
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Delete user This can only be done by the logged in user. DELETE /user/${param0} */
+export async function deleteUser(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.deleteUserParams,
+ options?: { [key: string]: any },
+) {
+ const { username: param0, ...queryParams } = params;
+ return request(`/user/${param0}`, {
+ method: 'DELETE',
+ params: { ...queryParams },
+ ...(options || {}),
+ });
+}
+
+/** Creates list of users with given input array POST /user/createWithArray */
+export async function createUsersWithArrayInput(
+ body: API.User[],
+ options?: { [key: string]: any },
+) {
+ return request('/user/createWithArray', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Creates list of users with given input array POST /user/createWithList */
+export async function createUsersWithListInput(body: API.User[], options?: { [key: string]: any }) {
+ return request('/user/createWithList', {
+ method: 'POST',
+ data: body,
+ ...(options || {}),
+ });
+}
+
+/** Logs user into the system GET /user/login */
+export async function loginUser(
+ // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
+ params: API.loginUserParams,
+ options?: { [key: string]: any },
+) {
+ return request('/user/login', {
+ method: 'GET',
+ params: {
+ ...params,
+ },
+ ...(options || {}),
+ });
+}
+
+/** Logs out current logged in user session GET /user/logout */
+export async function logoutUser(options?: { [key: string]: any }) {
+ return request('/user/logout', {
+ method: 'GET',
+ ...(options || {}),
+ });
+}
diff --git a/src/typings.d.ts b/src/typings.d.ts
new file mode 100644
index 0000000..742f70c
--- /dev/null
+++ b/src/typings.d.ts
@@ -0,0 +1,20 @@
+declare module 'slash2';
+declare module '*.css';
+declare module '*.less';
+declare module '*.scss';
+declare module '*.sass';
+declare module '*.svg';
+declare module '*.png';
+declare module '*.jpg';
+declare module '*.jpeg';
+declare module '*.gif';
+declare module '*.bmp';
+declare module '*.tiff';
+declare module 'omit.js';
+declare module 'numeral';
+declare module '@antv/data-set';
+declare module 'mockjs';
+declare module 'react-fittext';
+declare module 'bizcharts-plugin-slider';
+
+declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false;
diff --git a/tests/setupTests.jsx b/tests/setupTests.jsx
new file mode 100644
index 0000000..952561d
--- /dev/null
+++ b/tests/setupTests.jsx
@@ -0,0 +1,64 @@
+const localStorageMock = {
+ getItem: jest.fn(),
+ setItem: jest.fn(),
+ removeItem: jest.fn(),
+ clear: jest.fn(),
+};
+
+global.localStorage = localStorageMock;
+
+Object.defineProperty(URL, 'createObjectURL', {
+ writable: true,
+ value: jest.fn(),
+});
+
+class Worker {
+ constructor(stringUrl) {
+ this.url = stringUrl;
+ this.onmessage = () => {};
+ }
+
+ postMessage(msg) {
+ this.onmessage(msg);
+ }
+}
+window.Worker = Worker;
+
+/* eslint-disable global-require */
+if (typeof window !== 'undefined') {
+ // ref: https://github.com/ant-design/ant-design/issues/18774
+ if (!window.matchMedia) {
+ Object.defineProperty(global.window, 'matchMedia', {
+ writable: true,
+ configurable: true,
+ value: jest.fn(() => ({
+ matches: false,
+ addListener: jest.fn(),
+ removeListener: jest.fn(),
+ })),
+ });
+ }
+ if (!window.matchMedia) {
+ Object.defineProperty(global.window, 'matchMedia', {
+ writable: true,
+ configurable: true,
+ value: jest.fn((query) => ({
+ matches: query.includes('max-width'),
+ addListener: jest.fn(),
+ removeListener: jest.fn(),
+ })),
+ });
+ }
+}
+const errorLog = console.error;
+Object.defineProperty(global.window.console, 'error', {
+ writable: true,
+ configurable: true,
+ value: (...rest) => {
+ const logStr = rest.join('');
+ if (logStr.includes('Warning: An update to %s inside a test was not wrapped in act(...)')) {
+ return;
+ }
+ errorLog(...rest);
+ },
+});
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..85733f6
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "moduleResolution": "node",
+ "importHelpers": true,
+ "jsx": "preserve",
+ "esModuleInterop": true,
+ "sourceMap": true,
+ "baseUrl": "./",
+ "skipLibCheck": true,
+ "experimentalDecorators": true,
+ "strict": true,
+ "resolveJsonModule": true,
+ "allowSyntheticDefaultImports": true,
+ "paths": {
+ "@/*": ["./src/*"],
+ "@@/*": ["./src/.umi/*"],
+ "@@test/*": ["./src/.umi-test/*"]
+ }
+ },
+ "include": ["./**/*.d.ts", "./**/*.ts", "./**/*.tsx"]
+}
diff --git a/types/cache/cache.json b/types/cache/cache.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/types/cache/cache.json
@@ -0,0 +1 @@
+{}
diff --git a/types/cache/login.cache.json b/types/cache/login.cache.json
new file mode 100644
index 0000000..81109b4
--- /dev/null
+++ b/types/cache/login.cache.json
@@ -0,0 +1,386 @@
+{
+ "GET /api/currentUser": {
+ "res": {
+ "data": {
+ "name": "Serati Ma",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
+ "userid": "00000001",
+ "email": "antdesign@alipay.com",
+ "signature": "海纳百川,有容乃大",
+ "title": "交互专家",
+ "group": "蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED",
+ "tags": [
+ {
+ "key": "0",
+ "label": "很有想法的"
+ },
+ {
+ "key": "1",
+ "label": "专注设计"
+ },
+ {
+ "key": "2",
+ "label": "辣~"
+ },
+ {
+ "key": "3",
+ "label": "大长腿"
+ },
+ {
+ "key": "4",
+ "label": "川妹子"
+ },
+ {
+ "key": "5",
+ "label": "海纳百川"
+ }
+ ],
+ "notifyCount": 12,
+ "unreadCount": 11,
+ "country": "China",
+ "geographic": {
+ "province": {
+ "label": "浙江省",
+ "key": "330000"
+ },
+ "city": {
+ "label": "杭州市",
+ "key": "330100"
+ }
+ },
+ "address": "西湖区工专路 77 号",
+ "phone": "0752-268888888"
+ }
+ },
+ "query": {
+ "token ": " 123"
+ },
+ "payload": {},
+ "types": "/** GET /api/currentUser */\nexport type GET_API_CURRENT_USER_QUERY = {\n /** example: 123 */\n token : string\n}\n \n\nexport type GET_API_CURRENT_USER_PAYLOAD = {\n \n}\n \n\nexport type GET_API_CURRENT_USER_RES = {\n /** example: {\"name\": \"Serati Ma\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png\", \"userid\": \"00000001\", \"email\": \"antdesign@alipay.com\", \"signature\": \"海纳百川,有容乃大\", \"title\": \"交互专家\", \"group\": \"蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED\", \"tags\": [{\"key\": \"0\", \"label\": \"很有想法的\"}, {\"key\": \"1\", \"label\": \"专注设计\"}, {\"key\": \"2\", \"label\": \"辣~\"}, {\"key\": \"3\", \"label\": \"大长腿\"}, {\"key\": \"4\", \"label\": \"川妹子\"}, {\"key\": \"5\", \"label\": \"海纳百川\"}], \"notifyCount\": 12, \"unreadCount\": 11, \"country\": \"China\", \"geographic\": {\"province\": {\"label\": \"浙江省\", \"key\": \"330000\"}, \"city\": {\"label\": \"杭州市\", \"key\": \"330100\"}}, \"address\": \"西湖区工专路 77 号\", \"phone\": \"0752-268888888\"} */\n data: {\n name: string,\navatar: string,\nuserid: string,\nemail: string,\nsignature: string,\ntitle: string,\ngroup: string,\ntags: {\n key: string,\nlabel: string\n }[],\nnotifyCount: number,\nunreadCount: number,\ncountry: string,\ngeographic: {\n province: {\n label: string,\nkey: string\n },\ncity: {\n label: string,\nkey: string\n }\n },\naddress: string,\nphone: string\n }\n}\n "
+ },
+ "GET /api/rule": {
+ "res": {
+ "data": [
+ {
+ "key": 99,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 99",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 503,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 81
+ },
+ {
+ "key": 98,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 98",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 164,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 12
+ },
+ {
+ "key": 97,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 97",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 174,
+ "status": "1",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 81
+ },
+ {
+ "key": 96,
+ "disabled": true,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 96",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 914,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 7
+ },
+ {
+ "key": 95,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 95",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 698,
+ "status": "2",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 82
+ },
+ {
+ "key": 94,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 94",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 488,
+ "status": "1",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 14
+ },
+ {
+ "key": 93,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 93",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 580,
+ "status": "2",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 77
+ },
+ {
+ "key": 92,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 92",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 244,
+ "status": "3",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 58
+ },
+ {
+ "key": 91,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 91",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 959,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 66
+ },
+ {
+ "key": 90,
+ "disabled": true,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 90",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 958,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 72
+ },
+ {
+ "key": 89,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 89",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 301,
+ "status": "2",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 2
+ },
+ {
+ "key": 88,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 88",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 277,
+ "status": "1",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 12
+ },
+ {
+ "key": 87,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 87",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 810,
+ "status": "1",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 82
+ },
+ {
+ "key": 86,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 86",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 780,
+ "status": "3",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 22
+ },
+ {
+ "key": 85,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 85",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 705,
+ "status": "3",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 12
+ },
+ {
+ "key": 84,
+ "disabled": true,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 84",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 203,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 79
+ },
+ {
+ "key": 83,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 83",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 491,
+ "status": "2",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 59
+ },
+ {
+ "key": 82,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 82",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 73,
+ "status": "0",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 100
+ },
+ {
+ "key": 81,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png",
+ "name": "TradeCode 81",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 406,
+ "status": "3",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 61
+ },
+ {
+ "key": 80,
+ "disabled": false,
+ "href": "https://ant.design",
+ "avatar": "https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png",
+ "name": "TradeCode 80",
+ "owner": "曲丽丽",
+ "desc": "这是一段描述",
+ "callNo": 112,
+ "status": "2",
+ "updatedAt": "2022-12-06T05:00:57.040Z",
+ "createdAt": "2022-12-06T05:00:57.040Z",
+ "progress": 20
+ }
+ ],
+ "total": 100,
+ "success": true,
+ "pageSize": 20,
+ "current": 1
+ },
+ "query": {
+ "token ": " 123",
+ "current": "1",
+ "pageSize": "20"
+ },
+ "payload": {},
+ "types": "/** GET /api/rule */\nexport type GET_API_RULE_QUERY = {\n /** example: 123 */\n token : string;\n /** example: 1 */\n current: string;\n /** example: 20 */\n pageSize: string\n}\n \n\nexport type GET_API_RULE_PAYLOAD = {\n \n}\n \n\nexport type GET_API_RULE_RES = {\n /** example: [{\"key\": 99, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 99\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 503, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 81}, {\"key\": 98, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 98\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 164, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 12}, {\"key\": 97, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 97\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 174, \"status\": \"1\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 81}, {\"key\": 96, \"disabled\": true, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 96\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 914, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 7}, {\"key\": 95, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 95\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 698, \"status\": \"2\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 82}, {\"key\": 94, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 94\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 488, \"status\": \"1\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 14}, {\"key\": 93, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 93\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 580, \"status\": \"2\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 77}, {\"key\": 92, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 92\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 244, \"status\": \"3\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 58}, {\"key\": 91, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 91\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 959, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 66}, {\"key\": 90, \"disabled\": true, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 90\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 958, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 72}, {\"key\": 89, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 89\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 301, \"status\": \"2\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 2}, {\"key\": 88, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 88\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 277, \"status\": \"1\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 12}, {\"key\": 87, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 87\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 810, \"status\": \"1\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 82}, {\"key\": 86, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 86\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 780, \"status\": \"3\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 22}, {\"key\": 85, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 85\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 705, \"status\": \"3\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 12}, {\"key\": 84, \"disabled\": true, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 84\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 203, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 79}, {\"key\": 83, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 83\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 491, \"status\": \"2\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 59}, {\"key\": 82, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 82\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 73, \"status\": \"0\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 100}, {\"key\": 81, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png\", \"name\": \"TradeCode 81\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 406, \"status\": \"3\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 61}, {\"key\": 80, \"disabled\": false, \"href\": \"https: //ant.design\", \"avatar\": \"https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png\", \"name\": \"TradeCode 80\", \"owner\": \"曲丽丽\", \"desc\": \"这是一段描述\", \"callNo\": 112, \"status\": \"2\", \"updatedAt\": \"2022-12-06T05: 00: 57.040Z\", \"createdAt\": \"2022-12-06T05: 00: 57.040Z\", \"progress\": 20}] */\n data: {\n key: number,\ndisabled: boolean,\nhref: string,\navatar: string,\nname: string,\nowner: string,\ndesc: string,\ncallNo: number,\nstatus: string,\nupdatedAt: string,\ncreatedAt: string,\nprogress: number\n }[];\n /** example: 100 */\n total: number;\n /** example: true */\n success: boolean;\n /** example: 20 */\n pageSize: number;\n /** example: 1 */\n current: number\n}\n "
+ },
+ "POST /api/login/outLogin": {
+ "res": {
+ "data": {},
+ "success": true
+ },
+ "query": {
+ "token ": " 123"
+ },
+ "payload": {},
+ "types": "/** POST /api/login/outLogin */\nexport type POST_API_LOGIN_OUT_LOGIN_QUERY = {\n /** example: 123 */\n token : string\n}\n \n\nexport type POST_API_LOGIN_OUT_LOGIN_PAYLOAD = {\n \n}\n \n\nexport type POST_API_LOGIN_OUT_LOGIN_RES = {\n /** example: {} */\n data: {\n \n };\n /** example: true */\n success: boolean\n}\n "
+ },
+ "POST /api/login/account": {
+ "res": {
+ "status": "ok",
+ "type": "account",
+ "currentAuthority": "admin"
+ },
+ "query": {
+ "token ": " 123"
+ },
+ "payload": {
+ "username": "admin",
+ "password": "ant.design",
+ "autoLogin": true,
+ "type": "account"
+ },
+ "types": "/** POST /api/login/account */\nexport type POST_API_LOGIN_ACCOUNT_QUERY = {\n /** example: 123 */\n token : string\n}\n \n\nexport type POST_API_LOGIN_ACCOUNT_PAYLOAD = {\n /** example: admin */\n username: string;\n /** example: ant.design */\n password: string;\n /** example: true */\n autoLogin: boolean;\n /** example: account */\n type: string\n}\n \n\nexport type POST_API_LOGIN_ACCOUNT_RES = {\n /** example: ok */\n status: string;\n /** example: account */\n type: string;\n /** example: admin */\n currentAuthority: string\n}\n "
+ }
+}
diff --git a/types/cache/mock/login.mock.cache.js b/types/cache/mock/login.mock.cache.js
new file mode 100644
index 0000000..6c59e19
--- /dev/null
+++ b/types/cache/mock/login.mock.cache.js
@@ -0,0 +1,324 @@
+module.exports = {
+ 'GET /api/currentUser': {
+ data: {
+ name: 'Serati Ma',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
+ userid: '00000001',
+ email: 'antdesign@alipay.com',
+ signature: '海纳百川,有容乃大',
+ title: '交互专家',
+ group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED',
+ tags: [
+ { key: '0', label: '很有想法的' },
+ { key: '1', label: '专注设计' },
+ { key: '2', label: '辣~' },
+ { key: '3', label: '大长腿' },
+ { key: '4', label: '川妹子' },
+ { key: '5', label: '海纳百川' },
+ ],
+ notifyCount: 12,
+ unreadCount: 11,
+ country: 'China',
+ geographic: {
+ province: { label: '浙江省', key: '330000' },
+ city: { label: '杭州市', key: '330100' },
+ },
+ address: '西湖区工专路 77 号',
+ phone: '0752-268888888',
+ },
+ },
+ 'GET /api/rule': {
+ data: [
+ {
+ key: 99,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 99',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 503,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 81,
+ },
+ {
+ key: 98,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 98',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 164,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 12,
+ },
+ {
+ key: 97,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 97',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 174,
+ status: '1',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 81,
+ },
+ {
+ key: 96,
+ disabled: true,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 96',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 914,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 7,
+ },
+ {
+ key: 95,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 95',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 698,
+ status: '2',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 82,
+ },
+ {
+ key: 94,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 94',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 488,
+ status: '1',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 14,
+ },
+ {
+ key: 93,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 93',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 580,
+ status: '2',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 77,
+ },
+ {
+ key: 92,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 92',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 244,
+ status: '3',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 58,
+ },
+ {
+ key: 91,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 91',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 959,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 66,
+ },
+ {
+ key: 90,
+ disabled: true,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 90',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 958,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 72,
+ },
+ {
+ key: 89,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 89',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 301,
+ status: '2',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 2,
+ },
+ {
+ key: 88,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 88',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 277,
+ status: '1',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 12,
+ },
+ {
+ key: 87,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 87',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 810,
+ status: '1',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 82,
+ },
+ {
+ key: 86,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 86',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 780,
+ status: '3',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 22,
+ },
+ {
+ key: 85,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 85',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 705,
+ status: '3',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 12,
+ },
+ {
+ key: 84,
+ disabled: true,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 84',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 203,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 79,
+ },
+ {
+ key: 83,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 83',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 491,
+ status: '2',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 59,
+ },
+ {
+ key: 82,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 82',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 73,
+ status: '0',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 100,
+ },
+ {
+ key: 81,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
+ name: 'TradeCode 81',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 406,
+ status: '3',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 61,
+ },
+ {
+ key: 80,
+ disabled: false,
+ href: 'https://ant.design',
+ avatar: 'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
+ name: 'TradeCode 80',
+ owner: '曲丽丽',
+ desc: '这是一段描述',
+ callNo: 112,
+ status: '2',
+ updatedAt: '2022-12-06T05:00:57.040Z',
+ createdAt: '2022-12-06T05:00:57.040Z',
+ progress: 20,
+ },
+ ],
+ total: 100,
+ success: true,
+ pageSize: 20,
+ current: 1,
+ },
+ 'POST /api/login/outLogin': { data: {}, success: true },
+ 'POST /api/login/account': {
+ status: 'ok',
+ type: 'account',
+ currentAuthority: 'admin',
+ },
+};
diff --git a/types/cache/mock/mock.cache.js b/types/cache/mock/mock.cache.js
new file mode 100644
index 0000000..e69de29
diff --git a/types/index.d.ts b/types/index.d.ts
new file mode 100644
index 0000000..2c2805a
--- /dev/null
+++ b/types/index.d.ts
@@ -0,0 +1,120 @@
+export namespace API {
+ /** GET /api/currentUser */
+ export type GET_API_CURRENT_USER_QUERY = {
+ /** example: 123 */
+ token: string;
+ };
+
+ export type GET_API_CURRENT_USER_PAYLOAD = Record;
+
+ export type GET_API_CURRENT_USER_RES = {
+ /** example: {"name": "Serati Ma", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png", "userid": "00000001", "email": "antdesign@alipay.com", "signature": "海纳百川,有容乃大", "title": "交互专家", "group": "蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED", "tags": [{"key": "0", "label": "很有想法的"}, {"key": "1", "label": "专注设计"}, {"key": "2", "label": "辣~"}, {"key": "3", "label": "大长腿"}, {"key": "4", "label": "川妹子"}, {"key": "5", "label": "海纳百川"}], "notifyCount": 12, "unreadCount": 11, "country": "China", "geographic": {"province": {"label": "浙江省", "key": "330000"}, "city": {"label": "杭州市", "key": "330100"}}, "address": "西湖区工专路 77 号", "phone": "0752-268888888"} */
+ data: {
+ name: string;
+ avatar: string;
+ userid: string;
+ email: string;
+ signature: string;
+ title: string;
+ group: string;
+ tags: {
+ key: string;
+ label: string;
+ }[];
+ notifyCount: number;
+ unreadCount: number;
+ country: string;
+ geographic: {
+ province: {
+ label: string;
+ key: string;
+ };
+ city: {
+ label: string;
+ key: string;
+ };
+ };
+ address: string;
+ phone: string;
+ };
+ };
+
+ /** GET /api/rule */
+ export type GET_API_RULE_QUERY = {
+ /** example: 123 */
+ token: string;
+ /** example: 1 */
+ current: string;
+ /** example: 20 */
+ pageSize: string;
+ };
+
+ export type GET_API_RULE_PAYLOAD = Record;
+
+ export type GET_API_RULE_RES = {
+ /** example: [{"key": 99, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 99", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 503, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 81}, {"key": 98, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 98", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 164, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 12}, {"key": 97, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 97", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 174, "status": "1", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 81}, {"key": 96, "disabled": true, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 96", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 914, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 7}, {"key": 95, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 95", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 698, "status": "2", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 82}, {"key": 94, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 94", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 488, "status": "1", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 14}, {"key": 93, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 93", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 580, "status": "2", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 77}, {"key": 92, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 92", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 244, "status": "3", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 58}, {"key": 91, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 91", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 959, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 66}, {"key": 90, "disabled": true, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 90", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 958, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 72}, {"key": 89, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 89", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 301, "status": "2", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 2}, {"key": 88, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 88", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 277, "status": "1", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 12}, {"key": 87, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 87", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 810, "status": "1", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 82}, {"key": 86, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 86", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 780, "status": "3", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 22}, {"key": 85, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 85", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 705, "status": "3", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 12}, {"key": 84, "disabled": true, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 84", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 203, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 79}, {"key": 83, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 83", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 491, "status": "2", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 59}, {"key": 82, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 82", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 73, "status": "0", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 100}, {"key": 81, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png", "name": "TradeCode 81", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 406, "status": "3", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 61}, {"key": 80, "disabled": false, "href": "https: //ant.design", "avatar": "https: //gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png", "name": "TradeCode 80", "owner": "曲丽丽", "desc": "这是一段描述", "callNo": 112, "status": "2", "updatedAt": "2022-12-06T05: 00: 57.040Z", "createdAt": "2022-12-06T05: 00: 57.040Z", "progress": 20}] */
+ data: {
+ key: number;
+ disabled: boolean;
+ href: string;
+ avatar: string;
+ name: string;
+ owner: string;
+ desc: string;
+ callNo: number;
+ status: string;
+ updatedAt: string;
+ createdAt: string;
+ progress: number;
+ }[];
+ /** example: 100 */
+ total: number;
+ /** example: true */
+ success: boolean;
+ /** example: 20 */
+ pageSize: number;
+ /** example: 1 */
+ current: number;
+ };
+
+ /** POST /api/login/outLogin */
+ export type POST_API_LOGIN_OUT_LOGIN_QUERY = {
+ /** example: 123 */
+ token: string;
+ };
+
+ export type POST_API_LOGIN_OUT_LOGIN_PAYLOAD = Record;
+
+ export type POST_API_LOGIN_OUT_LOGIN_RES = {
+ /** example: {} */
+ data: Record;
+ /** example: true */
+ success: boolean;
+ };
+
+ /** POST /api/login/account */
+ export type POST_API_LOGIN_ACCOUNT_QUERY = {
+ /** example: 123 */
+ token: string;
+ };
+
+ export type POST_API_LOGIN_ACCOUNT_PAYLOAD = {
+ /** example: admin */
+ username: string;
+ /** example: ant.design */
+ password: string;
+ /** example: true */
+ autoLogin: boolean;
+ /** example: account */
+ type: string;
+ };
+
+ export type POST_API_LOGIN_ACCOUNT_RES = {
+ /** example: ok */
+ status: string;
+ /** example: account */
+ type: string;
+ /** example: admin */
+ currentAuthority: string;
+ };
+}