index.js 7.1 KB

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