From 97348fea9e49c7d938b6aa824aedc23ba43a7cdb Mon Sep 17 00:00:00 2001 From: zhengw <247276359@qq.com> Date: Tue, 18 Apr 2023 09:57:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=8F=91:=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=B8=8D=E7=94=A8=E7=9A=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.tsx | 6 +- src/components/Footer/index.tsx | 9 +- src/global.less | 4 - src/global.tsx | 9 +- src/pages/Admin.tsx | 45 - src/pages/ChatLogs/ChatLogsType.ts | 1 + src/pages/ChatLogs/index.tsx | 3 +- src/pages/TableList/components/UpdateForm.tsx | 209 ---- src/pages/TableList/index.tsx | 422 ------- .../Login/__snapshots__/login.test.tsx.snap | 1114 ----------------- src/pages/User/Login/index.tsx | 76 +- src/pages/User/Login/login.test.tsx | 96 -- src/pages/Welcome.tsx | 168 --- src/pages/Workbench/index.module.scss | 8 +- 14 files changed, 36 insertions(+), 2134 deletions(-) delete mode 100644 src/pages/Admin.tsx delete mode 100644 src/pages/TableList/components/UpdateForm.tsx delete mode 100644 src/pages/TableList/index.tsx delete mode 100644 src/pages/User/Login/__snapshots__/login.test.tsx.snap delete mode 100644 src/pages/User/Login/login.test.tsx delete mode 100644 src/pages/Welcome.tsx diff --git a/src/app.tsx b/src/app.tsx index c819e03..2ec8b21 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,6 +1,6 @@ import Footer from '@/components/Footer'; import { LinkOutlined } from '@ant-design/icons'; -import type { Settings as LayoutSettings } from '@ant-design/pro-components'; +import { Settings as LayoutSettings } from '@ant-design/pro-components'; import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max'; import { history, Link } from '@umijs/max'; import { App } from 'antd'; @@ -114,7 +114,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) = childrenRender: (children) => { // if (initialState?.loading) return ; return ( - <> +
{children} {/* } @@ -134,7 +134,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) = })); }} /> */} - +
); }, ...initialState?.settings, diff --git a/src/components/Footer/index.tsx b/src/components/Footer/index.tsx index 76a0188..5f2798e 100644 --- a/src/components/Footer/index.tsx +++ b/src/components/Footer/index.tsx @@ -1,20 +1,13 @@ 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: '2021 - 2028 福州晨丰科技有限公司', - }); - return ( { 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 @@ -62,12 +61,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, diff --git a/src/pages/Admin.tsx b/src/pages/Admin.tsx deleted file mode 100644 index 2f93986..0000000 --- a/src/pages/Admin.tsx +++ /dev/null @@ -1,45 +0,0 @@ -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/ChatLogs/ChatLogsType.ts b/src/pages/ChatLogs/ChatLogsType.ts index 14883fd..37002a6 100644 --- a/src/pages/ChatLogs/ChatLogsType.ts +++ b/src/pages/ChatLogs/ChatLogsType.ts @@ -70,6 +70,7 @@ export interface IGroup { export interface IGroupMembers { avatar: string; + staff_avatar?: string; cust_id: string; gender: number; diff --git a/src/pages/ChatLogs/index.tsx b/src/pages/ChatLogs/index.tsx index 421a9ea..6bc2015 100644 --- a/src/pages/ChatLogs/index.tsx +++ b/src/pages/ChatLogs/index.tsx @@ -186,11 +186,12 @@ const ChatLogs: React.FC = () => { }).then((res) => { if (res.err_code == 0) { if (Array.isArray(res.data)) { - setGroupMembersList(res.data); groupMembersObjRef.current = {}; res.data.forEach((item: IGroupMembers) => { + item.avatar = item.staff_avatar || item.avatar; groupMembersObjRef.current[item.user_id] = item; }); + setGroupMembersList(res.data); page(1); } } diff --git a/src/pages/TableList/components/UpdateForm.tsx b/src/pages/TableList/components/UpdateForm.tsx deleted file mode 100644 index 5cd603e..0000000 --- a/src/pages/TableList/components/UpdateForm.tsx +++ /dev/null @@ -1,209 +0,0 @@ -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 deleted file mode 100644 index 6691441..0000000 --- a/src/pages/TableList/index.tsx +++ /dev/null @@ -1,422 +0,0 @@ -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, useModel } 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); - }} - > - - , - - - , - ], - }, - ]; - - const { add, minus, counter } = useModel('demo', (ret) => ({ - add: ret.increment, - minus: ret.decrement, - counter: ret.counter, - })); - - return ( - -
- - - {counter} -
- - 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 deleted file mode 100644 index af647ff..0000000 --- a/src/pages/User/Login/__snapshots__/login.test.tsx.snap +++ /dev/null @@ -1,1114 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Login Page should login success 1`] = ` - -
-
-
-
-
- -
-
-
-
- -
-
-
-
-
- - - - - - - - avatar - - - Serati Ma - - - - - - - -
-
-
-
-
-
-
-
-
-
-
- - Welcome - -
-
-
-
-
-
-
-
-
-
-
- 欢迎使用 Ant Design Pro -
-

- Ant Design Pro 是一个整合了 umi,Ant Design 和 ProComponents 的脚手架方案。致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。 -

-
-
-
-
- 1 -
-
- 了解 umi -
-
-
- umi 是一个可扩展的企业级前端应用框架,umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。 -
- - 了解更多 > - -
-
-
-
- 2 -
-
- 了解 ant design -
-
-
- antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。 -
- - 了解更多 > - -
-
-
-
- 3 -
-
- 了解 Pro Components -
-
-
- ProComponents 是一个基于 Ant Design 做了更高抽象的模板组件,以 一个组件就是一个页面为开发理念,为中后台开发带来更好的体验。 -
- - 了解更多 > - -
-
-
-
-
-
-
-
-
-
-
-
- - - -
-
- -
-
-
-
- -`; - -exports[`Login Page should show login form 1`] = ` - -
-
- - - - - -
-
- - -`; diff --git a/src/pages/User/Login/index.tsx b/src/pages/User/Login/index.tsx index 28d7449..45dd9d4 100644 --- a/src/pages/User/Login/index.tsx +++ b/src/pages/User/Login/index.tsx @@ -1,6 +1,5 @@ import Footer from '@/components/Footer'; import { IAjaxReturn, post } from '@/services/ajax'; -import { getFakeCaptcha } from '@/services/ant-design-pro/login'; import { AlipayCircleOutlined, LockOutlined, @@ -16,8 +15,8 @@ import { ProFormText, } from '@ant-design/pro-components'; import { useEmotionCss } from '@ant-design/use-emotion-css'; -import { FormattedMessage, Helmet, history, SelectLang, useIntl, useModel } from '@umijs/max'; -import { Alert, App, message, Tabs } from 'antd'; +import { FormattedMessage, Helmet, history, SelectLang, useModel } from '@umijs/max'; +import { Alert, App, Tabs } from 'antd'; import { stringify as qsStringify } from 'qs'; import React, { useState } from 'react'; import { flushSync } from 'react-dom'; @@ -101,8 +100,6 @@ const Login: React.FC = () => { }; }); - const intl = useIntl(); - const fetchUserInfo = async () => { const userInfo = await initialState?.fetchUserInfo?.(); if (userInfo) { @@ -148,13 +145,7 @@ const Login: React.FC = () => { return (
- - {intl.formatMessage({ - id: 'menu.login', - defaultMessage: '登录页', - })} - - {Settings.title} - + 登录页 - {Settings.title} {/* */}
{ 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' && ( <> @@ -242,10 +222,7 @@ const Login: React.FC = () => { size: 'large', prefix: , }} - placeholder={intl.formatMessage({ - id: 'pages.login.username.placeholder', - defaultMessage: '用户名: admin or user', - })} + placeholder={'用户名'} rules={[ { required: true, @@ -264,10 +241,7 @@ const Login: React.FC = () => { size: 'large', prefix: , }} - placeholder={intl.formatMessage({ - id: 'pages.login.password.placeholder', - defaultMessage: '请输入密码', - })} + placeholder={'请输入密码'} rules={[ { required: true, @@ -292,10 +266,7 @@ const Login: React.FC = () => { prefix: , }} name="mobile" - placeholder={intl.formatMessage({ - id: 'pages.login.phoneNumber.placeholder', - defaultMessage: '手机号', - })} + placeholder={'手机号'} rules={[ { required: true, @@ -325,21 +296,12 @@ 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={[ @@ -354,13 +316,13 @@ const Login: React.FC = () => { }, ]} onGetCaptcha={async (phone) => { - const result = await getFakeCaptcha({ - phone, - }); - if (!result) { - return; - } - message.success('获取验证码成功!验证码为:1234'); + // const result = await getFakeCaptcha({ + // phone, + // }); + // if (!result) { + // return; + // } + // message.success('获取验证码成功!验证码为:1234'); }} /> diff --git a/src/pages/User/Login/login.test.tsx b/src/pages/User/Login/login.test.tsx deleted file mode 100644 index 18593f8..0000000 --- a/src/pages/User/Login/login.test.tsx +++ /dev/null @@ -1,96 +0,0 @@ -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 deleted file mode 100644 index aced863..0000000 --- a/src/pages/Welcome.tsx +++ /dev/null @@ -1,168 +0,0 @@ -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 ( -
-
-
- {index} -
-
- {title} -
-
-
- {desc} -
- - 了解更多 {'>'} - -
- ); -}; - -const Welcome: React.FC = () => { - const { token } = theme.useToken(); - const { initialState } = useModel('@@initialState'); - - const count = useModel('demo'); - - return ( - - {count.counter} - -
-
- 欢迎使用 Ant Design Pro -
-

- Ant Design Pro 是一个整合了 umi,Ant Design 和 ProComponents - 的脚手架方案。致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。 -

-
- - - -
-
-
-
- ); -}; - -export default Welcome; diff --git a/src/pages/Workbench/index.module.scss b/src/pages/Workbench/index.module.scss index 6a2ec64..9d4ac54 100644 --- a/src/pages/Workbench/index.module.scss +++ b/src/pages/Workbench/index.module.scss @@ -10,8 +10,12 @@ display: inline-flex; flex: 1; margin-bottom: 12px; - border-right: 1px solid #ddd; padding-left: 24px; + border-right: 1px solid #ddd; + + &:last-child { + border-right: none; + } } .dataIconBox { @@ -41,8 +45,8 @@ } .dataCard { + flex: 1; padding: 16px; border: 1px solid #ddd; border-radius: 12px; - flex: 1; }