tiefen_space_app/screeens/SpaceSetting/AgencySetting/index.jsx

530 lines
17 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,
ScrollView,
Modal,
TextInput,
KeyboardAvoidingView,
TouchableOpacity,
Image as NativeImage,
} from "react-native";
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Toast from "react-native-toast-message";
import { Image } from "expo-image";
import { Icon, Button } from "@rneui/themed";
import baseRequest from "../../../utils/baseRequest";
import { generateSignature } from "../../../utils/crypto";
import { get } from "../../../utils/storeInfo";
import { JSEncrypt } from "jsencrypt";
import Picker from "../../../components/Picker";
export default function AgencySetting({ navigation, route }) {
const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk";
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
//获取环境变量
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
//获取数据
const [data, setData] = useState();
useEffect(() => {
const getData = async () => {
try {
const base = await baseRequest();
const body = {
zid: route.params.data.id,
...base,
};
const signature = await generateSignature(body);
const _response = await fetch(
`${apiUrl}/api/zone_third_partner/list?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const _data = await _response.json();
if (_data.ret === -1) {
Toast.show({
type: "error",
text1: _data.msg,
topOffset: 60,
});
return;
}
setData(_data.data.zone_third_partner);
} catch (error) {
console.error(error);
}
};
getData();
}, []);
//获取当前用户的手机号
const [regionCode, setRegionCode] = useState("");
const [mobilePhone, setMobilePhone] = useState("");
useEffect(() => {
async function getMobilePhone() {
setMobilePhone(await get("mobile_phone"));
setRegionCode(await get("region_code"));
}
getMobilePhone();
}, []);
//添加代运营Modal
const [idAddAgencyModalVisible, setIsAddAgencyModalVisible] = useState(false);
//搜索用户ID以及是否选中用户
const [userId, setUserId] = useState();
const [agencyData, setAgencyData] = useState();
const [isSelected, setIsSelected] = useState(false);
const handleSearch = async () => {
if (!userId) {
Toast.show({
type: "error",
text1: "请先输入ID",
topOffset: 60,
});
return;
}
const base = await baseRequest();
const signature = await generateSignature({
...base,
user_id: parseInt(userId, 10),
});
try {
//获取账号基本信息
const _response = await fetch(
`${apiUrl}/api/account/list_others_by_user_id?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
user_id: parseInt(userId, 10),
}),
}
);
const _data = await _response.json();
if (_data.ret === -1) {
Toast.show({
type: "error",
text1: _data.msg,
topOffset: 60,
});
return;
}
setAgencyData(_data.data.account);
setIsSelected(false);
} catch (error) {
console.error(error);
}
};
//验证码
const [veriCode, setVeriCode] = useState();
//重新获取验证码的计时器
const [isCounting, setIsCounting] = useState(false);
const [seconds, setSeconds] = useState(60);
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 (!isSelected) {
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 [rate, setRate] = useState();
//生成比例选项
const generateItems = useCallback((min, max) => {
const items = [];
for (let i = min; i <= max; i++) {
items.push({ label: `${i.toString()}%`, value: i.toString() });
}
return items;
}, []);
const rates = useMemo(() => generateItems(1, 50), []);
//提交
const handleSubmit = async () => {
if (!isSelected) {
Toast.show({
type: "error",
text1: "请先选中用户",
topOffset: 60,
});
return;
}
if (!veriCode) {
Toast.show({
type: "error",
text1: "请输入验证码",
topOffset: 60,
});
return;
}
if (!rate) {
Toast.show({
type: "error",
text1: "请选择分成比例",
topOffset: 60,
});
return;
}
try {
const base = await baseRequest();
//对手机号进行RSA加密
const encrypt = new JSEncrypt();
encrypt.setPublicKey(process.env.EXPO_PUBLIC_RSA_KEY);
const mobile_phone = encrypt.encrypt(mobilePhone);
const body = {
zid: route.params.data.id,
third_partner_mid: agencyData.mid,
region_code: regionCode,
mobile_phone: mobile_phone,
veri_code: veriCode,
sharing_ratio: parseInt(rate, 10) / 100,
...base,
};
const signature = await generateSignature(body);
const _response = await fetch(
`${apiUrl}/api/zone_third_partner/create?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const _data = await _response.json();
if (_data.ret === -1) {
Toast.show({
type: "error",
text1: _data.msg,
topOffset: 60,
});
return;
}
navigation.goBack();
} catch (error) {
console.error(error);
}
};
//关闭
const handleCancel = () => {
setIsAddAgencyModalVisible(false);
setIsSelected(false);
setAgencyData();
setUserId();
setRate();
setVeriCode();
};
return (
<ScrollView
style={{
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1"),
}}
>
<View style={tailwind("flex flex-col items-center p-4")}>
{data ? (
<Image
source={data.third_partner_account.avatar.images[0].urls[0]}
contentFit="cover"
transition={1000}
placeholder={blurhash}
cachePolicy="disk"
style={tailwind("w-[4.6rem] h-[4.6rem] rounded-full")}
/>
) : (
<Icon
onPress={() => setIsAddAgencyModalVisible(true)}
type="ionicon"
name="add"
size={40}
color="white"
containerStyle={tailwind(
"border border-white rounded-full w-[4.6rem] h-[4.6rem] flex items-center justify-center"
)}
/>
)}
{data && (
<View
style={{
gap: 8,
...tailwind(
"flex flex-col border border-2 border-[#2c2b2f] rounded-2xl p-4 w-full mt-6"
),
}}
>
<Text style={tailwind("text-white text-base font-medium")}>
代运营昵称{data.third_partner_account.name}
</Text>
<Text style={tailwind("text-white text-base font-medium")}>
ID{data.third_partner_account.user_id}
</Text>
<Text style={tailwind("text-white text-base font-medium")}>
分成比例{(data.sharing_ratio * 100).toFixed()}%
</Text>
</View>
)}
<View style={tailwind("mt-8")}>
<Text style={tailwind("text-[#FFFFFF80] text-base font-medium")}>
注意事项
</Text>
<Text style={tailwind("text-[#FFFFFF80] text-sm")}>
1一个空间仅可设置一个代运营若您的代运营团队为多人请设置代运营主账号后让代运营主账号进入当前空间设置合伙人
</Text>
<Text style={tailwind("text-[#FFFFFF80] text-sm")}>
2设置完成后无法再次修改人员和分成比例请确认后再提交后续如需修改请联系人工客服
</Text>
<Text style={tailwind("text-[#FFFFFF80] text-sm")}>
3您获得的收益会按照您设置的分成比例直接转移至代运营及协作者账户您将不会得到这部分的收益如有疑问请咨询人工客服
</Text>
</View>
</View>
<Modal
visible={idAddAgencyModalVisible}
transparent={true}
statusBarTranslucent
animationType="fade"
>
<TouchableOpacity
activeOpacity={1}
onPress={handleCancel}
style={tailwind("flex flex-1 bg-[#00000080] px-4")}
>
<KeyboardAvoidingView
style={tailwind("flex flex-1 items-center justify-center")}
behavior="padding"
>
<TouchableOpacity
activeOpacity={1}
style={{
gap: 12,
...tailwind(
"flex flex-col w-full bg-[#17161A] rounded-3xl px-4 py-6"
),
}}
>
<View style={tailwind("flex flex-row items-center")}>
<Text style={tailwind("text-white text-base font-medium")}>
搜索用户
</Text>
<TextInput
placeholder="请输入用户ID"
placeholderTextColor="#FFFFFF80"
keyboardType="numeric"
underlineColorAndroid="transparent"
onChangeText={(value) => setUserId(value)}
value={userId}
style={tailwind(
"flex-1 bg-[#FFFFFF1A] text-white rounded-2xl px-4 h-8 mx-2"
)}
/>
<Text
onPress={handleSearch}
style={tailwind("text-[#FF669E] text-base font-medium")}
>
搜索
</Text>
</View>
{agencyData && (
<View
style={[
tailwind("flex flex-row items-center rounded-2xl p-4"),
isSelected
? { borderColor: "#FF669E", ...tailwind("border") }
: { borderColor: "#2c2b2f", ...tailwind("border") },
]}
>
<Image
source={agencyData?.avatar?.images[0]?.urls[0]}
contentFit="cover"
transition={1000}
placeholder={blurhash}
cachePolicy="disk"
style={tailwind("w-12 h-12 rounded-full")}
/>
<View
style={tailwind(
"flex flex-1 flex-col justify-around items-start ml-2"
)}
>
<Text
style={tailwind("text-base text-white font-medium")}
numberOfLines={1}
ellipsizeMode="tail"
>
{agencyData?.name}
</Text>
<View
style={tailwind(
"flex flex-row items-center py-0.5 px-2 bg-[#FFFFFF1A] rounded-full"
)}
>
<NativeImage
source={require("../../../assets/icon/12DP/ID.png")}
/>
<Text
style={tailwind(
"text-white text-xs font-medium ml-0.5"
)}
>
{agencyData?.user_id}
</Text>
</View>
</View>
<Button
color={isSelected ? "#FFFFFF1A" : "#FF669E"}
radius="999"
size="md"
onPress={() => setIsSelected(!isSelected)}
titleStyle={tailwind("text-base")}
containerStyle={{ width: 80 }}
>
{isSelected ? "取消" : "选择"}
</Button>
</View>
)}
<View style={tailwind("flex flex-row items-center")}>
<Text style={tailwind("text-white text-base font-medium")}>
手机号
<Text style={tailwind("text-[#FFFFFF80]")}>
{mobilePhone?.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2")}
</Text>
</Text>
</View>
<View style={tailwind("flex flex-row items-center")}>
<Text style={tailwind("text-white text-base font-medium")}>
验证码
</Text>
<TextInput
placeholder="请输入验证码"
placeholderTextColor="#FFFFFF80"
keyboardType="numeric"
underlineColorAndroid="transparent"
onChangeText={(value) => setVeriCode(value)}
value={veriCode}
style={tailwind(
"flex-1 bg-[#FFFFFF1A] text-white rounded-2xl px-4 h-8 mx-2"
)}
/>
<Button
color="#FF669E"
radius="999"
size="sm"
disabled={isCounting}
disabledStyle={tailwind("bg-[#FFFFFF1A]")}
titleStyle={tailwind("text-sm mx-2")}
onPress={handleVerification}
>
{isCounting ? `(${seconds})重新发送` : "获取验证码"}
</Button>
</View>
<View style={tailwind("flex flex-row items-center")}>
<Text style={tailwind("text-white text-base font-medium")}>
分成比例
</Text>
<View style={tailwind("w-1/3")}>
<Picker items={rates} onChange={(value) => setRate(value)} />
</View>
</View>
<Text style={tailwind("text-[#F53030] text-xs font-medium")}>
注意事项分成比例不得超过50%且确认后无法修改
</Text>
<View style={tailwind("flex flex-row mt-2")}>
<Button
color="#FF669E"
radius="999"
size="md"
titleStyle={tailwind("text-sm mx-2")}
containerStyle={tailwind("flex-1 px-2")}
onPress={handleSubmit}
>
确认
</Button>
<Button
color="#FFFFFF1A"
radius="999"
size="md"
titleStyle={tailwind("text-sm mx-2")}
containerStyle={tailwind("flex-1 px-2")}
onPress={handleCancel}
>
取消
</Button>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</TouchableOpacity>
<Toast />
</Modal>
</ScrollView>
);
}