index.jsx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import {
  2. // AlipayCircleOutlined,
  3. LockTwoTone,
  4. MailTwoTone,
  5. MobileTwoTone,
  6. // TaobaoCircleOutlined,
  7. UserOutlined
  8. // WeiboCircleOutlined,
  9. } from '@ant-design/icons'
  10. import { Alert, message, Tabs } from 'antd'
  11. import React, { useState } from 'react'
  12. import ProForm, { ProFormCaptcha, ProFormCheckbox, ProFormText } from '@ant-design/pro-form'
  13. import { connect, useIntl, FormattedMessage } from 'umi'
  14. import { getFakeCaptcha } from '@/services/login'
  15. import styles from './index.less'
  16. const LoginMessage = ({ content }) => (
  17. <Alert
  18. style={{
  19. marginBottom: 24
  20. }}
  21. message={content}
  22. type="error"
  23. showIcon
  24. />
  25. )
  26. const Login = (props) => {
  27. const { userLogin = {}, submitting } = props
  28. const { status, type: loginType } = userLogin
  29. const [ type, setType ] = useState('account')
  30. const intl = useIntl()
  31. const handleSubmit = (values) => {
  32. const { dispatch } = props
  33. dispatch({
  34. type: 'login/login',
  35. payload: { ...values, type }
  36. })
  37. }
  38. return (
  39. <div className={styles.main}>
  40. <ProForm
  41. initialValues={{
  42. autoLogin: true
  43. }}
  44. submitter={{
  45. render: (_, dom) => dom.pop(),
  46. submitButtonProps: {
  47. loading: submitting,
  48. size: 'large',
  49. style: {
  50. width: '100%'
  51. }
  52. }
  53. }}
  54. onFinish={async (values) => {
  55. handleSubmit(values)
  56. }}
  57. >
  58. <Tabs activeKey={type} onChange={setType} className={styles.tabMargin}>
  59. <Tabs.TabPane
  60. key="account"
  61. tab={intl.formatMessage({
  62. id: 'pages.login.accountLogin.tab',
  63. defaultMessage: '账户密码登录'
  64. })}
  65. />
  66. {/* <Tabs.TabPane
  67. key="mobile"
  68. tab={intl.formatMessage({
  69. id: 'pages.login.phoneLogin.tab',
  70. defaultMessage: '手机号登录',
  71. })}
  72. /> */}
  73. </Tabs>
  74. {status === 'error' && loginType === 'account' && !submitting && (
  75. <LoginMessage
  76. content={intl.formatMessage({
  77. id: 'pages.login.accountLogin.errorMessage',
  78. defaultMessage: '账户或密码错误(admin/ant.design)'
  79. })}
  80. />
  81. )}
  82. {type === 'account' && (
  83. <>
  84. <ProFormText
  85. name="userName"
  86. fieldProps={{
  87. size: 'large',
  88. prefix: <UserOutlined className={styles.prefixIcon} />
  89. }}
  90. placeholder={intl.formatMessage({
  91. id: 'pages.login.username.placeholder',
  92. defaultMessage: '用户名: admin or user'
  93. })}
  94. rules={[
  95. {
  96. required: true,
  97. message: (
  98. <FormattedMessage
  99. id="pages.login.username.required"
  100. defaultMessage="请输入用户名!"
  101. />
  102. )
  103. }
  104. ]}
  105. />
  106. <ProFormText.Password
  107. name="password"
  108. fieldProps={{
  109. size: 'large',
  110. prefix: <LockTwoTone className={styles.prefixIcon} />
  111. }}
  112. placeholder={intl.formatMessage({
  113. id: 'pages.login.password.placeholder',
  114. defaultMessage: '密码: ant.design'
  115. })}
  116. rules={[
  117. {
  118. required: true,
  119. message: (
  120. <FormattedMessage
  121. id="pages.login.password.required"
  122. defaultMessage="请输入密码!"
  123. />
  124. )
  125. }
  126. ]}
  127. />
  128. </>
  129. )}
  130. {status === 'error' && loginType === 'mobile' && !submitting && (
  131. <LoginMessage content="验证码错误" />
  132. )}
  133. {type === 'mobile' && (
  134. <>
  135. <ProFormText
  136. fieldProps={{
  137. size: 'large',
  138. prefix: <MobileTwoTone className={styles.prefixIcon} />
  139. }}
  140. name="mobile"
  141. placeholder={intl.formatMessage({
  142. id: 'pages.login.phoneNumber.placeholder',
  143. defaultMessage: '手机号'
  144. })}
  145. rules={[
  146. {
  147. required: true,
  148. message: (
  149. <FormattedMessage
  150. id="pages.login.phoneNumber.required"
  151. defaultMessage="请输入手机号!"
  152. />
  153. )
  154. },
  155. {
  156. pattern: /^1\d{10}$/,
  157. message: (
  158. <FormattedMessage
  159. id="pages.login.phoneNumber.invalid"
  160. defaultMessage="手机号格式错误!"
  161. />
  162. )
  163. }
  164. ]}
  165. />
  166. <ProFormCaptcha
  167. fieldProps={{
  168. size: 'large',
  169. prefix: <MailTwoTone className={styles.prefixIcon} />
  170. }}
  171. captchaProps={{
  172. size: 'large'
  173. }}
  174. placeholder={intl.formatMessage({
  175. id: 'pages.login.captcha.placeholder',
  176. defaultMessage: '请输入验证码'
  177. })}
  178. captchaTextRender={(timing, count) =>
  179. timing
  180. ? `${count} ${intl.formatMessage({
  181. id: 'pages.getCaptchaSecondText',
  182. defaultMessage: '获取验证码'
  183. })}`
  184. : intl.formatMessage({
  185. id: 'pages.login.phoneLogin.getVerificationCode',
  186. defaultMessage: '获取验证码'
  187. })
  188. }
  189. name="captcha"
  190. rules={[
  191. {
  192. required: true,
  193. message: (
  194. <FormattedMessage
  195. id="pages.login.captcha.required"
  196. defaultMessage="请输入验证码!"
  197. />
  198. )
  199. }
  200. ]}
  201. onGetCaptcha={async (mobile) => {
  202. const result = await getFakeCaptcha(mobile)
  203. if (result === false) {
  204. return
  205. }
  206. message.success('获取验证码成功!验证码为:1234')
  207. }}
  208. />
  209. </>
  210. )}
  211. <div
  212. style={{
  213. marginBottom: 24
  214. }}
  215. >
  216. <ProFormCheckbox noStyle name="autoLogin">
  217. <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
  218. </ProFormCheckbox>
  219. <a
  220. style={{
  221. float: 'right'
  222. }}
  223. >
  224. <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
  225. </a>
  226. </div>
  227. </ProForm>
  228. {/* <Space className={styles.other}>
  229. <FormattedMessage id="pages.login.loginWith" defaultMessage="其他登录方式" />
  230. <AlipayCircleOutlined className={styles.icon} />
  231. <TaobaoCircleOutlined className={styles.icon} />
  232. <WeiboCircleOutlined className={styles.icon} />
  233. </Space> */}
  234. </div>
  235. )
  236. }
  237. export default connect(({ login, loading }) => ({
  238. userLogin: login,
  239. submitting: loading.effects['login/login']
  240. }))(Login)