tiefen_space_app/screeens/Login/PhoneNumLogin/index.jsx

486 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { View, Text, TextInput } from "react-native";
import React, { useState, useEffect, useContext } 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 { JSEncrypt } from "jsencrypt";
import MyDivider from "../../../components/MyDivider";
import baseRequest from "../../../utils/baseRequest";
import { get, save, storeAppInfo } from "../../../utils/storeInfo";
import { generateSignature } from "../../../utils/crypto";
import Modal from "react-native-modal";
import { WebView } from "react-native-webview";
import { Icon } from "@rneui/themed";
import MyModal from "../../../components/MyModal";
export default function PhoneNumLogin() {
const { signIn, inviterCode, checked, setChecked } = useContext(AuthContext);
const navigation = useNavigation();
const tailwind = useTailwind();
//设置checkbox
const toggleCheckbox = () => setChecked(!checked);
//重新获取验证码的计时器
const [isCounting, setIsCounting] = useState(false);
const [seconds, setSeconds] = useState(60);
//保存区号、手机号、验证码
const [regionCode, setRegionCode] = useState("86");
const [mobilePhone, setMobilePhone] = useState("");
const [veriCode, setVeriCode] = useState("");
//协议Modal是否展示
const [popVisible, setPopVisible] = useState({
visible: false,
data: {
title: "",
uri: "",
},
});
//设置cookies
const [cookies, setCookies] = useState();
const [isModalVisible, setIsModalVisible] = useState(false);
const setCookieScript = `
document.cookie = "b_mid=${cookies?.b_mid} ;";
document.cookie = "b_did=${cookies?.b_did} ;";
document.cookie = "b_ver=${cookies?.b_ver} ;";
document.cookie = "b_dt=${cookies?.b_dt} ;";
document.cookie = "b_model=${cookies?.b_model} ;";
document.cookie = "b_nt=${cookies?.b_nt} ;";
document.cookie = "b_token=${cookies?.b_token} ;";
true;
`;
useEffect(() => {
async function getCookies() {
const base = await baseRequest();
setCookies({
b_mid: base.b_mid,
b_did: base.b_did,
b_ver: base.b_ver,
b_dt: base.b_dt,
b_model: base.b_model,
b_nt: base.b_nt,
b_token: base.b_token,
});
}
getCookies();
}, []);
//获取之前缓存的用户的手机号
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 apiUrl = process.env.EXPO_PUBLIC_API_URL;
useEffect(() => {
let interval;
if (isCounting && seconds > 0) {
interval = setInterval(() => {
setSeconds(seconds - 1);
}, 1000);
} else {
setIsCounting(false);
setSeconds(60);
clearInterval(interval);
}
return () => {
clearInterval(interval);
};
}, [isCounting, seconds]);
//点击获取验证码
const handleVerification = async () => {
//手机号校验
if (!mobilePhone.match(/^1[3456789]\d{9}$/)) {
Toast.show({
type: "error",
text1: "手机号码格式错误",
topOffset: 60,
});
return;
}
//开始倒计时
setIsCounting(true);
//对手机号进行RSA加密
const encrypt = new JSEncrypt();
encrypt.setPublicKey(process.env.EXPO_PUBLIC_RSA_KEY);
const mobile_phone = encrypt.encrypt(mobilePhone);
//发送短信验证码
const base = await baseRequest();
const signature = await generateSignature({
mobile_phone: mobile_phone,
region_code: regionCode,
...base,
});
try {
await fetch(`${apiUrl}/api/veri_code/send?signature=${signature}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mobile_phone: mobile_phone,
region_code: regionCode,
...base,
}),
});
} catch (error) {
console.error(error);
}
};
//点击登录
const handleSubmit = async () => {
// if (!checked) {
// Toast.show({
// type: "error",
// text1: "请先阅读并同意《用户协议》和《隐私政策》后登录",
// topOffset: 60,
// });
// return;
// }
//重新获取设备和app信息
await storeAppInfo();
//对手机号进行RSA加密
const encrypt = new JSEncrypt();
encrypt.setPublicKey(process.env.EXPO_PUBLIC_RSA_KEY);
const mobile_phone = encrypt.encrypt(mobilePhone);
//发送登录请求
const base = await baseRequest();
const signature = await generateSignature({
mobile_phone: mobile_phone,
region_code: regionCode,
veri_code: veriCode,
inviter: inviterCode,
...base,
});
try {
const response = await fetch(
`${apiUrl}/api/login/login_by_veri_code?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mobile_phone: mobile_phone,
region_code: regionCode,
veri_code: veriCode,
inviter: inviterCode,
...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,
account: data.data.account,
login_time: new Date().getTime(),
});
//若已经设置了密码则直接登录
if (data.data.is_enabled) {
signIn(data, mobilePhone, regionCode);
return;
}
//若没设置密码则前往设置密码
await save("token", data.data.token);
await save("account", data.data.account);
await save("mobile_phone", mobile_phone);
await save("region_code", regionCode);
navigation.navigate("SetPassword", {
data: data,
mobile_phone: mobile_phone,
region_code: regionCode,
mobilePhone: mobilePhone,
});
} catch (error) {
console.error(error);
}
};
//点击登录
const handleCheck = async () => {
if (!mobilePhone.match(/^1[3456789]\d{9}$/)) {
Toast.show({
type: "error",
text1: "手机号码格式错误",
topOffset: 60,
});
return;
}
if (!veriCode) {
Toast.show({
type: "error",
text1: "请输入验证码",
topOffset: 60,
});
return;
}
//验证数据格式
if (!checked) {
setIsModalVisible(true);
return;
}
handleSubmit();
};
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"
keyboardType="numeric"
onChangeText={(value) => setVeriCode(value)}
value={veriCode}
style={tailwind("flex-1 text-white")}
/>
<Button
color="#FF669E"
radius="999"
size="sm"
disabled={isCounting}
disabledStyle={tailwind("bg-[#FFFFFF1A]")}
titleStyle={tailwind("text-xs mx-1")}
onPress={handleVerification}
>
{isCounting ? `(${seconds})重新发送` : "获取验证码"}
</Button>
</View>
</View>
<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")}>
我已阅读并同意
<Text
onPress={() => {
setPopVisible({
visible: true,
data: {
title: "用户协议",
uri: `${process.env.EXPO_PUBLIC_WEB_URL}/doc/useragreement`,
},
});
}}
style={tailwind("text-[#FF669E] text-xs")}
>
用户协议
</Text>
<Text
onPress={() => {
setPopVisible({
visible: true,
data: {
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={handleCheck}
titleStyle={tailwind("text-base font-medium")}
containerStyle={tailwind("mt-2")}
>
登录
</Button>
</View>
<MyModal
visible={isModalVisible}
setVisible={setIsModalVisible}
title="登录提示"
content={
<Text style={tailwind("text-[#FFFFFF80] font-medium text-base")}>
为了更好保障你的合法权益请阅读和同意
<Text
onPress={() => {
setPopVisible({
visible: true,
data: {
title: "用户协议",
uri: `${process.env.EXPO_PUBLIC_WEB_URL}/doc/useragreement`,
},
});
}}
style={tailwind("text-[#FF669E] text-base")}
>
用户协议
</Text>
<Text
onPress={() => {
setPopVisible({
visible: true,
data: {
title: "隐私政策",
uri: `${process.env.EXPO_PUBLIC_WEB_URL}/doc/privatypolicy`,
},
});
}}
style={tailwind("text-[#FF669E] text-base")}
>
隐私政策
</Text>
</Text>
}
cancel={() => {
setIsModalVisible(false);
}}
confirm={() => {
setIsModalVisible(false);
toggleCheckbox();
handleSubmit();
}}
/>
{/* 协议通知弹窗 */}
{popVisible.visible && (
<Modal
isVisible={popVisible.visible}
// swipeDirection={["down"]}
onBackdropPress={() =>
setPopVisible({
visible: false,
data: {
title: "",
uri: "",
},
})
}
animationInTiming={500} // 打开动画时长
animationOutTiming={1000} // 关闭动画时长
animationIn="bounceInUp" // 打开动画类型
animationOut="bounceInDown" // 关闭动画类型
// scrollHorizontal={true}
style={{
height: 120,
paddingBottom: 0,
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
margin: 0,
justifyContent: "flex-end",
}}
>
<View style={tailwind("flex flex-row items-center h-12")}>
<Icon
type="ionicon"
name="chevron-back"
size={32}
color="white"
onPress={() =>
setPopVisible({
visible: false,
data: {
title: "",
uri: "",
},
})
}
/>
<Text style={tailwind("text-base font-medium text-white")}>
{popVisible.data.title}
</Text>
</View>
<View
style={{
...tailwind("w-full"),
backgroundColor: "#17161A",
paddingBottom: 20,
height: 620,
}}
>
<WebView
incognito
source={{
uri: popVisible.data.uri,
}}
userAgent="FromWebview"
// onMessage={async (event) => {
// const msg = JSON.parse(event.nativeEvent.data);
// if (msg.type === "SAVE_IMAGE") {
// saveImage(msg.data);
// } else if (msg.type === "COPY_URL") {
// copy(msg.data);
// } else if (msg.type === "NAVIGATE") {
// navigation.navigate(msg.data.page, { ...msg.data.params });
// } else if (msg.type === "OPEN_BROWSER") {
// openBrowser(msg.data);
// }
// }}
injectedJavaScript={setCookieScript}
originWhitelist={[
"https://*",
"http://*",
"alipays://*",
"alipay://*",
"weixin://*",
]}
/>
</View>
</Modal>
)}
</View>
);
}