Commit bf6df595 authored by 邓晓峰's avatar 邓晓峰

feat: 梳理登录模块

parent 620fd83b
Pipeline #32469 skipped with stages
......@@ -87,7 +87,8 @@ module.exports = {
'react/static-property-placement': 0,
'react/destructuring-assignment': 0,
'react/no-array-index-key': 'warn',
'react-hooks/rules-of-hooks': 'error',
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
'react/jsx-closing-tag-location': 0,
'react/forbid-prop-types': 0,
'react/jsx-first-prop-new-line': [2, 'multiline'],
......
/* eslint-disable */
// const proxyURL = process.env.NODE_ENV !== 'production' ? 'http://192.168.10.150:8777' : window.location.origin;
const proxyURL = 'http://192.168.19.105:8082';
const proxyURL = 'https://panda-water.com';
module.exports = {
assetsRoot: process.env.NODE_ENV !== 'production' ? proxyURL : './',
dev: {
......
......@@ -18,6 +18,8 @@ export const LOGIN_WAY = {
Mobile: 'iotPhone',
};
export const WECHART_APPID = 'wx8bfa8b02cb95010b';
export const WX_REDIRECT_URI = 'https://panda-water.com/civbase/user/login';
......@@ -30,4 +32,4 @@ export const REQUEST_POP = 'pop';
export const REQUEST_METHOD_GET = 'get';
export const REQUEST_METHOD_POST = 'post';
export const REQUEST_METHOD_PUT = 'put';
export const REQUEST_METHOD_DELETE = 'delete';
\ No newline at end of file
export const REQUEST_METHOD_DELETE = 'delete';
import { Alert } from 'antd';
import React from 'react';
const LoginMessage = ({ content }) => (
<Alert
style={{
marginBottom: 2,
}}
message={content}
type="error"
showIcon
/>
);
export default LoginMessage;
import { Checkbox } from 'antd';
import React from 'react';
import LoginForm from '../components/Login';
import LoginMessage from './loginMessage';
import { useIntl } from '@/locales/localeExports';
/* eslint-disable */
const { UserName, Password, Submit } = LoginForm;
const useAccount = props => (
<LoginForm onSubmit={props.onSubmit}>
{props.status === 'error' && props.type === 'account' && !props.submitting && (
<LoginMessage
content={useIntl().formatMessage({
id: 'pages.login.accountLogin.errorMessage',
})}
/>
)}
<UserName
name="userName"
placeholder={useIntl().formatMessage({
id: 'pages.login.username.placeholder',
})}
rules={[
{
required: true,
message: useIntl().formatMessage({
id: 'pages.login.username.required',
}),
},
]}
/>
<Password
name="password"
placeholder={useIntl().formatMessage({
id: 'pages.login.password.placeholder',
})}
rules={[
{
required: true,
message: useIntl().formatMessage({
id: 'pages.login.password.required',
}),
},
]}
/>
<div>
<Checkbox
checked={props.autoLogin}
onChange={e => props.setAutoLogin(e.target.checked)}
>
{useIntl().formatMessage({ id: 'pages.login.rememberMe' })}
</Checkbox>
</div>
<Submit loading={props.submitting}>
{useIntl().formatMessage({ id: 'pages.login.submit' })}
</Submit>
</LoginForm>
);
export default useAccount;
import Cookies from 'js-cookie';
import React from 'react';
import { LOGIN_DISPLAY, LOGIN_WAY } from '@/constants';
import Account from './useAccount';
import IOTQRCode from './useIOTQRCode';
import Phone from './usePhone';
import { useIntl } from '@/locales/localeExports';
import styles from '../style.less';
const useIOTComponent = props => {
const handlerType = type => {
props.setType(LOGIN_DISPLAY[type]);
props.updateLoginMode(LOGIN_WAY[type]);
Cookies.set('loginMode', LOGIN_WAY[type], {
expires: 5 * 60 * 1000,
path: '/',
});
};
return (
<div className={styles.wechatQRcode}>
{props.type === LOGIN_DISPLAY.Account ? (
<Account {...props} />
) : props.type === LOGIN_DISPLAY.WeChart ? (
<IOTQRCode {...props} />
) : props.type === LOGIN_DISPLAY.Mobile ? (
<Phone {...props} />
) : (
<Account {...props} />
)}
<div className={styles.loginDisplay}>
<a
onClick={() => handlerType('Account')}
style={{
display: props.type === LOGIN_DISPLAY.Account ? 'none' : 'block',
}}
>
{useIntl().formatMessage({ id: 'pages.login.accountLogin.tab' })}
</a>
<a
onClick={() => handlerType('WeChart')}
style={{
display: props.type === LOGIN_DISPLAY.WeChart ? 'none' : 'block',
}}
>
{useIntl().formatMessage({ id: 'pages.login.weChart.tab' })}
</a>
<a
onClick={() => handlerType('Mobile')}
style={{
display: props.type === LOGIN_DISPLAY.Mobile ? 'none' : 'block',
}}
>
{useIntl().formatMessage({ id: 'pages.login.phoneLogin.tab' })}
</a>
</div>
</div>
);
};
export default useIOTComponent;
import React, { useEffect, useState } from 'react';
import { encode } from 'js-base64';
import Cookies from 'js-cookie';
import WxLogin from '../components/WxLogin';
import { WECHART_APPID, WX_REDIRECT_URI } from '../../../../constants';
const useIOTQRCode = () => {
const [rstate, setRstate] = useState(() =>
encode(
`panda_${Math.round(Math.random() * 10000 + Date.now()).toString(16)}`,
),
);
useEffect(() => {
Cookies.set('redirect_state', rstate, {
expires: 5 * 60 * 1000,
path: '/',
});
}, []);
const props = Object.assign(
{},
{
self_redirect: false,
scope: 'snsapi_login',
appid: WECHART_APPID,
state: rstate,
redirect_uri: WX_REDIRECT_URI,
href: 'https://panda-water.cn/web4/styles/PandaIOTQrcodeStyle.css',
},
);
return <WxLogin {...props} />;
};
export default useIOTQRCode;
import { Form } from 'antd';
import React from 'react';
import LoginForm from '../components/Login';
import LoginMessage from './loginMessage';
const { Mobile, Captcha, Submit } = LoginForm;
const usePhone = props => {
const [form] = Form.useForm();
return (
<LoginForm form={form} onSubmit={props.onSubmit}>
{props.status === 'error' &&
props.type === 'account' &&
!props.submitting && <LoginMessage content="手机号码未注册" />}
<Mobile name="mobile" placeholder="请输入手机号码" />
<Captcha
name="captcha"
placeholder="请输入短信验证码"
countDown={60}
getCaptchaButtonText=""
getCaptchaSecondText="秒"
autoComplete="off"
rules={[
{
required: true,
message: '请输入短信验证码!',
},
]}
/>
<Submit loading={props.submitting} style={{ marginTop: '0px' }}>
登录
</Submit>
</LoginForm>
);
};
export default usePhone;
import React from 'react';
import classNames from 'classnames';
import { Popover } from 'antd';
import QRCode from 'qrcode.react';
import styles from '../style.less';
const useRenderQcode = props => {
if (!props.qrcode) {
return null;
}
const qrcodes = props.qrcode.split('|');
const qcodeComponent = url => (
<img
src={url}
className="QuickMark-cont"
style={{ width: '150px', height: '150px' }}
alt=""
/>
);
const element = [];
qrcodes.forEach((item, index) => {
const firstValue = item.split('=');
switch (firstValue[0]) {
case '小程序':
element.push(
<div
className={classNames(
styles['quickMark-single'],
styles['mini-single'],
)}
key={firstValue[0]}
>
<Popover
placement="top"
content={qcodeComponent(
'https://panda-water.cn/web4/assets/images/小程序二维码.jpg',
)}
>
<div className={styles['icon-Container']}>
<span className={styles.Wechat} />
<span className="iconText WechatText">Wechat</span>
</div>
</Popover>
</div>,
);
break;
case '智联小程序':
element.push(
<div
className={classNames(styles['quickMark-single'], 'miniIOT-single')}
key={firstValue[0]}
>
<Popover
placement="top"
content={qcodeComponent(
'https://panda-water.cn/web4/assets/images/智联小程序二维码.jpg',
)}
>
<div className={styles['icon-Container']}>
<span className={styles.Wechat} />
<span
className={classNames(styles.iconText, styles.WechatText)}
>
熊猫智联
</span>
</div>
</Popover>
</div>,
);
break;
case 'Android':
if (firstValue[1] && firstValue[1].replace(/ /g, '').length > 0) {
element.push(
<div
className={classNames(
styles['quickMark-single'],
'Android-single',
)}
key={firstValue[0]}
>
<Popover
placement="top"
content={
<QRCode
value={firstValue[1].replace(
/{ip}/gi,
props.ip || window.location.host,
)}
/>
}
>
<div className={styles['icon-Container']}>
<span className={styles.Android} />
<span
className={classNames(styles.iconText, styles.AndroidText)}
>
Android
</span>
</div>
</Popover>
</div>,
);
}
break;
case 'iPhone':
if (firstValue[1] && firstValue[1].replace(/ /g, '').length > 0) {
element.push(
<div
className={classNames(
styles['quickMark-single'],
'iphone-single',
)}
key={firstValue[0]}
>
<Popover
placement="top"
content={
<QRCode
value={firstValue[1].replace(
/{ip}/gi,
props.ip || window.location.host,
)}
/>
}
>
<div className={styles['icon-Container']}>
<span className={styles.Wechat} />
<span
className={classNames(styles.iconText, styles.iphoneText)}
>
iPhone
</span>
</div>
</Popover>
</div>,
);
}
break;
default:
if (item && item.replace(/ /g, '').length > 0) {
const indexIndex = element.findIndex(
// eslint-disable-next-line no-shadow
item => item.props.className.indexOf('Android-single') > -1,
);
element.splice(indexIndex, 1);
element.push(
<div
className={classNames(
styles['quickMark-single'],
'Android-single',
)}
key={index}
>
<Popover
placement="top"
content={
<QRCode
value={item.replace(
/{ip}/gi,
props.ip || window.location.host,
)}
/>
}
>
<div className={styles['icon-Container']}>
<span className={styles.Android} />
<span
className={classNames(styles.iconText, styles.AndroidText)}
>
Android
</span>
</div>
</Popover>
</div>,
);
}
break;
}
});
return element;
};
export default useRenderQcode;
This diff is collapsed.
......@@ -31,17 +31,17 @@ import {
LOGIN_WAY,
} from '@/constants';
import { actionCreators } from '@/containers/App/store';
// import { appService } from '../../../../api';
import {
FormattedMessage,
useIntl,
} from '@/locales/localeExports';
import defaultSetting from '../../../../../config/defaultSetting';
// import i18n from '../../../../utils/share';
import LoginForm from '../components/Login';
import WxLogin from '../components/WxLogin';
import LoginAction from '../login';
import LoginMessage from '../js/loginMessage';
import useRenderQcode from '../js/useRenderQcode';
import styles from '../style.less';
const {
......@@ -52,193 +52,6 @@ const {
Submit,
} = LoginForm;
const LoginMessage = ({ content }) => (
<Alert
style={{
marginBottom: 2,
}}
message={content}
type="error"
showIcon
/>
);
const useRenderQcode = props => {
if (!props.qrcode) {
return null;
}
const qrcodes = props.qrcode.split('|');
const qcodeComponent = url => (
<img
src={url}
className="QuickMark-cont"
style={{ width: '150px', height: '150px' }}
alt=""
/>
);
const element = [];
qrcodes.forEach((item, index) => {
const firstValue = item.split('=');
switch (firstValue[0]) {
case '小程序':
element.push(
<div
className={classNames(
styles['quickMark-single'],
styles['mini-single'],
)}
key={firstValue[0]}
>
<Popover
placement="top"
content={qcodeComponent(
'https://panda-water.cn/web4/assets/images/小程序二维码.jpg',
)}
>
<div className={styles['icon-Container']}>
<span className={styles.Wechat} />
<span className="iconText WechatText">Wechat</span>
</div>
</Popover>
</div>,
);
break;
case '智联小程序':
element.push(
<div
className={classNames(styles['quickMark-single'], 'miniIOT-single')}
key={firstValue[0]}
>
<Popover
placement="top"
content={qcodeComponent(
'https://panda-water.cn/web4/assets/images/智联小程序二维码.jpg',
)}
>
<div className={styles['icon-Container']}>
<span className={styles.Wechat} />
<span
className={classNames(styles.iconText, styles.WechatText)}
>
熊猫智联
</span>
</div>
</Popover>
</div>,
);
break;
case 'Android':
if (firstValue[1] && firstValue[1].replace(/ /g, '').length > 0) {
element.push(
<div
className={classNames(
styles['quickMark-single'],
'Android-single',
)}
key={firstValue[0]}
>
<Popover
placement="top"
content={
<QRCode
value={firstValue[1].replace(
/{ip}/gi,
props.ip || window.location.host,
)}
/>
}
>
<div className={styles['icon-Container']}>
<span className={styles.Android} />
<span
className={classNames(styles.iconText, styles.AndroidText)}
>
Android
</span>
</div>
</Popover>
</div>,
);
}
break;
case 'iPhone':
if (firstValue[1] && firstValue[1].replace(/ /g, '').length > 0) {
element.push(
<div
className={classNames(
styles['quickMark-single'],
'iphone-single',
)}
key={firstValue[0]}
>
<Popover
placement="top"
content={
<QRCode
value={firstValue[1].replace(
/{ip}/gi,
props.ip || window.location.host,
)}
/>
}
>
<div className={styles['icon-Container']}>
<span className={styles.Wechat} />
<span
className={classNames(styles.iconText, styles.iphoneText)}
>
iPhone
</span>
</div>
</Popover>
</div>,
);
}
break;
default:
if (item && item.replace(/ /g, '').length > 0) {
const indexIndex = element.findIndex(
// eslint-disable-next-line no-shadow
item => item.props.className.indexOf('Android-single') > -1,
);
element.splice(indexIndex, 1);
element.push(
<div
className={classNames(
styles['quickMark-single'],
'Android-single',
)}
key={index}
>
<Popover
placement="top"
content={
<QRCode
value={item.replace(
/{ip}/gi,
props.ip || window.location.host,
)}
/>
}
>
<div className={styles['icon-Container']}>
<span className={styles.Android} />
<span
className={classNames(styles.iconText, styles.AndroidText)}
>
Android
</span>
</div>
</Popover>
</div>,
);
}
break;
}
});
return element;
};
/* eslint-disable */
const Account = props => (
<LoginForm onSubmit={props.onSubmit}>
......
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