diff --git a/StepForm/src/_mock.js b/StepForm/src/_mock.js deleted file mode 100644 index 8e7996deae35737ca576735528af9f6eaa281b98..0000000000000000000000000000000000000000 --- a/StepForm/src/_mock.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - 'POST /api/BLOCK_NAME/forms': (req, res) => { - res.send({ message: 'Ok' }); - }, -}; diff --git a/StepForm/src/_mock.ts b/StepForm/src/_mock.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd0b6f89263bb78148aa9c427abe4330f654082b --- /dev/null +++ b/StepForm/src/_mock.ts @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/forms': (req: any, res: { send: (arg0: { message: string }) => void }) => { + res.send({ message: 'Ok' }); + }, +}; diff --git a/StepForm/src/components/PageHeaderWrapper/index.js b/StepForm/src/components/PageHeaderWrapper/index.js deleted file mode 100644 index 1a40e25dfdc97a4e69407cbf1516e15ad65bd00b..0000000000000000000000000000000000000000 --- a/StepForm/src/components/PageHeaderWrapper/index.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'umi-plugin-react/locale'; -import Link from 'umi/link'; -import { PageHeader } from 'ant-design-pro'; -import styles from './index.less'; - -const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( -
- } - key="pageheader" - {...restProps} - linkElement={Link} - itemRender={item => { - if (item.locale) { - return ; - } - return item.title; - }} - /> - {children ?
{children}
: null} -
-); - -export default PageHeaderWrapper; diff --git a/StepForm/src/components/PageHeaderWrapper/index.less b/StepForm/src/components/PageHeaderWrapper/index.less index 39a449657a98b039c29e6654fd117267cbb5283a..908db575ae9f0a0cd75d04952ba4f37b3002da42 100644 --- a/StepForm/src/components/PageHeaderWrapper/index.less +++ b/StepForm/src/components/PageHeaderWrapper/index.less @@ -1,11 +1,86 @@ @import '~antd/lib/style/themes/default.less'; -.content { +.children-content { margin: 24px 24px 0; } -@media screen and (max-width: @screen-sm) { +.main { + .detail { + display: flex; + } + + .row { + display: flex; + width: 100%; + } + + .title-content { + margin-bottom: 16px; + } + + @media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } + } + + .title, .content { - margin: 24px 0 0; + flex: auto; + } + + .extraContent, + .main { + flex: 0 1 auto; + } + + .main { + width: 100%; + } + + .title { + margin-bottom: 16px; + } + + .logo, + .content, + .extraContent { + margin-bottom: 16px; + } + + .extraContent { + min-width: 242px; + margin-left: 88px; + text-align: right; + } +} + +@media screen and (max-width: @screen-xl) { + .extraContent { + margin-left: 44px; + } +} + +@media screen and (max-width: @screen-lg) { + .extraContent { + margin-left: 20px; + } +} + +@media screen and (max-width: @screen-md) { + .row { + display: block; + } + + .action, + .extraContent { + margin-left: 0; + text-align: left; + } +} + +@media screen and (max-width: @screen-sm) { + .detail { + display: block; } } diff --git a/StepForm/src/components/PageHeaderWrapper/index.tsx b/StepForm/src/components/PageHeaderWrapper/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..fe1a33b8a4fa0759d759c01304484d9eee5e7986 --- /dev/null +++ b/StepForm/src/components/PageHeaderWrapper/index.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { RouteContext } from '@ant-design/pro-layout'; +import { PageHeader, Typography } from 'antd'; +import styles from './index.less'; +import { GridContent } from '@ant-design/pro-layout'; + +interface IPageHeaderWrapperProps { + content?: React.ReactNode; + title: React.ReactNode; + extraContent?: React.ReactNode; +} + +const PageHeaderWrapper: React.SFC = ({ + children, + title, + content, + extraContent, + ...restProps +}) => ( + + {value => ( +
+ + {title} + + } + {...restProps} + {...value} + > +
+
+
+ {content &&
{content}
} + {extraContent &&
{extraContent}
} +
+
+
+
+ {children ? ( + +
{children}
+
+ ) : null} +
+ )} +
+); + +export default PageHeaderWrapper; diff --git a/StepForm/src/components/Result/index.less b/StepForm/src/components/Result/index.less new file mode 100644 index 0000000000000000000000000000000000000000..00c958793c541ca8e5ca4c6cba0aceda83d23dc3 --- /dev/null +++ b/StepForm/src/components/Result/index.less @@ -0,0 +1,58 @@ +@import '~antd/lib/style/themes/default.less'; + +.result { + width: 72%; + margin: 0 auto; + text-align: center; + @media screen and (max-width: @screen-xs) { + width: 100%; + } + + .icon { + margin-bottom: 24px; + font-size: 72px; + line-height: 72px; + + & > .success { + color: @success-color; + } + + & > .error { + color: @error-color; + } + } + + .title { + margin-bottom: 16px; + color: @heading-color; + font-weight: 500; + font-size: 24px; + line-height: 32px; + } + + .description { + margin-bottom: 24px; + color: @text-color-secondary; + font-size: 14px; + line-height: 22px; + } + + .extra { + padding: 24px 40px; + text-align: left; + background: #fafafa; + border-radius: @border-radius-sm; + + @media screen and (max-width: @screen-xs) { + padding: 18px 20px; + } + } + + .actions { + margin-top: 32px; + + button:not(:last-child) { + margin-right: 8px; + } + } +} diff --git a/StepForm/src/components/Result/index.tsx b/StepForm/src/components/Result/index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..63ba3ebc21b6db3f3e254e5686e48d37ea3e4ffc --- /dev/null +++ b/StepForm/src/components/Result/index.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import classNames from 'classnames'; +import { Icon } from 'antd'; +import styles from './index.less'; + +export interface ResultProps { + actions?: React.ReactNode; + className?: string; + description?: React.ReactNode; + extra?: React.ReactNode; + style?: React.CSSProperties; + title?: React.ReactNode; + type: 'success' | 'error'; +} + +const Result: React.SFC = ({ + className, + type, + title, + description, + extra, + actions, + ...restProps +}) => { + const iconMap = { + error: , + success: , + }; + const clsString = classNames(styles.result, className); + return ( +
+
{iconMap[type]}
+
{title}
+ {description &&
{description}
} + {extra &&
{extra}
} + {actions &&
{actions}
} +
+ ); +}; + +export default Result; diff --git a/StepForm/src/components/Step1/index.js b/StepForm/src/components/Step1/index.tsx similarity index 89% rename from StepForm/src/components/Step1/index.js rename to StepForm/src/components/Step1/index.tsx index 8476d220f14ec4e776be4cf60e1de2dd716336cc..fe3acd665bf151691b5df7f6975a9da852d933a3 100644 --- a/StepForm/src/components/Step1/index.js +++ b/StepForm/src/components/Step1/index.tsx @@ -2,6 +2,9 @@ import React, { Fragment } from 'react'; import { connect } from 'dva'; import { Form, Input, Button, Select, Divider } from 'antd'; import styles from './index.less'; +import { FormComponentProps } from 'antd/lib/form'; +import { IStateType } from '../../model'; +import { Dispatch } from 'redux'; const { Option } = Select; @@ -13,18 +16,21 @@ const formItemLayout = { span: 19, }, }; +interface Step1Props extends FormComponentProps { + data?: IStateType['step']; + dispatch?: Dispatch; +} -@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ - data: BLOCK_NAME_CAMEL_CASE.step, -})) -@Form.create() -class Step1 extends React.PureComponent { +class Step1 extends React.PureComponent { render() { const { form, dispatch, data } = this.props; + if (!data) { + return; + } const { getFieldDecorator, validateFields } = form; const onValidateForm = () => { validateFields((err, values) => { - if (!err) { + if (!err && dispatch) { dispatch({ type: 'BLOCK_NAME_CAMEL_CASE/saveStepFormData', payload: values, @@ -114,4 +120,6 @@ class Step1 extends React.PureComponent { } } -export default Step1; +export default connect(({ BLOCK_NAME_CAMEL_CASE }: { BLOCK_NAME_CAMEL_CASE: IStateType }) => ({ + data: BLOCK_NAME_CAMEL_CASE.step, +}))(Form.create()(Step1)); diff --git a/StepForm/src/components/Step2/index.js b/StepForm/src/components/Step2/index.tsx similarity index 67% rename from StepForm/src/components/Step2/index.js rename to StepForm/src/components/Step2/index.tsx index 5c1ca6c4ac757d9ccea0654f86e14aa4e7508740..48ea521076eae4741a2f9ef6497c84071a17ad85 100644 --- a/StepForm/src/components/Step2/index.js +++ b/StepForm/src/components/Step2/index.tsx @@ -1,8 +1,10 @@ import React from 'react'; import { connect } from 'dva'; -import { Form, Input, Button, Alert, Divider } from 'antd'; -import { digitUppercase } from '../../utils/utils'; +import { Form, Input, Button, Alert, Divider, Statistic } from 'antd'; import styles from './index.less'; +import { FormComponentProps } from 'antd/lib/form'; +import { IStateType } from '../../model'; +import { Dispatch } from 'redux'; const formItemLayout = { labelCol: { @@ -12,33 +14,38 @@ const formItemLayout = { span: 19, }, }; +interface Step2Props extends FormComponentProps { + data?: IStateType['step']; + dispatch?: Dispatch; + submitting?: boolean; +} -@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ - submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitStepForm'], - data: BLOCK_NAME_CAMEL_CASE.step, -})) -@Form.create() -class Step2 extends React.PureComponent { +class Step2 extends React.Component { render() { const { form, data, dispatch, submitting } = this.props; + if (!data) { + return; + } const { getFieldDecorator, validateFields } = form; const onPrev = () => { - dispatch({ - type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', - payload: 'info', - }); + dispatch && + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', + payload: 'info', + }); }; - const onValidateForm = e => { + const onValidateForm = (e: React.FormEvent) => { e.preventDefault(); validateFields((err, values) => { if (!err) { - dispatch({ - type: 'BLOCK_NAME_CAMEL_CASE/submitStepForm', - payload: { - ...data, - ...values, - }, - }); + dispatch && + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/submitStepForm', + payload: { + ...data, + ...values, + }, + }); } }); }; @@ -61,7 +68,6 @@ class Step2 extends React.PureComponent { {data.amount} - ({digitUppercase(data.amount)}) @@ -97,5 +103,17 @@ class Step2 extends React.PureComponent { ); } } - -export default Step2; +export default connect( + ({ + BLOCK_NAME_CAMEL_CASE, + loading, + }: { + BLOCK_NAME_CAMEL_CASE: IStateType; + loading: { + effects: { [key: string]: boolean }; + }; + }) => ({ + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitStepForm'], + data: BLOCK_NAME_CAMEL_CASE.step, + }) +)(Form.create()(Step2)); diff --git a/StepForm/src/components/Step3/index.js b/StepForm/src/components/Step3/index.tsx similarity index 73% rename from StepForm/src/components/Step3/index.js rename to StepForm/src/components/Step3/index.tsx index d1570665f7dd6670971d65fd8c490e8f4e54d303..dec1402c4ed653fb4cc1810096b9d0d0725e3330 100644 --- a/StepForm/src/components/Step3/index.js +++ b/StepForm/src/components/Step3/index.tsx @@ -1,20 +1,40 @@ import React, { Fragment } from 'react'; import { connect } from 'dva'; import { Button, Row, Col } from 'antd'; -import { Result } from 'ant-design-pro'; +import Result from '../Result'; import styles from './index.less'; +import { IStateType } from '../../model'; +import { Dispatch } from 'redux'; -@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ - data: BLOCK_NAME_CAMEL_CASE.step, -})) -class Step3 extends React.PureComponent { +interface Step3Props { + data?: IStateType['step']; + dispatch?: Dispatch; +} + +@connect( + ({ + BLOCK_NAME_CAMEL_CASE, + }: { + BLOCK_NAME_CAMEL_CASE: IStateType; + loading: { + effects: { [key: string]: boolean }; + }; + }) => ({ + data: BLOCK_NAME_CAMEL_CASE.step, + }) +) +class Step3 extends React.Component { render() { const { data, dispatch } = this.props; + if (!data) { + return; + } const onFinish = () => { - dispatch({ - type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', - payload: 'info', - }); + dispatch && + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', + payload: 'info', + }); }; const information = (
diff --git a/StepForm/src/index.js b/StepForm/src/index.tsx similarity index 81% rename from StepForm/src/index.js rename to StepForm/src/index.tsx index 7ac32b27f8b354837cf23915b0019fc42eb630c0..f7982f4daef855b987037173535f8ee0c4791eaf 100644 --- a/StepForm/src/index.js +++ b/StepForm/src/index.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent, Fragment } from 'react'; +import React, { Component, Fragment } from 'react'; import { Card, Steps } from 'antd'; import { connect } from 'dva'; import PageHeaderWrapper from './components/PageHeaderWrapper'; @@ -6,13 +6,18 @@ import Step1 from './components/Step1'; import Step2 from './components/Step2'; import Step3 from './components/Step3'; import styles from './style.less'; +import { IStateType } from './model'; const { Step } = Steps; -@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ +interface PAGE_NAME_UPPER_CAMEL_CASEProps { + current: IStateType['current']; +} + +@connect(({ BLOCK_NAME_CAMEL_CASE }: { BLOCK_NAME_CAMEL_CASE: IStateType }) => ({ current: BLOCK_NAME_CAMEL_CASE.current, })) -class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { getCurrentStep() { const { current } = this.props; switch (current) { diff --git a/StepForm/src/model.js b/StepForm/src/model.ts similarity index 54% rename from StepForm/src/model.js rename to StepForm/src/model.ts index 36a6aae2e0e9e288c5db881d9b7a23c37ac258e4..2cf19b0e4bd3e624ef623d2b5d54030710992b0e 100644 --- a/StepForm/src/model.js +++ b/StepForm/src/model.ts @@ -1,6 +1,36 @@ import { fakeSubmitForm } from './service'; +import { Reducer } from 'redux'; +import { EffectsCommandMap } from 'dva'; +import { AnyAction } from 'redux'; -export default { +export interface IStateType { + current?: string; + step?: { + payAccount: string; + receiverAccount: string; + receiverName: string; + amount: string; + }; +} + +export type Effect = ( + action: AnyAction, + effects: EffectsCommandMap & { select: (func: (state: IStateType) => T) => T } +) => void; + +export interface ModelType { + namespace: string; + state: IStateType; + effects: { + submitStepForm: Effect; + }; + reducers: { + saveStepFormData: Reducer; + saveCurrentStep: Reducer; + }; +} + +const Model: ModelType = { namespace: 'BLOCK_NAME_CAMEL_CASE', state: { @@ -39,10 +69,12 @@ export default { return { ...state, step: { - ...state.step, + ...state!.step, ...payload, }, }; }, }, }; + +export default Model; diff --git a/StepForm/src/service.js b/StepForm/src/service.ts similarity index 100% rename from StepForm/src/service.js rename to StepForm/src/service.ts diff --git a/StepForm/src/utils/utils.js b/StepForm/src/utils/utils.js deleted file mode 100644 index 042d3ec77ee08a9f67519fa98743dbf55432e622..0000000000000000000000000000000000000000 --- a/StepForm/src/utils/utils.js +++ /dev/null @@ -1,5 +0,0 @@ -import nzh from 'nzh/cn'; - -export function digitUppercase(n) { - return nzh.toMoney(n); -} diff --git a/package.json b/package.json index 31303af9186fdf1e2eab7db4ef9895b3d8d424d0..ecfb6091df730535f5d2c0b9f2047dde9838138d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "scripts": { - "dev": "cross-env PAGES_PATH='SearchListProjects/src' umi dev", + "dev": "cross-env PAGES_PATH='StepForm/src' umi dev", "lint:style": "stylelint \"src/**/*.less\" --syntax less", "lint": "eslint --ext .js src mock tests && npm run lint:style", "lint:fix": "eslint --fix --ext .js src mock tests && npm run lint:style",