index.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import React, { Component } from 'react';
  2. import './index.less';
  3. import { Modal, Icon, Button, Tooltip } from 'antd';
  4. import Assets from '@src/components/Assets';
  5. import { Icon as GIcon } from '../Icon';
  6. import { Button as GButton } from '../Button';
  7. import { User } from '../../stores/user';
  8. const LOGIN_PHONE = 'LOGIN_PHONE';
  9. const REGISTER_PHONE = 'REGISTER_PHONE';
  10. const LOGIN_WX = 'LOGIN_WX';
  11. const BIND_PHONE = 'BIND_PHONE';
  12. const BIND_WX = 'BIND_WX';
  13. const BIND_WX_ERROR = 'BIND_WX_ERROR';
  14. export default class Login extends Component {
  15. constructor(props) {
  16. super(props);
  17. this.state = { type: LOGIN_PHONE };
  18. }
  19. close() {
  20. User.closeLogin();
  21. }
  22. render() {
  23. const { type } = this.state;
  24. const { user } = this.props;
  25. return (
  26. <Modal wrapClassName={`login-modal ${type}`} visible={user.needLogin} footer={null} closable={false} width={470}>
  27. {this.renderBody(type)}
  28. <GIcon name="close" onClick={() => this.close()} />
  29. </Modal>
  30. );
  31. }
  32. renderBody(type) {
  33. switch (type) {
  34. case LOGIN_PHONE:
  35. return this.renderLoginPhone();
  36. case REGISTER_PHONE:
  37. return this.renderRegisterPhone();
  38. case LOGIN_WX:
  39. return this.renderLoginWx();
  40. case BIND_PHONE:
  41. return this.renderBindPhone();
  42. case BIND_WX:
  43. return this.renderBindWx();
  44. case BIND_WX_ERROR:
  45. return this.renderBindWxError();
  46. default:
  47. return this.LOGIN_PHONE();
  48. }
  49. }
  50. renderLoginPhone() {
  51. return (
  52. <div className="body">
  53. <div className="title">手机号登录</div>
  54. <SelectInput placeholder="请输入手机号" />
  55. <VerificationInput placeholder="请输入验证码" />
  56. <Button type="primary" size="large" block>
  57. 登录
  58. </Button>
  59. <Tooltip overlayClassName="gray" placement="left" title="微信扫码登录">
  60. <a className="other">
  61. <Assets name="code" />
  62. </a>
  63. </Tooltip>
  64. </div>
  65. );
  66. }
  67. renderRegisterPhone() {
  68. return (
  69. <div className="body">
  70. <div className="title">手机号登录</div>
  71. <div className="tip">
  72. <Assets name="notice" />
  73. 该手机号尚未注册,将自动为您注册账户
  74. </div>
  75. <SelectInput placeholder="请输入手机号" />
  76. <VerificationInput placeholder="请输入验证码" />
  77. <Input placeholder="请输入邮箱" />
  78. <Button type="primary" size="large" block>
  79. 登录
  80. </Button>
  81. <Tooltip overlayClassName="gray" placement="left" title="微信扫码登录">
  82. <a className="other">
  83. <Assets name="code" />
  84. </a>
  85. </Tooltip>
  86. </div>
  87. );
  88. }
  89. renderLoginWx() {
  90. return (
  91. <div className="body">
  92. <div className="title">微信扫码登录</div>
  93. <div className="qr-code">
  94. <Assets name="qrcode" />
  95. <div className="text">请使用微信扫描二维码登录</div>
  96. </div>
  97. <Tooltip overlayClassName="gray" placement="left" title="手机号登录">
  98. <a className="other">
  99. <Assets name="phone" />
  100. </a>
  101. </Tooltip>
  102. </div>
  103. );
  104. }
  105. renderBindPhone() {
  106. return (
  107. <div className="body">
  108. <div className="title">绑定手机号</div>
  109. <div className="tip">
  110. <Assets name="notice" />
  111. 微信登录成功!为更好的使用服务,请您绑定手机号和邮箱。
  112. </div>
  113. <SelectInput placeholder="请输入手机号" />
  114. <VerificationInput placeholder="请输入验证码" />
  115. <Input placeholder="请输入邮箱" />
  116. <Button type="primary" size="large" block>
  117. 绑定
  118. </Button>
  119. </div>
  120. );
  121. }
  122. renderBindWx() {
  123. return (
  124. <div className="body">
  125. <div className="title">绑定微信号</div>
  126. <div className="tip">
  127. <Assets name="notice" />
  128. 手机号注册成功!为更好的使用服务,建议您绑定微信号。
  129. </div>
  130. <div className="qr-code">
  131. <Assets name="qrcode" />
  132. <div className="text">请使用微信扫描二维码登录</div>
  133. <div className="jump">跳过</div>
  134. </div>
  135. </div>
  136. );
  137. }
  138. renderBindWxError() {
  139. return (
  140. <div className="body">
  141. <div className="title">绑定失败</div>
  142. <div className="text">该微信账户已绑定其他手机号,您可直接使用微信登入。</div>
  143. <div className="btn">
  144. <GButton radius>Ok</GButton>
  145. </div>
  146. </div>
  147. );
  148. }
  149. }
  150. class Input extends Component {
  151. render() {
  152. const { className = '', onChange, placeholder, error, left, right } = this.props;
  153. return (
  154. <div className={`g-input-container ${className}`}>
  155. <div className={`g-input-wrapper ${error ? 'error' : ''}`}>
  156. {left && <div className="g-input-left">{left}</div>}
  157. <input className="g-input" placeholder={placeholder} onChange={data => onChange && onChange(data)} />
  158. {right && <div className="g-input-right">{right}</div>}
  159. </div>
  160. <div hidden={!error} className="g-input-error">
  161. {error}
  162. </div>
  163. </div>
  164. );
  165. }
  166. }
  167. class SelectInput extends Component {
  168. render() {
  169. const { className = '', onChange, placeholder, value, selectValue, onSelect } = this.props;
  170. return (
  171. <Input
  172. className={className}
  173. left={
  174. <span className="g-input-left-select" onClick={() => onSelect && onSelect()}>
  175. {selectValue}
  176. <Icon type="down" />
  177. </span>
  178. }
  179. value={value}
  180. placeholder={placeholder}
  181. onChange={data => onChange && onChange(data)}
  182. />
  183. );
  184. }
  185. }
  186. class VerificationInput extends Component {
  187. constructor(props) {
  188. super(props);
  189. this.timeKey = null;
  190. this.state = { loading: 0 };
  191. }
  192. componentWillUnmount() {
  193. if (this.timeKey) clearTimeout(this.timeKey);
  194. }
  195. onSend() {
  196. const { onSend, time = 60 } = this.props;
  197. if (onSend) {
  198. onSend();
  199. }
  200. this.setTime(time);
  201. }
  202. setTime(time) {
  203. this.setState({ loading: time });
  204. this.timeKey = setTimeout(() => {
  205. this.setTime(time - 1);
  206. }, 1000);
  207. }
  208. render() {
  209. const { loading } = this.state;
  210. const { className = '', onChange, placeholder, value } = this.props;
  211. return (
  212. <Input
  213. className={className}
  214. right={
  215. loading <= 0 ? (
  216. <span className="g-input-right-verification" onClick={() => this.onSend()}>
  217. 获取验证码
  218. </span>
  219. ) : (
  220. <span className="g-input-right-verification-loading">等待{loading}秒</span>
  221. )
  222. }
  223. value={value}
  224. placeholder={placeholder}
  225. onChange={data => onChange && onChange(data)}
  226. />
  227. );
  228. }
  229. }