410 lines
13 KiB
JavaScript
410 lines
13 KiB
JavaScript
import { View, Text, TextInput, TouchableOpacity } 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, storeAppInfo } from "../../../utils/storeInfo";
|
||
import MyModal from "../../../components/MyModal";
|
||
import Modal from "react-native-modal";
|
||
import { WebView } from "react-native-webview";
|
||
import { Icon } from "@rneui/themed";
|
||
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("");
|
||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||
//协议Modal是否展示
|
||
const [popVisible, setPopVisible] = useState({
|
||
visible: false,
|
||
data: {
|
||
title: "",
|
||
uri: "",
|
||
},
|
||
});
|
||
//设置cookies
|
||
const [cookies, setCookies] = useState();
|
||
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 handleCheck = async () => {
|
||
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;
|
||
}
|
||
//验证数据格式
|
||
if (!checked) {
|
||
// Toast.show({
|
||
// type: "error",
|
||
// text1: "请先阅读并同意《用户协议》和《隐私政策》后登录",
|
||
// topOffset: 60,
|
||
// });
|
||
setIsModalVisible(true);
|
||
return;
|
||
}
|
||
handleSubmit();
|
||
};
|
||
const handleSubmit = async () => {
|
||
//重新获取设备和app信息
|
||
await storeAppInfo();
|
||
//对手机号进行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,
|
||
login_time: new Date().getTime(),
|
||
});
|
||
//登录
|
||
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")}>
|
||
我已阅读并同意
|
||
<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>
|
||
);
|
||
}
|