Commit cdc57db2 authored by 陈帅's avatar 陈帅

UserLogin finish

parent f0d97f9b
version: 2
jobs:
build:
docker:
- image: circleci/node:latest
steps:
- checkout
- run: npm install
- run: npm run lint
- run: npm run build
test:
docker:
- image: circleci/node:latest-browsers
steps:
- checkout
- run: npm install
- run:
command: npm run test:all
no_output_timeout: 30m
workflows:
version: 2
build_and_test:
jobs:
- build
- test
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/accountcenter"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0"
......
......@@ -12,7 +12,7 @@
"dev": "umi dev"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0"
......
......@@ -12,8 +12,7 @@
"dev": "umi dev"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"lodash": "^4.17.10",
"react": "^16.6.3",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedprofile"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"lodash-decorators": "^6.0.0",
......
......@@ -13,7 +13,7 @@
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"antd": "^3.10.9",
"antd": "^3.16.3",
"bizcharts": "^3.5.2",
"bizcharts-plugin-slider": "^2.1.1-beta.1",
"dva": "^2.4.0",
......
......@@ -11,8 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/basicform"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0",
......
......@@ -12,7 +12,7 @@
"dev": "umi dev"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"hash.js": "^1.1.5",
"moment": "^2.22.2",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/basicprofile"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0"
......
......@@ -11,8 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/cardlist"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0"
......
......@@ -12,7 +12,7 @@
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"antd": "^3.10.9",
"antd": "^3.16.3",
"bizcharts": "^3.5.2",
"bizcharts-plugin-slider": "^2.1.1-beta.1",
"dva": "^2.4.0",
......
......@@ -12,8 +12,7 @@
},
"dependencies": {
"react": "^16.6.3",
"antd": "^3.10.9",
"ant-design-pro": "^2.1.1"
"antd": "^3.16.3"
},
"devDependencies": {
"umi": "^2.6.9",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/searchlistapplications"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"hash.js": "^1.1.5",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/searchlistarticles"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"moment": "^2.22.2",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/searchlistprojects"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"classnames": "^2.2.6",
"dva": "^2.4.0",
"moment": "^2.22.2",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/stepform"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"react": "^16.6.3",
"umi-request": "^1.0.0",
......
......@@ -11,7 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/tablelist"
},
"dependencies": {
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"moment": "^2.22.2",
"react": "^16.6.3",
......
......@@ -11,8 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/userlogin"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"moment": "^2.22.2",
"query-string": "^6.0.0",
......
function getFakeCaptcha(req, res) {
function getFakeCaptcha(req: any, res: { json: (arg0: string) => void }) {
return res.json('captcha-xxx');
}
export default {
'POST /api/BLOCK_NAME/account': (req, res) => {
'POST /api/BLOCK_NAME/account': (
req: { body: { password: any; userName: any; type: any } },
res: {
send: (data: any) => void;
}
) => {
const { password, userName, type } = req.body;
if (password === 'ant.design' && userName === 'admin') {
res.send({
......
......@@ -3,7 +3,7 @@ import { Form, Input, Button, Row, Col } from 'antd';
import omit from 'omit.js';
import styles from './index.less';
import ItemMap from './map';
import LoginContext, { ILoginContext } from './loginContext';
import LoginContext, { ILoginContext } from './LoginContext';
import { FormComponentProps } from 'antd/lib/form';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
......@@ -12,7 +12,7 @@ export type WrappedLoginItemProps = Omit<LoginItemProps, 'form' | 'type' | 'upda
export type LoginItemKeyType = keyof typeof ItemMap;
export type LoginItemType = { [K in keyof typeof ItemMap]: React.FC<WrappedLoginItemProps> };
export interface LoginItemProps extends FormComponentProps {
export interface LoginItemProps {
name?: string;
rules?: any[];
style?: React.CSSProperties;
......@@ -23,9 +23,10 @@ export interface LoginItemProps extends FormComponentProps {
countDown?: number;
getCaptchaButtonText?: string;
getCaptchaSecondText?: string;
updateActive: ILoginContext['updateActive'];
type: string;
updateActive?: ILoginContext['updateActive'];
type?: string;
defaultValue?: string;
form?: FormComponentProps['form'];
customProps?: { [key: string]: any };
onChange?: (e: any) => void;
}
......@@ -124,7 +125,6 @@ class WrapFormItem extends Component<LoginItemProps, LoginItemState> {
console.warn('name is required!');
return null;
}
console.log(form);
if (!form) {
return null;
}
......
......@@ -6,7 +6,7 @@ import { ButtonProps } from 'antd/lib/button';
const FormItem = Form.Item;
interface LoginSubmitProps extends ButtonProps {
className: string;
className?: string;
}
const LoginSubmit: React.SFC<LoginSubmitProps> = ({ className, ...rest }) => {
......
......@@ -34,13 +34,15 @@ class LoginTab extends Component<LoginTabProps> {
}
}
const wrapContext = (props: TabPaneProps) => (
const WrapContext: React.SFC<TabPaneProps> & {
typeName: string;
} = props => (
<LoginContext.Consumer>
{value => <LoginTab tabUtil={value.tabUtil} {...props} />}
</LoginContext.Consumer>
);
// 标志位 用来判断是不是自定义组件
wrapContext.typeName = 'LoginTab';
WrapContext.typeName = 'LoginTab';
export default wrapContext;
export default WrapContext;
......@@ -8,12 +8,13 @@ import LoginContext, { ILoginContext } from './LoginContext';
import { FormComponentProps } from 'antd/lib/form';
import LoginSubmit from './LoginSubmit';
export interface LoginProps extends FormComponentProps {
export interface LoginProps {
defaultActiveKey?: string;
onTabChange?: (key: string) => void;
style?: React.CSSProperties;
onSubmit?: (error: any, values: any) => void;
className?: string;
form?: FormComponentProps['form'];
children: React.ReactElement<LoginTab>[];
}
......@@ -96,6 +97,7 @@ class Login extends Component<LoginProps, LoginState> {
const { active = {}, type = '' } = this.state;
const { form, onSubmit } = this.props;
const activeFields = active[type] || [];
form &&
form.validateFields(activeFields, { force: true }, (err, values) => {
onSubmit && onSubmit(err, values);
});
......@@ -119,7 +121,6 @@ class Login extends Component<LoginProps, LoginState> {
}
}
);
console.log(this.getContext());
return (
<LoginContext.Provider value={this.getContext()}>
<div className={classNames(className, styles.login)}>
......@@ -149,4 +150,4 @@ class Login extends Component<LoginProps, LoginState> {
Login[item] = LoginItem[item];
});
export default Form.create()(Login);
export default (Form.create()(Login as any) as unknown) as typeof Login;
......@@ -5,40 +5,78 @@ import Link from 'umi/link';
import { Checkbox, Alert, Icon } from 'antd';
import Login from './components/Login';
import styles from './style.less';
import { Dispatch } from 'redux';
import { IStateType } from './model';
import { FormComponentProps } from 'antd/lib/form';
import { CheckboxChangeEvent } from 'antd/lib/checkbox';
const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login;
@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({
interface BLOCK_NAME_CAMEL_CASEProps {
dispatch: Dispatch;
BLOCK_NAME_CAMEL_CASE: IStateType;
submitting: boolean;
}
interface BLOCK_NAME_CAMEL_CASEState {
type: string;
autoLogin: boolean;
}
export interface FromDataType {
userName: string;
password: string;
mobile: string;
captcha: string;
}
@connect(
({
BLOCK_NAME_CAMEL_CASE,
loading,
}: {
BLOCK_NAME_CAMEL_CASE: IStateType;
loading: {
effects: {
[key: string]: string;
};
};
}) => ({
BLOCK_NAME_CAMEL_CASE,
submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/login'],
}))
class LoginPage extends Component {
state = {
})
)
class BLOCK_NAME_CAMEL_CASE extends Component<
BLOCK_NAME_CAMEL_CASEProps,
BLOCK_NAME_CAMEL_CASEState
> {
state: BLOCK_NAME_CAMEL_CASEState = {
type: 'account',
autoLogin: true,
};
onTabChange = type => {
onTabChange = (type: string) => {
this.setState({ type });
};
loginForm: loginForm;
loginForm: FormComponentProps['form'] | undefined | null;
onGetCaptcha = () =>
new Promise((resolve, reject) => {
this.loginForm.validateFields(['mobile'], {}, (err, values) => {
if (!this.loginForm) {
return;
}
this.loginForm.validateFields(['mobile'], {}, (err: any, values: FromDataType) => {
if (err) {
reject(err);
} else {
const { dispatch } = this.props;
dispatch({
((dispatch({
type: 'BLOCK_NAME_CAMEL_CASE/getCaptcha',
payload: values.mobile,
})
}) as unknown) as Promise<any>)
.then(resolve)
.catch(reject);
}
});
});
handleSubmit = (err, values) => {
handleSubmit = (err: any, values: FromDataType) => {
const { type } = this.state;
if (!err) {
const { dispatch } = this.props;
......@@ -52,13 +90,13 @@ class LoginPage extends Component {
}
};
changeAutoLogin = e => {
changeAutoLogin = (e: CheckboxChangeEvent) => {
this.setState({
autoLogin: e.target.checked,
});
};
renderMessage = content => (
renderMessage = (content: string) => (
<Alert style={{ marginBottom: 24 }} message={content} type="error" showIcon />
);
......@@ -72,7 +110,7 @@ class LoginPage extends Component {
defaultActiveKey={type}
onTabChange={this.onTabChange}
onSubmit={this.handleSubmit}
ref={form => {
ref={(form: any) => {
this.loginForm = form;
}}
>
......@@ -92,7 +130,7 @@ class LoginPage extends Component {
message: formatMessage({ id: 'BLOCK_NAME.userName.required' }),
},
]}
/>{' '}
/>
<Password
name="password"
placeholder={`${formatMessage({ id: 'BLOCK_NAME.login.password' })}: ant.design`}
......@@ -102,7 +140,9 @@ class LoginPage extends Component {
message: formatMessage({ id: 'BLOCK_NAME.password.required' }),
},
]}
onPressEnter={() => this.loginForm.validateFields(this.handleSubmit)}
onPressEnter={() =>
this.loginForm && this.loginForm.validateFields(this.handleSubmit)
}
/>
</Tab>
<Tab key="mobile" tab={formatMessage({ id: 'BLOCK_NAME.login.tab-login-mobile' })}>
......@@ -112,7 +152,7 @@ class LoginPage extends Component {
this.renderMessage(
formatMessage({ id: 'BLOCK_NAME.login.message-invalid-verification-code' })
)}
{/* <Mobile
<Mobile
name="mobile"
placeholder={formatMessage({ id: 'BLOCK_NAME.phone-number.placeholder' })}
rules={[
......@@ -139,7 +179,7 @@ class LoginPage extends Component {
message: formatMessage({ id: 'BLOCK_NAME.verification-code.required' }),
},
]}
/> */}
/>
</Tab>
<div>
<Checkbox checked={autoLogin} onChange={this.changeAutoLogin}>
......@@ -167,4 +207,4 @@ class LoginPage extends Component {
}
}
export default LoginPage;
export default BLOCK_NAME_CAMEL_CASE;
......@@ -2,7 +2,34 @@ import { routerRedux } from 'dva/router';
import { getPageQuery } from './utils/utils';
import { fakeAccountLogin, getFakeCaptcha } from './service';
export default {
import { Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { AnyAction } from 'redux';
export interface IStateType {
status?: 'ok' | 'error';
type?: string;
currentAuthority?: 'user' | 'guest' | 'admin';
}
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: IStateType) => T) => T }
) => void;
export interface ModelType {
namespace: string;
state: IStateType;
effects: {
login: Effect;
getCaptcha: Effect;
};
reducers: {
changeLoginStatus: Reducer<IStateType>;
};
}
const Model: ModelType = {
namespace: 'BLOCK_NAME_CAMEL_CASE',
state: {
......@@ -20,7 +47,7 @@ export default {
if (response.status === 'ok') {
const urlParams = new URL(window.location.href);
const params = getPageQuery();
let { redirect } = params;
let { redirect } = params as { redirect: string };
if (redirect) {
const redirectUrlParams = new URL(redirect);
if (redirectUrlParams.origin === urlParams.origin) {
......@@ -44,7 +71,6 @@ export default {
reducers: {
changeLoginStatus(state, { payload }) {
setAuthority(payload.currentAuthority);
return {
...state,
status: payload.status,
......@@ -53,3 +79,5 @@ export default {
},
},
};
export default Model;
import request from 'umi-request';
import { FromDataType } from './index';
export async function fakeAccountLogin(params) {
export async function fakeAccountLogin(params: FromDataType) {
return request('/api/BLOCK_NAME/account', {
method: 'POST',
data: params,
});
}
export async function getFakeCaptcha(mobile) {
export async function getFakeCaptcha(mobile: string) {
return request(`/api/BLOCK_NAME/captcha?mobile=${mobile}`);
}
......@@ -11,8 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/userregister"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"hash.js": "^1.1.5",
"moment": "^2.22.2",
......
......@@ -12,8 +12,7 @@
},
"dependencies": {
"react": "^16.6.3",
"antd": "^3.10.9",
"ant-design-pro": "^2.1.1"
"antd": "^3.16.3"
},
"devDependencies": {
"umi": "^2.6.9",
......
......@@ -11,8 +11,7 @@
"url": "https://github.com/umijs/umi-blocks/ant-design-pro/workplace"
},
"dependencies": {
"ant-design-pro": "^2.1.1",
"antd": "^3.10.9",
"antd": "^3.16.3",
"dva": "^2.4.0",
"moment": "^2.22.2",
"prop-types": "^15.5.10",
......
......@@ -2,13 +2,32 @@
"private": true,
"scripts": {
"dev": "cross-env PAGES_PATH='UserLogin/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",
"lint-staged": "lint-staged",
"lint-staged:js": "eslint --ext .js",
"lint:fix": "eslint --fix --ext .js src mock tests && npm run lint:style",
"lint:style": "stylelint \"src/**/*.less\" --syntax less",
"prettier": "node ./_scripts/prettier.js"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint-staged"
}
},
"lint-staged": {
"**/*.less": "stylelint --syntax less",
"x/**/*.{js,jsx}": "npm run lint-staged:js",
"x/**/*.{js,ts,tsx,json,jsx,less}": [
"node ./_scripts/lint-prettier.js",
"git add"
]
},
"dependencies": {
"cross-env": "^5.2.0"
},
"peerDependencies": {
"antd": "^3.16.3"
},
"devDependencies": {
"@types/classnames": "^2.2.7",
"babel-eslint": "^10.0.1",
......@@ -32,21 +51,5 @@
"umi-plugin-block-dev": "^2.0.2",
"umi-plugin-react": "^1.3.0-0",
"umi-request": "^1.0.0"
},
"lint-staged": {
"x/**/*.{js,ts,tsx,json,jsx,less}": [
"node ./_scripts/lint-prettier.js",
"git add"
],
"x/**/*.{js,jsx}": "npm run lint-staged:js",
"**/*.less": "stylelint --syntax less"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint-staged"
}
},
"dependencies": {
"cross-env": "^5.2.0"
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment