login.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. import React, {Component} from 'react';
  2. import {
  3. View,
  4. Text,
  5. TextInput,
  6. TouchableOpacity,
  7. Image,
  8. SafeAreaView,
  9. DeviceEventEmitter,
  10. ScrollView,
  11. } from 'react-native';
  12. import {WhiteSpace, WingBlank} from '@ant-design/react-native';
  13. import {
  14. IndividualStorageData,
  15. RetrieveData,
  16. StorageData,
  17. } from '../../data/storage';
  18. import {RequestNetwork} from '../../data/encryption';
  19. import Spinner from 'react-native-loading-spinner-overlay';
  20. import public_css from '../../source/css/public_css';
  21. import loading_css from '../../source/css/loading_css';
  22. import login_css from './login_css';
  23. import {CheckPhoneNumber, CheckPassword} from '../../source/inspect/inspect';
  24. import {ToastShow} from '../../components/toast/toast';
  25. import BouncyCheckbox from 'react-native-bouncy-checkbox';
  26. export default class login extends Component {
  27. constructor(props) {
  28. super(props);
  29. this.props.navigation.dangerouslyGetParent().setOptions({
  30. tabBarVisible: false,
  31. });
  32. this.afterEnd = this.afterEnd;
  33. this.state = {
  34. user_name: '',
  35. user_password: '',
  36. user_verification: '',
  37. user_status: 1,
  38. token: '',
  39. timeLeft: 60,
  40. begin: 0,
  41. isDisable: false,
  42. spinner: false,
  43. initRealmMark: false,
  44. initData: 'loading',
  45. userAgreement: false,
  46. };
  47. }
  48. render() {
  49. return (
  50. <SafeAreaView style={public_css.body}>
  51. <View style={public_css.body}>
  52. <View style={login_css.bg}>
  53. <View style={login_css.login_bg_img}>
  54. <Image
  55. source={require('../../source/img/login/login_bg.png')}
  56. style={login_css.bgImg}
  57. resizeMode="cover"
  58. />
  59. </View>
  60. <Spinner
  61. visible={this.state.spinner}
  62. textContent={this.state.initData}
  63. textStyle={loading_css.spinnerTextStyle}
  64. />
  65. <View style={login_css.full_box}>
  66. <ScrollView style={login_css.inner_con}>
  67. <WhiteSpace />
  68. <WingBlank>
  69. <View style={login_css.input_item}>
  70. <Text style={login_css.text_label}>手机号:</Text>
  71. <TextInput
  72. style={login_css.text_input}
  73. ref="mobileInput"
  74. placeholder="请输入您的手机号码"
  75. clearButtonMode="while-editing"
  76. secureTextEntry={false}
  77. keyboardType={'numeric'}
  78. onChangeText={(text) => {
  79. this.setState({
  80. user_name: text,
  81. });
  82. }}
  83. />
  84. </View>
  85. </WingBlank>
  86. <WingBlank>
  87. {this.state.user_status === 1 ? (
  88. <View style={login_css.input_item}>
  89. <Text style={login_css.text_label}>密码:</Text>
  90. <TextInput
  91. style={login_css.text_input}
  92. ref="passwordInput"
  93. placeholder="请输入您的密码"
  94. clearButtonMode="while-editing"
  95. secureTextEntry
  96. value={this.state.user_password}
  97. onChangeText={(text) => {
  98. this.setState({
  99. user_password: text,
  100. });
  101. }}
  102. />
  103. </View>
  104. ) : (
  105. <View style={login_css.input_item}>
  106. <Text style={login_css.text_label}>验证码:</Text>
  107. <TextInput
  108. style={login_css.text_input}
  109. placeholder="请输入您的短信验证码"
  110. clearButtonMode="while-editing"
  111. value={this.state.user_verification}
  112. onChangeText={(text) => {
  113. this.setState({
  114. user_verification: text,
  115. });
  116. }}
  117. />
  118. <TouchableOpacity
  119. style={login_css.vertify}
  120. disabled={this.state.isDisable}
  121. onPress={this.beginCountDown.bind(this)}>
  122. <Text style={login_css.texts}>
  123. {this.state.begin === 0
  124. ? '获取验证码'
  125. : this.state.timeLeft + '秒后重试'}
  126. </Text>
  127. </TouchableOpacity>
  128. </View>
  129. )}
  130. </WingBlank>
  131. <WhiteSpace />
  132. <WingBlank>
  133. <View
  134. style={{
  135. flexDirection: 'row',
  136. justifyContent: 'space-between',
  137. }}>
  138. <Text
  139. onPress={() =>
  140. this.props.navigation.navigate('forget_password')
  141. }
  142. style={{color: '#B6B8C0'}}>
  143. 忘记密码?
  144. </Text>
  145. </View>
  146. </WingBlank>
  147. <TouchableOpacity
  148. style={login_css.button}
  149. onPress={() => this.login()}>
  150. <View style={login_css.buttonView}>
  151. <Text style={login_css.buttonText}>登 录</Text>
  152. </View>
  153. </TouchableOpacity>
  154. <View style={login_css.login_text_view}>
  155. {this.state.user_status === 1 ? (
  156. <Text
  157. onPress={() => this.changeState(2)}
  158. style={{color: '#1263EA'}}>
  159. 短信验证码登录
  160. </Text>
  161. ) : (
  162. <Text
  163. onPress={() => this.changeState(1)}
  164. style={{color: '#1263EA'}}>
  165. 账号登录
  166. </Text>
  167. )}
  168. </View>
  169. <WhiteSpace />
  170. <WhiteSpace />
  171. <View
  172. style={{
  173. flexDirection: 'row',
  174. justifyContent: 'center',
  175. alignItems: 'center',
  176. }}>
  177. <BouncyCheckbox
  178. size={20}
  179. // style={{backgroundColor: 'red'}}
  180. disableText={true}
  181. fillColor="#2A67FE"
  182. unfillColor="#FFFFFF"
  183. // text="我以阅读并同意"
  184. iconStyle={{borderColor: '#A3A3A3'}}
  185. // textStyle={{
  186. // fontFamily: 'JosefinSans-Regular',
  187. // textDecorationLine: 'none',
  188. // }}
  189. onPress={(isChecked: boolean) => {
  190. this.setState({
  191. userAgreement: isChecked,
  192. });
  193. }}
  194. />
  195. <View
  196. style={{
  197. flexDirection: 'row',
  198. justifyContent: 'center',
  199. alignItems: 'center',
  200. marginLeft: 5,
  201. }}>
  202. <Text style={{color: '#A3A3A3', fontSize: 16}}>
  203. 我已阅读并同意
  204. </Text>
  205. <TouchableOpacity onPress={() => {this.props.navigation.navigate('user_agreement')}}>
  206. <Text style={{color: '#2A67FE', fontSize: 16}}>
  207. 《云票在线用户使用协议》
  208. </Text>
  209. </TouchableOpacity>
  210. </View>
  211. </View>
  212. </ScrollView>
  213. </View>
  214. </View>
  215. {/*<View style={{alignItems: 'center', justifyContent: 'center', height: 50}}>*/}
  216. {/* <TouchableOpacity*/}
  217. {/* onPress={() => {*/}
  218. {/* this.loginWeChat();*/}
  219. {/* }}>*/}
  220. {/* <Image source={require('../../source/img/wechat.png')} />*/}
  221. {/* </TouchableOpacity>*/}
  222. {/*</View>*/}
  223. </View>
  224. </SafeAreaView>
  225. );
  226. }
  227. //是否显示Loading层
  228. setLoadingStatus(isLoading) {
  229. this.setState({
  230. spinner: isLoading,
  231. });
  232. }
  233. //更新验证码状态
  234. updateVerificationCodeStatus(timeLeft, callback, begin) {
  235. if (timeLeft > 0) {
  236. this.state.begin = 1;
  237. let that = this;
  238. let interval = setInterval(function () {
  239. if (that.state.timeLeft < 1) {
  240. clearInterval(interval);
  241. callback(that);
  242. that.setState({
  243. isDisable: false,
  244. });
  245. } else {
  246. let totalTime = that.state.timeLeft;
  247. that.setState({
  248. timeLeft: totalTime - 1,
  249. isDisable: true,
  250. });
  251. }
  252. }, 1000);
  253. }
  254. }
  255. //开始验证码计时
  256. beginCountDown = async () => {
  257. let {status, msg} = CheckPhoneNumber(`${this.state.user_name}`);
  258. if (!status) {
  259. ToastShow(1, msg);
  260. return;
  261. }
  262. if (this.state.begin === 1) {
  263. return;
  264. }
  265. let time = this.state.timeLeft;
  266. let afterEnd = this.afterEnd;
  267. let begin = this.state.begin;
  268. this.updateVerificationCodeStatus(time, afterEnd, begin);
  269. await this.sendVerificationCode();
  270. };
  271. //验证码时间
  272. afterEnd(that) {
  273. that.setState({
  274. begin: 0,
  275. timeLeft: 60,
  276. });
  277. }
  278. //修改登录方式状态
  279. changeState = async (status) => {
  280. this.setState({
  281. user_status: status,
  282. user_password: '',
  283. user_verification: '',
  284. });
  285. };
  286. //登录
  287. login = async () => {
  288. if (this.state.user_status === 2) {
  289. if (this.state.user_verification === '') {
  290. ToastShow(1, '验证码不能为空!');
  291. return;
  292. }
  293. let {status, msg} = CheckPhoneNumber(`${this.state.user_name}`);
  294. if (status) {
  295. await this.signIn();
  296. } else {
  297. ToastShow(1, msg);
  298. }
  299. } else {
  300. let {status, msg} = CheckPhoneNumber(`${this.state.user_name}`);
  301. if (status) {
  302. let {status, msg} = CheckPassword(`${this.state.user_password}`);
  303. if (status) {
  304. await this.signIn();
  305. } else {
  306. ToastShow(1, msg);
  307. }
  308. } else {
  309. ToastShow(1, msg);
  310. }
  311. }
  312. };
  313. //提交登录信息
  314. signIn = async () => {
  315. if (!this.state.userAgreement) {
  316. ToastShow(1, '请先勾选同意「云票在线用户使用协议」');
  317. return;
  318. }
  319. this.setLoadingStatus(true);
  320. const url = '/login';
  321. let token = null;
  322. let response = await RequestNetwork(
  323. url,
  324. token,
  325. {
  326. account: this.state.user_name,
  327. password: this.state.user_password,
  328. smsCode: this.state.user_verification,
  329. reqChannel: 3,
  330. loginType: this.state.user_status,
  331. },
  332. false,
  333. 1,
  334. );
  335. if (response) {
  336. if (response.code === 0) {
  337. await StorageData(response);
  338. await this.getCompanyInfo(response.data.account, response.data.token);
  339. await this.getUserInformation();
  340. DeviceEventEmitter.emit('updateCompany', null);
  341. this.props.route.params.refresh(true);
  342. this.props.navigation.goBack();
  343. this.setLoadingStatus(false);
  344. } else {
  345. this.setLoadingStatus(false);
  346. ToastShow(1, response.msg);
  347. }
  348. } else {
  349. this.setLoadingStatus(false);
  350. ToastShow(1, response.msg);
  351. }
  352. };
  353. // 获取默认企业信息
  354. getCompanyInfo = async (account, token) => {
  355. const url = '/auth/comm/user/findDefaultChoose';
  356. let response = await RequestNetwork(
  357. url,
  358. token,
  359. {
  360. mobile: account,
  361. },
  362. false,
  363. 2,
  364. );
  365. if (response) {
  366. if (response.code === 0) {
  367. await IndividualStorageData('company', JSON.stringify(response.data));
  368. }
  369. }
  370. };
  371. //获取短信验证码
  372. sendVerificationCode = async () => {
  373. let {status, msg} = CheckPhoneNumber(`${this.state.user_name}`);
  374. if (status) {
  375. const url = '/sms/getSmscode';
  376. let token = null;
  377. let response = await RequestNetwork(
  378. url,
  379. token,
  380. {
  381. phoneNo: this.state.user_name,
  382. },
  383. false,
  384. 1,
  385. );
  386. if (response) {
  387. ToastShow(1, '验证码发送成功!');
  388. } else {
  389. ToastShow(1, '验证码发送失败!');
  390. }
  391. } else {
  392. ToastShow(1, msg);
  393. }
  394. };
  395. //获取用户信息
  396. getUserInformation = async () => {
  397. let account = await RetrieveData('account');
  398. let token = await RetrieveData('token');
  399. if (token && account) {
  400. const url = '/auth/comm/user/personalInfo/find';
  401. let response = await RequestNetwork(
  402. url,
  403. token,
  404. {
  405. mobile: account,
  406. },
  407. false,
  408. 2,
  409. );
  410. if (response) {
  411. if (response.code === 0) {
  412. let userHeadImg = {
  413. headImage: '',
  414. sex: 'M',
  415. };
  416. if (response.data !== null) {
  417. userHeadImg.headImage = response.data.avatar;
  418. userHeadImg.sex = response.data.sex;
  419. }
  420. await IndividualStorageData(
  421. 'userHeadImg',
  422. JSON.stringify(userHeadImg),
  423. );
  424. }
  425. }
  426. }
  427. };
  428. }