226 lines
7.1 KiB
JavaScript
226 lines
7.1 KiB
JavaScript
import { View, Text, TextInput } from "react-native";
|
||
import React, { useState, useContext, useEffect } from "react";
|
||
import { useTailwind } from "tailwind-rn";
|
||
import { Button, CheckBox } from "@rneui/themed";
|
||
import { useNavigation } from "@react-navigation/native";
|
||
import Toast from "react-native-toast-message";
|
||
import { AuthContext } from "../../../App";
|
||
import { cryptoPassword, generateSignature } from "../../../utils/crypto";
|
||
import { JSEncrypt } from "jsencrypt";
|
||
import MyDivider from "../../../components/MyDivider";
|
||
import baseRequest from "../../../utils/baseRequest";
|
||
import { get, save } from "../../../utils/storeInfo";
|
||
|
||
export default function PasswordLogin() {
|
||
const { signIn, checked, setChecked } = useContext(AuthContext);
|
||
const navigation = useNavigation();
|
||
const tailwind = useTailwind();
|
||
//获取环境变量
|
||
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
|
||
//设置checkbox
|
||
const toggleCheckbox = () => setChecked(!checked);
|
||
//保存区号、手机号、验证码
|
||
const [regionCode, setRegionCode] = useState("86");
|
||
const [mobilePhone, setMobilePhone] = useState("");
|
||
const [password, setPassword] = useState("");
|
||
|
||
//获取之前缓存的用户的手机号
|
||
useEffect(() => {
|
||
async function getMobilePhone() {
|
||
const mobile_phone = await get("mobile_phone");
|
||
const region_code = await get("region_code");
|
||
if (mobile_phone && region_code) {
|
||
setMobilePhone(mobile_phone);
|
||
setRegionCode(region_code);
|
||
}
|
||
}
|
||
getMobilePhone();
|
||
}, []);
|
||
|
||
//点击登录
|
||
const handleSubmit = async () => {
|
||
//验证数据格式
|
||
if (!checked) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "请先阅读并同意《用户协议》和《隐私政策》后登录",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (!mobilePhone.match(/^1[3456789]\d{9}$/)) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "手机号码格式错误",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (password.length < 8) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "密码不得小于8位",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
if (password.length > 15) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: "密码不得大于15位",
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
//对手机号进行RSA加密
|
||
const encrypt = new JSEncrypt();
|
||
encrypt.setPublicKey(process.env.EXPO_PUBLIC_RSA_KEY);
|
||
const mobile_phone = encrypt.encrypt(mobilePhone);
|
||
//MD5加密password
|
||
const encryptedPassword = await cryptoPassword(password);
|
||
//发送登录请求
|
||
const base = await baseRequest();
|
||
const signature = await generateSignature({
|
||
mobile_phone: mobile_phone,
|
||
region_code: regionCode,
|
||
password: encryptedPassword,
|
||
...base,
|
||
});
|
||
try {
|
||
const response = await fetch(
|
||
`${apiUrl}/api/login/login_by_pswd?signature=${signature}`,
|
||
{
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/json",
|
||
},
|
||
body: JSON.stringify({
|
||
mobile_phone: mobile_phone,
|
||
region_code: regionCode,
|
||
password: encryptedPassword,
|
||
...base,
|
||
}),
|
||
}
|
||
);
|
||
const data = await response.json();
|
||
if (data.ret === -1) {
|
||
Toast.show({
|
||
type: "error",
|
||
text1: data.msg,
|
||
topOffset: 60,
|
||
});
|
||
return;
|
||
}
|
||
//保存账号信息,用于切换账号
|
||
await save(`account_list_${data.data.account.user_id}`, {
|
||
mobile_phone_origion: mobilePhone,
|
||
mobile_phone: mobile_phone,
|
||
region_code: regionCode,
|
||
password: encryptedPassword,
|
||
account: data.data.account,
|
||
});
|
||
//登录
|
||
signIn(data, mobilePhone, regionCode);
|
||
} catch (error) {
|
||
console.error(error);
|
||
}
|
||
};
|
||
return (
|
||
<View style={tailwind("mt-14 flex-1 flex-col")}>
|
||
<View style={tailwind("flex px-10 justify-center")}>
|
||
<View style={tailwind("border-2 border-[#2c2b2f] rounded-2xl p-4")}>
|
||
<View style={tailwind("flex flex-row flex-nowrap items-center")}>
|
||
<Text style={tailwind("text-base text-white font-medium mr-4")}>
|
||
+{regionCode}
|
||
</Text>
|
||
<TextInput
|
||
placeholder="请输入手机号"
|
||
placeholderTextColor="#FFFFFF80"
|
||
underlineColorAndroid="transparent"
|
||
keyboardType="numeric"
|
||
onChangeText={(value) => setMobilePhone(value)}
|
||
value={mobilePhone}
|
||
style={tailwind("flex-1 text-white")}
|
||
/>
|
||
</View>
|
||
<View style={tailwind("my-4")}>
|
||
<MyDivider />
|
||
</View>
|
||
<View style={tailwind("flex flex-row flex-nowrap items-center")}>
|
||
<Text style={tailwind("text-base text-white font-medium mr-4")}>
|
||
密码
|
||
</Text>
|
||
<TextInput
|
||
placeholder="请输入密码"
|
||
placeholderTextColor="#FFFFFF80"
|
||
underlineColorAndroid="transparent"
|
||
secureTextEntry={true}
|
||
onChangeText={(value) => setPassword(value)}
|
||
value={password}
|
||
style={tailwind("flex-1 text-white")}
|
||
/>
|
||
</View>
|
||
</View>
|
||
<Text
|
||
onPress={() => navigation.navigate("ForgetPassword")}
|
||
style={tailwind("text-base font-medium text-[#FF669E] ml-auto mt-2")}
|
||
>
|
||
忘记密码?
|
||
</Text>
|
||
<View
|
||
style={tailwind(
|
||
"flex flex-row flex-nowrap justify-center items-center mt-16"
|
||
)}
|
||
>
|
||
<CheckBox
|
||
checked={checked}
|
||
onPress={toggleCheckbox}
|
||
iconType="material-community"
|
||
checkedIcon="checkbox-marked"
|
||
uncheckedIcon="checkbox-blank-outline"
|
||
checkedColor="#FF669E"
|
||
containerStyle={tailwind("p-0 m-0 bg-transparent")}
|
||
size={18}
|
||
/>
|
||
<Text style={tailwind("text-[#FFFFFF80] font-medium text-xs")}>
|
||
我确认已满18周岁并同意
|
||
<Text
|
||
onPress={() =>
|
||
navigation.navigate("WebWithHeader", {
|
||
title: "用户协议",
|
||
uri: `${process.env.EXPO_PUBLIC_WEB_URL}/doc/useragreement`,
|
||
})
|
||
}
|
||
style={tailwind("text-[#FF669E] text-xs")}
|
||
>
|
||
《用户协议》
|
||
</Text>
|
||
、
|
||
<Text
|
||
onPress={() =>
|
||
navigation.navigate("WebWithHeader", {
|
||
title: "隐私政策",
|
||
uri: `${process.env.EXPO_PUBLIC_WEB_URL}/doc/privatypolicy`,
|
||
})
|
||
}
|
||
style={tailwind("text-[#FF669E] text-xs")}
|
||
>
|
||
《隐私政策》
|
||
</Text>
|
||
</Text>
|
||
</View>
|
||
<Button
|
||
color="#FF669E"
|
||
radius="999"
|
||
size="md"
|
||
onPress={handleSubmit}
|
||
titleStyle={tailwind("text-base font-medium")}
|
||
containerStyle={tailwind("mt-2")}
|
||
>
|
||
登录
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
);
|
||
}
|