SetUpPassword.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import React, { useEffect, useState } from 'react'
  2. import useRequest from '@ahooksjs/use-request'
  3. import { useHistory, useLocation } from 'react-router-dom'
  4. import { Col, Row, Divider, Input, Button, Select, Form, message, Modal, TabsProps, Tabs } from 'antd'
  5. import styles from 'styles/NewPage.module.scss'
  6. import { SafetyCertificateOutlined, ExclamationCircleFilled } from '@ant-design/icons'
  7. import { useLogin2p } from '../Login2pContext'
  8. import { ReactComponent as LoginMobile } from 'assets/login_mobile.svg'
  9. import { ReactComponent as LoginPassword } from 'assets/login_passwode.svg'
  10. import { Login2pService } from '../Login2p.service'
  11. interface ISetUpPasswordProps {
  12. visible: boolean
  13. isBindMobile: number
  14. encryptionPhone: string
  15. phoneAreaCode: number
  16. onCancelPassword: () => void
  17. onRefresh?: () => void
  18. }
  19. /**
  20. * 编辑专栏信息
  21. */
  22. const SetUpPassword: React.FC<ISetUpPasswordProps> = props => {
  23. const { Option } = Select
  24. const { visible, isBindMobile, encryptionPhone, phoneAreaCode, onCancelPassword, onRefresh } = props
  25. const [form] = Form.useForm()
  26. const login2p = useLogin2p()
  27. const next = new URLSearchParams(useLocation().search).get('next')
  28. const wechatToken = new URLSearchParams(useLocation().search).get('smtoken')
  29. const [phoneArea, setPhoneArea] = useState<number>(86)
  30. const [isDisabled, setIsDisabled] = useState<boolean>(false)
  31. const [captchaBtnText, setCaptchaBtnText] = useState<string>('获取验证码')
  32. const phoneAreaList = [
  33. { id: 86, optionName: '中国(+86)', regText: /^1\d{10}$/ },
  34. { id: 853, optionName: '中国澳门(+853)', regText: /^6\d{7}$/ },
  35. { id: 852, optionName: '中国香港(+852)', regText: /^[569]\d{3}\-?\d{4}$/ },
  36. { id: 61, optionName: '澳大利亚(+61)', regText: /^4\d{8}$/ },
  37. { id: 65, optionName: '新加坡(+65)', regText: /^[89]\d{7}$/ },
  38. { id: 1, optionName: '美国(+001)', regText: /^[2-9]\d{2}[2-9](?!11)\d{6}$/ },
  39. { id: 81, optionName: '日本(+81)', regText: /^\d{1,4}[ \-]?\d{1,4}[ \-]?\d{4}$/ },
  40. { id: 44, optionName: '英国(+44)', regText: /^\+?[0-9,\-,\s]{5,20}$/ },
  41. { id: 886, optionName: '中国台湾(+886)', regText: /^[0][9]\d{8}$/ }
  42. ]
  43. const { run: getLoginCode, loading: loadingVCode } = useRequest(Login2pService.getVCode, {
  44. manual: true,
  45. formatResult: response => response.data,
  46. onSuccess: result => message.success('验证码请求成功!'),
  47. onError: e => message.error('验证码请求失败~')
  48. })
  49. // 点击了登录
  50. const handleLoginegByCode = (value: any) => {
  51. // 至少 6 位字符,包含字母和数字
  52. const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{6,}$/
  53. if (passwordRegex.test(value.password)) {
  54. login2p.initPassword(
  55. value.phone_number || encryptionPhone,
  56. value.code || phoneAreaCode,
  57. isBindMobile + '',
  58. value.password,
  59. next ? next : '/'
  60. )
  61. } else {
  62. message.error('请设置6位以上数字字母组合')
  63. return
  64. }
  65. }
  66. const checkPhoneNumber = (phoneNumber: string) => {
  67. const findItem = phoneAreaList.find(item => item.id === phoneArea)
  68. return findItem ? findItem.regText.test(phoneNumber) : false
  69. }
  70. // 手机验证码
  71. const getVCodeData = () => {
  72. if (!checkPhoneNumber(form.getFieldValue('phone_number')) && !encryptionPhone) {
  73. message.warning('格式错误,请输入正确的手机号码')
  74. return
  75. }
  76. setIsDisabled(true)
  77. let countdown = 60
  78. const captchaCountdown = setInterval(() => {
  79. setCaptchaBtnText(`${countdown--}s`)
  80. }, 1000)
  81. setTimeout(() => {
  82. setIsDisabled(false)
  83. setCaptchaBtnText('获取验证码')
  84. clearInterval(captchaCountdown)
  85. }, 60000)
  86. getLoginCode(
  87. phoneArea.toString() || phoneAreaCode.toString(),
  88. form.getFieldValue('phone_number') || encryptionPhone
  89. )
  90. }
  91. // 关闭弹框事件
  92. const closeModalHandler = () => {
  93. onCancelPassword()
  94. }
  95. return (
  96. <Modal open={visible} closable={false} destroyOnClose={true} maskClosable={false} footer={null} width={600}>
  97. {isBindMobile === 1 && (
  98. <div className={styles['set-up-password-text']}>
  99. <ExclamationCircleFilled style={{ color: '#E37318', fontSize: 18, marginRight: 8 }} />
  100. 该账号尚未设置登录密码,请先设置登录密码
  101. </div>
  102. )}
  103. <div className={`${styles['login-content-bg-img']} ${styles['login-content-box-set-up']} `}>
  104. <div className="password-dlg-title">设置密码</div>
  105. <div className={styles['login-columncenter-content']}>
  106. <Form form={form} onFinish={handleLoginegByCode}>
  107. {isBindMobile === 1 ? (
  108. <div className={styles['encryption-phone-text']}>
  109. +{phoneAreaCode} &nbsp;
  110. {encryptionPhone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')}
  111. </div>
  112. ) : (
  113. <Form.Item style={{ marginBottom: '5px' }}>
  114. <Form.Item name="phone_number" rules={[{ required: true, message: 'Please input your phone number!' }]}>
  115. <div className={styles['input-content']}>
  116. <Select
  117. defaultValue={phoneArea}
  118. className="select-input"
  119. onChange={value => {
  120. setPhoneArea(value)
  121. }}
  122. >
  123. {phoneAreaList.map(item => (
  124. <Option value={item.id} key={item.id}>
  125. {item.optionName}
  126. </Option>
  127. ))}
  128. </Select>
  129. <Input prefix={<LoginMobile style={{ width: 15, marginRight: 10 }} />} placeholder="请输入手机号" />
  130. </div>
  131. </Form.Item>
  132. </Form.Item>
  133. )}
  134. <Form.Item style={{ marginBottom: '5px' }}>
  135. <Form.Item name={'code'} rules={[{ required: true, message: 'Please input Captcha!' }]}>
  136. <div className={styles['input-content']}>
  137. <Input
  138. prefix={<SafetyCertificateOutlined style={{ color: '#E37318', fontSize: 20, marginRight: 10 }} />}
  139. placeholder="请输入验证码"
  140. />
  141. <Button
  142. onClick={getVCodeData}
  143. style={{ width: 160, marginLeft: '12px' }}
  144. loading={loadingVCode}
  145. disabled={isDisabled}
  146. className="custom-style-bottom"
  147. >
  148. {captchaBtnText}
  149. </Button>
  150. </div>
  151. </Form.Item>
  152. </Form.Item>
  153. <Form.Item style={{ marginBottom: '-19px' }}>
  154. <Form.Item>
  155. <div className={styles['input-content']}>
  156. <Form.Item
  157. name={'password'}
  158. style={{ width: '100%', display: 'inline-block' }}
  159. rules={[{ required: true, message: 'Please input Password!' }]}
  160. >
  161. <Input.Password
  162. style={{ height: 40 }}
  163. prefix={<LoginPassword style={{ width: 20, marginRight: 10 }} />}
  164. placeholder="请设置登录密码(6位以上数字字母组合)"
  165. />
  166. </Form.Item>
  167. </div>
  168. </Form.Item>
  169. </Form.Item>
  170. <Form.Item>
  171. <div className="password-btn-box">
  172. <Button
  173. onClick={closeModalHandler}
  174. htmlType="button"
  175. className="password-btn"
  176. style={{ color: '#faa12f' }}
  177. >
  178. 取消
  179. </Button>
  180. <Button type="primary" htmlType="submit" className="password-btn">
  181. 登录
  182. </Button>
  183. </div>
  184. </Form.Item>
  185. </Form>
  186. </div>
  187. </div>
  188. </Modal>
  189. )
  190. }
  191. export default SetUpPassword