diff --git a/config/config.ts b/config/config.ts index acf2afd..2dbc934 100644 --- a/config/config.ts +++ b/config/config.ts @@ -4,9 +4,7 @@ import { join } from 'path'; import defaultSettings from './defaultSettings'; import proxy from './proxy'; import routes from './routes'; - const { REACT_APP_ENV = 'dev' } = process.env; - export default defineConfig({ /** * @name 开启 hash 模式 @@ -14,7 +12,6 @@ export default defineConfig({ * @doc https://umijs.org/docs/api/config#hash */ hash: true, - /** * @name 兼容性设置 * @description 设置 ie11 不一定完美兼容,需要检查自己使用的所有依赖 @@ -93,15 +90,7 @@ export default defineConfig({ /** * @name 国际化插件 * @doc https://umijs.org/docs/max/i18n - */ - locale: { - // default zh-CN - default: 'zh-CN', - antd: true, - // default true, when it is true, will use `navigator.language` overwrite default - baseNavigator: true, - }, - /** + */ /** * @name antd 插件 * @description 内置了 babel import 插件 * @doc https://umijs.org/docs/max/antd#antd @@ -125,7 +114,10 @@ export default defineConfig({ */ headScripts: [ // 解决首次加载时白屏的问题 - { src: '/scripts/loading.js', async: true }, + { + src: '/scripts/loading.js', + async: true, + }, ], //================ pro 插件配置 ================= presets: ['umi-presets-pro'], diff --git a/config/routes.ts b/config/routes.ts index 9a68bcb..61c19a6 100644 --- a/config/routes.ts +++ b/config/routes.ts @@ -1,63 +1,21 @@ -/** - * @name umi 的路由配置 - * @description 只支持 path,component,routes,redirect,wrappers,name,icon 的配置 - * @param path path 只支持两种占位符配置,第一种是动态参数 :id 的形式,第二种是 * 通配符,通配符只能出现路由字符串的最后。 - * @param component 配置 location 和 path 匹配后用于渲染的 React 组件路径。可以是绝对路径,也可以是相对路径,如果是相对路径,会从 src/pages 开始找起。 - * @param routes 配置子路由,通常在需要为多个路径增加 layout 组件时使用。 - * @param redirect 配置路由跳转 - * @param wrappers 配置路由组件的包装组件,通过包装组件可以为当前的路由组件组合进更多的功能。 比如,可以用于路由级别的权限校验 - * @param name 配置路由的标题,默认读取国际化文件 menu.ts 中 menu.xxxx 的值,如配置 name 为 login,则读取 menu.ts 中 menu.login 的取值作为标题 - * @param icon 配置路由的图标,取值参考 https://ant.design/components/icon-cn, 注意去除风格后缀和大小写,如想要配置图标为 则取值应为 stepBackward 或 StepBackward,如想要配置图标为 则取值应为 user 或者 User - * @doc https://umijs.org/docs/guides/routes - */ export default [ { path: '/user', layout: false, - routes: [ - { - name: 'login', - path: '/user/login', - component: './User/Login', - }, - ], - }, - { - path: '/welcome', - name: 'welcome', - icon: 'smile', - component: './Welcome', + routes: [{ name: '登录', path: '/user/login', component: './User/Login' }], }, + { path: '/welcome', name: '欢迎', icon: 'smile', component: './Welcome' }, { path: '/admin', - name: 'admin', + name: '管理页', icon: 'crown', access: 'canAdmin', routes: [ - { - path: '/admin', - redirect: '/admin/sub-page', - }, - { - path: '/admin/sub-page', - name: 'sub-page', - component: './Admin', - }, + { path: '/admin', redirect: '/admin/sub-page' }, + { path: '/admin/sub-page', name: '二级管理页', component: './Admin' }, ], }, - { - name: 'list.table-list', - icon: 'table', - path: '/list', - component: './TableList', - }, - { - path: '/', - redirect: '/welcome', - }, - { - path: '*', - layout: false, - component: './404', - }, + { name: '查询表格', icon: 'table', path: '/list', component: './TableList' }, + { path: '/', redirect: '/welcome' }, + { path: '*', layout: false, component: './404' }, ]; diff --git a/package.json b/package.json index 683ab35..8c920d3 100644 --- a/package.json +++ b/package.json @@ -76,8 +76,11 @@ "@umijs/fabric": "^2.14.1", "@umijs/lint": "^4.0.52", "@umijs/max": "^4.0.52", + "add": "^2.0.6", "cross-env": "^7.0.3", "eslint": "^8.34.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-unicorn": "^47.0.0", "express": "^4.18.2", "gh-pages": "^3.2.3", "husky": "^7.0.4", @@ -89,7 +92,8 @@ "swagger-ui-dist": "^4.15.5", "ts-node": "^10.9.1", "typescript": "^4.9.5", - "umi-presets-pro": "^2.0.2" + "umi-presets-pro": "^2.0.2", + "yarn": "^1.22.19" }, "engines": { "node": ">=12.0.0" diff --git a/src/app.tsx b/src/app.tsx index 024f261..d7a91ae 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,15 +1,14 @@ import Footer from '@/components/Footer'; -import { Question, SelectLang } from '@/components/RightContent'; +import { Question } 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 { AvatarDropdown, AvatarName } from './components/RightContent/AvatarDropdown'; 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'; @@ -52,7 +51,7 @@ export async function getInitialState(): Promise<{ // ProLayout 支持的api https://procomponents.ant.design/components/layout export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => { return { - actionsRender: () => [, ], + actionsRender: () => [], avatarProps: { src: initialState?.currentUser?.avatar, title: , diff --git a/src/components/Footer/index.tsx b/src/components/Footer/index.tsx index 03ac146..b5085b7 100644 --- a/src/components/Footer/index.tsx +++ b/src/components/Footer/index.tsx @@ -1,17 +1,10 @@ import { GithubOutlined } from '@ant-design/icons'; import { DefaultFooter } from '@ant-design/pro-components'; -import { useIntl } from '@umijs/max'; +import '@umijs/max'; import React from 'react'; - const Footer: React.FC = () => { - const intl = useIntl(); - const defaultMessage = intl.formatMessage({ - id: 'app.copyright.produced', - defaultMessage: '蚂蚁集团体验技术部出品', - }); - + const defaultMessage = '蚂蚁集团体验技术部出品'; const currentYear = new Date().getFullYear(); - return ( { /> ); }; - export default Footer; diff --git a/src/components/RightContent/index.tsx b/src/components/RightContent/index.tsx index 20a7831..8696cd8 100644 --- a/src/components/RightContent/index.tsx +++ b/src/components/RightContent/index.tsx @@ -1,9 +1,6 @@ import { QuestionCircleOutlined } from '@ant-design/icons'; -import { SelectLang as UmiSelectLang } from '@umijs/max'; -import React from 'react'; - +import '@umijs/max'; export type SiderTheme = 'light' | 'dark'; - export const SelectLang = () => { return ( { /> ); }; - export const Question = () => { return (
{ // remove all caches if (window.caches) { @@ -23,7 +21,7 @@ const clearCache = () => { if (pwa) { // Notify user if offline now window.addEventListener('sw.offline', () => { - message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' })); + message.warning('当前处于离线状态'); }); // Pop up a prompt on the page asking the user if they want to use the latest version @@ -46,9 +44,13 @@ if (pwa) { resolve(msgEvent.data); } }; - worker.postMessage({ type: 'skip-waiting' }, [channel.port2]); + worker.postMessage( + { + type: 'skip-waiting', + }, + [channel.port2], + ); }); - clearCache(); window.location.reload(); return true; @@ -62,12 +64,12 @@ if (pwa) { reloadSW(); }} > - {useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.ok' })} + {'刷新'} ); notification.open({ - message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }), - description: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }), + message: '有新内容', + description: '请点击“刷新”按钮或者手动刷新页面', btn, key, onClose: async () => null, @@ -86,6 +88,5 @@ if (pwa) { serviceWorker.getRegistration().then((sw) => { if (sw) sw.unregister(); }); - clearCache(); } diff --git a/src/pages/Admin.tsx b/src/pages/Admin.tsx index 2f93986..e0a1aae 100644 --- a/src/pages/Admin.tsx +++ b/src/pages/Admin.tsx @@ -1,24 +1,14 @@ import { HeartTwoTone, SmileTwoTone } from '@ant-design/icons'; import { PageContainer } from '@ant-design/pro-components'; -import { useIntl } from '@umijs/max'; +import '@umijs/max'; import { Alert, Card, Typography } from 'antd'; import React from 'react'; - const Admin: React.FC = () => { - const intl = useIntl(); return ( - + { marginBottom: 48, }} /> - + Ant Design Pro You -

+

Want to add more pages? Please refer to{' '} use block @@ -41,5 +41,4 @@ const Admin: React.FC = () => { ); }; - export default Admin; diff --git a/src/pages/TableList/components/UpdateForm.tsx b/src/pages/TableList/components/UpdateForm.tsx index 5cd603e..958d8b9 100644 --- a/src/pages/TableList/components/UpdateForm.tsx +++ b/src/pages/TableList/components/UpdateForm.tsx @@ -6,10 +6,9 @@ import { ProFormTextArea, StepsForm, } from '@ant-design/pro-components'; -import { FormattedMessage, useIntl } from '@umijs/max'; +import '@umijs/max'; import { Modal } from 'antd'; import React from 'react'; - export type FormValueType = { target?: string; template?: string; @@ -17,16 +16,13 @@ export type FormValueType = { 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 ( = (props) => { return ( { @@ -59,50 +54,28 @@ const UpdateForm: React.FC = (props) => { name: props.values.name, desc: props.values.desc, }} - title={intl.formatMessage({ - id: 'pages.searchTable.updateForm.basicConfig', - defaultMessage: '基本信息', - })} + title={'基本信息'} > - ), + message: '请输入规则名称!', }, ]} /> - ), + message: '请输入至少五个字符的规则描述!', min: 5, }, ]} @@ -113,18 +86,12 @@ const UpdateForm: React.FC = (props) => { target: '0', template: '0', }} - title={intl.formatMessage({ - id: 'pages.searchTable.updateForm.ruleProps.title', - defaultMessage: '配置规则属性', - })} + title={'配置规则属性'} > = (props) => { = (props) => { /> = (props) => { type: '1', frequency: 'month', }} - title={intl.formatMessage({ - id: 'pages.searchTable.updateForm.schedulingPeriod.title', - defaultMessage: '设定调度周期', - })} + title={'设定调度周期'} > - ), + message: '请选择开始时间!', }, ]} /> = (props) => { ); }; - export default UpdateForm; diff --git a/src/pages/TableList/index.tsx b/src/pages/TableList/index.tsx index c201007..f6617b7 100644 --- a/src/pages/TableList/index.tsx +++ b/src/pages/TableList/index.tsx @@ -10,7 +10,7 @@ import { ProFormTextArea, ProTable, } from '@ant-design/pro-components'; -import { FormattedMessage, useIntl } from '@umijs/max'; +import '@umijs/max'; import { Button, Drawer, Input, message } from 'antd'; import React, { useRef, useState } from 'react'; import type { FormValueType } from './components/UpdateForm'; @@ -24,7 +24,9 @@ import UpdateForm from './components/UpdateForm'; const handleAdd = async (fields: API.RuleListItem) => { const hide = message.loading('正在添加'); try { - await addRule({ ...fields }); + await addRule({ + ...fields, + }); hide(); message.success('Added successfully'); return true; @@ -50,7 +52,6 @@ const handleUpdate = async (fields: FormValueType) => { key: fields.key, }); hide(); - message.success('Configuration is successful'); return true; } catch (error) { @@ -82,7 +83,6 @@ const handleRemove = async (selectedRows: API.RuleListItem[]) => { return false; } }; - const TableList: React.FC = () => { /** * @en-US Pop-up window of new window @@ -94,9 +94,7 @@ const TableList: React.FC = () => { * @zh-CN 分布更新窗口的弹窗 * */ const [updateModalOpen, handleUpdateModalOpen] = useState(false); - const [showDetail, setShowDetail] = useState(false); - const actionRef = useRef(); const [currentRow, setCurrentRow] = useState(); const [selectedRowsState, setSelectedRows] = useState([]); @@ -105,16 +103,10 @@ const TableList: React.FC = () => { * @en-US International configuration * @zh-CN 国际化配置 * */ - const intl = useIntl(); const columns: ProColumns[] = [ { - title: ( - - ), + title: '规则名称', dataIndex: 'name', tip: 'The rule name is the unique key', render: (dom, entity) => { @@ -131,70 +123,42 @@ const TableList: React.FC = () => { }, }, { - title: , + title: '描述', dataIndex: 'desc', valueType: 'textarea', }, { - title: ( - - ), + title: '服务调用次数', dataIndex: 'callNo', sorter: true, hideInForm: true, - renderText: (val: string) => - `${val}${intl.formatMessage({ - id: 'pages.searchTable.tenThousand', - defaultMessage: ' 万 ', - })}`, + renderText: (val: string) => `${val}${'万'}`, }, { - title: , + title: '状态', dataIndex: 'status', hideInForm: true, valueEnum: { 0: { - text: ( - - ), + text: '关闭', status: 'Default', }, 1: { - text: ( - - ), + text: '运行中', status: 'Processing', }, 2: { - text: ( - - ), + text: '已上线', status: 'Success', }, 3: { - text: ( - - ), + text: '异常', status: 'Error', }, }, }, { - title: ( - - ), + title: '上次调度时间', sorter: true, dataIndex: 'updatedAt', valueType: 'dateTime', @@ -204,21 +168,13 @@ const TableList: React.FC = () => { return false; } if (`${status}` === '3') { - return ( - - ); + return ; } return defaultRender(item); }, }, { - title: , + title: '操作', dataIndex: 'option', valueType: 'option', render: (_, record) => [ @@ -229,25 +185,18 @@ const TableList: React.FC = () => { setCurrentRow(record); }} > - + 配置 , - + 订阅警报 , ], }, ]; - return ( - headerTitle={intl.formatMessage({ - id: 'pages.searchTable.title', - defaultMessage: 'Enquiry form', - })} + headerTitle={'查询表格'} actionRef={actionRef} rowKey="key" search={{ @@ -261,7 +210,7 @@ const TableList: React.FC = () => { handleModalOpen(true); }} > - + 新建 , ]} request={rule} @@ -276,17 +225,17 @@ const TableList: React.FC = () => { - {' '} - {selectedRowsState.length}{' '} - -    + 已选择{' '} + + {selectedRowsState.length} + {' '} + 项    - {' '} - {selectedRowsState.reduce((pre, item) => pre + item.callNo!, 0)}{' '} - + 服务调用次数总计 {selectedRowsState.reduce((pre, item) => pre + item.callNo!, 0)} 万

} @@ -298,24 +247,13 @@ const TableList: React.FC = () => { actionRef.current?.reloadAndRest?.(); }} > - - - + )} { rules={[ { required: true, - message: ( - - ), + message: '规则名称为必填项', }, ]} width="md" @@ -393,5 +326,4 @@ const TableList: React.FC = () => { ); }; - export default TableList; diff --git a/src/pages/User/Login/index.tsx b/src/pages/User/Login/index.tsx index ef48307..bfe1fa8 100644 --- a/src/pages/User/Login/index.tsx +++ b/src/pages/User/Login/index.tsx @@ -16,12 +16,11 @@ import { 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 { Helmet, history, useModel } from '@umijs/max'; import { Alert, message, Tabs } from 'antd'; -import Settings from '../../../../config/defaultSettings'; import React, { useState } from 'react'; import { flushSync } from 'react-dom'; - +import Settings from '../../../../config/defaultSettings'; const ActionIcons = () => { const langClassName = useEmotionCss(({ token }) => { return { @@ -36,7 +35,6 @@ const ActionIcons = () => { }, }; }); - return ( <> @@ -45,7 +43,6 @@ const ActionIcons = () => { ); }; - const Lang = () => { const langClassName = useEmotionCss(({ token }) => { return { @@ -60,14 +57,8 @@ const Lang = () => { }, }; }); - - return ( -
- {SelectLang && } -
- ); + return; }; - const LoginMessage: React.FC<{ content: string; }> = ({ content }) => { @@ -82,12 +73,10 @@ const LoginMessage: React.FC<{ /> ); }; - const Login: React.FC = () => { const [userLoginState, setUserLoginState] = useState({}); const [type, setType] = useState('account'); const { initialState, setInitialState } = useModel('@@initialState'); - const containerClassName = useEmotionCss(() => { return { display: 'flex', @@ -99,9 +88,6 @@ const Login: React.FC = () => { backgroundSize: '100% 100%', }; }); - - const intl = useIntl(); - const fetchUserInfo = async () => { const userInfo = await initialState?.fetchUserInfo?.(); if (userInfo) { @@ -113,16 +99,15 @@ const Login: React.FC = () => { }); } }; - const handleSubmit = async (values: API.LoginParams) => { try { // 登录 - const msg = await login({ ...values, type }); + const msg = await login({ + ...values, + type, + }); if (msg.status === 'ok') { - const defaultLoginSuccessMessage = intl.formatMessage({ - id: 'pages.login.success', - defaultMessage: '登录成功!', - }); + const defaultLoginSuccessMessage = '登录成功!'; message.success(defaultLoginSuccessMessage); await fetchUserInfo(); const urlParams = new URL(window.location.href).searchParams; @@ -133,25 +118,17 @@ const Login: React.FC = () => { // 如果失败去设置用户错误信息 setUserLoginState(msg); } catch (error) { - const defaultLoginFailureMessage = intl.formatMessage({ - id: 'pages.login.failure', - defaultMessage: '登录失败,请重试!', - }); + const defaultLoginFailureMessage = '登录失败,请重试!'; console.log(error); message.error(defaultLoginFailureMessage); } }; const { status, type: loginType } = userLoginState; - return (
- {intl.formatMessage({ - id: 'menu.login', - defaultMessage: '登录页', - })} - - {Settings.title} + {'登录'}- {Settings.title} @@ -168,18 +145,11 @@ const Login: React.FC = () => { }} logo={logo} title="Ant Design" - subTitle={intl.formatMessage({ id: 'pages.layouts.userLayout.title' })} + subTitle={'Ant Design 是西湖区最具影响力的 Web 设计规范'} initialValues={{ autoLogin: true, }} - actions={[ - , - , - ]} + actions={['其他登录方式 :', ]} onFinish={async (values) => { await handleSubmit(values as API.LoginParams); }} @@ -191,28 +161,17 @@ const Login: React.FC = () => { items={[ { key: 'account', - label: intl.formatMessage({ - id: 'pages.login.accountLogin.tab', - defaultMessage: '账户密码登录', - }), + label: '账户密码登录', }, { key: 'mobile', - label: intl.formatMessage({ - id: 'pages.login.phoneLogin.tab', - defaultMessage: '手机号登录', - }), + label: '手机号登录', }, ]} /> {status === 'error' && loginType === 'account' && ( - + )} {type === 'account' && ( <> @@ -222,19 +181,11 @@ const Login: React.FC = () => { size: 'large', prefix: , }} - placeholder={intl.formatMessage({ - id: 'pages.login.username.placeholder', - defaultMessage: '用户名: admin or user', - })} + placeholder={'用户名: admin or user'} rules={[ { required: true, - message: ( - - ), + message: '用户名是必填项!', }, ]} /> @@ -244,19 +195,11 @@ const Login: React.FC = () => { size: 'large', prefix: , }} - placeholder={intl.formatMessage({ - id: 'pages.login.password.placeholder', - defaultMessage: '密码: ant.design', - })} + placeholder={'密码: ant.design'} rules={[ { required: true, - message: ( - - ), + message: '密码是必填项!', }, ]} /> @@ -272,28 +215,15 @@ const Login: React.FC = () => { prefix: , }} name="mobile" - placeholder={intl.formatMessage({ - id: 'pages.login.phoneNumber.placeholder', - defaultMessage: '手机号', - })} + placeholder={'请输入手机号!'} rules={[ { required: true, - message: ( - - ), + message: '手机号是必填项!', }, { pattern: /^1\d{10}$/, - message: ( - - ), + message: '不合法的手机号!', }, ]} /> @@ -305,32 +235,18 @@ const Login: React.FC = () => { captchaProps={{ size: 'large', }} - placeholder={intl.formatMessage({ - id: 'pages.login.captcha.placeholder', - defaultMessage: '请输入验证码', - })} + placeholder={'请输入验证码!'} captchaTextRender={(timing, count) => { if (timing) { - return `${count} ${intl.formatMessage({ - id: 'pages.getCaptchaSecondText', - defaultMessage: '获取验证码', - })}`; + return `${count} ${'秒后重新获取'}`; } - return intl.formatMessage({ - id: 'pages.login.phoneLogin.getVerificationCode', - defaultMessage: '获取验证码', - }); + return '获取验证码'; }} name="captcha" rules={[ { required: true, - message: ( - - ), + message: '验证码是必填项!', }, ]} onGetCaptcha={async (phone) => { @@ -351,14 +267,14 @@ const Login: React.FC = () => { }} > - + 自动登录 - + 忘记密码 ?
@@ -367,5 +283,4 @@ const Login: React.FC = () => { ); }; - export default Login;