修改入驻流程 #14

Merged
yezian merged 1 commits from change_join into main 2024-07-09 23:12:55 +08:00
5 changed files with 700 additions and 246 deletions
Showing only changes of commit 798d681494 - Show all commits

View File

@ -69,6 +69,7 @@ export default function My({ navigation }) {
}, []);
//focus
const [isInJoinProgress, setIsInJoinProgress] = useState(false);
useFocusEffect(
useCallback(() => {
const getData = async () => {
@ -182,10 +183,64 @@ export default function My({ navigation }) {
console.error(error);
}
};
//
const getBasicStatus = async () => {
//
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const base = await baseRequest();
const body = {
...base,
};
const signature = await generateSignature(body);
try {
//
const _response = await fetch(
`${apiUrl}/api/account/list_by_mid?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;
}
if (
_data.data.basic_status === 0 ||
_data.data.basic_status === 1 ||
_data.data.basic_status === 3
)
setIsInJoinProgress(true);
} catch (error) {
console.error(error);
}
};
getData();
getBasicStatus();
}, [])
);
//toast
const remainCompleteInformation = (func) => {
if (data?.role === 3) {
func();
return;
}
Toast.show({
type: "error",
text1: "请先完善资料并等待审核通过",
topOffset: 60,
});
};
return (
<ScrollView>
<View
@ -395,16 +450,43 @@ export default function My({ navigation }) {
</View>
</TouchableOpacity>
{/* 纵向列表设置区 */}
{data?.role === 3 && (
{(data?.role === 3 || isInJoinProgress) && (
<View
style={{
...tailwind("flex flex-col py-2 rounded-2xl mt-3.5 border-2"),
borderColor: "#2c2b2f",
}}
>
{isInJoinProgress && (
<TouchableOpacity
onPress={() =>
navigation.navigate("StreamerVerification", {
screen: "CompleteStreamerInformation",
})
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
<NativeImage
source={require("../../assets/icon/32DP/editprofile.png")}
/>
<Text style={tailwind("text-base text-white ml-2 flex-1")}>
完善资料
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
完善后解锁全部功能
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
/>
</TouchableOpacity>
)}
{data?.streamer_ext?.zones?.length === 0 ? (
<TouchableOpacity
onPress={() => navigation.navigate("CreateSpace")}
onPress={() =>
remainCompleteInformation(() =>
navigation.navigate("CreateSpace")
)
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
<NativeImage
@ -414,7 +496,7 @@ export default function My({ navigation }) {
开通空间
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
创作者功能
{data?.role === 3 ? "创作者功能" : "完善资料后解锁"}
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
@ -423,7 +505,9 @@ export default function My({ navigation }) {
) : (
<TouchableOpacity
onPress={() =>
navigation.navigate("StreamerSpace", { mid: data?.mid })
remainCompleteInformation(() =>
navigation.navigate("StreamerSpace", { mid: data?.mid })
)
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
@ -434,7 +518,7 @@ export default function My({ navigation }) {
我的空间
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
创作者功能
{data?.role === 3 ? "创作者功能" : "完善资料后解锁"}
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
@ -443,7 +527,9 @@ export default function My({ navigation }) {
)}
<TouchableOpacity
onPress={() =>
navigation.navigate("StreamerPosts", { mid: data?.mid })
remainCompleteInformation(() =>
navigation.navigate("StreamerPosts", { mid: data?.mid })
)
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
@ -454,7 +540,7 @@ export default function My({ navigation }) {
广场动态
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
创作者功能
{data?.role === 3 ? "创作者功能" : "完善资料后解锁"}
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
@ -462,7 +548,9 @@ export default function My({ navigation }) {
</TouchableOpacity>
<TouchableOpacity
onPress={() =>
navigation.navigate("WechatWaitingToAdd", { tab: 0 })
remainCompleteInformation(() =>
navigation.navigate("WechatWaitingToAdd", { tab: 0 })
)
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
@ -473,38 +561,46 @@ export default function My({ navigation }) {
待添加微信
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
创作者功能
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate("EditStreamerInfo")}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
<NativeImage
source={require("../../assets/icon/32DP/editprofile.png")}
/>
<Text style={tailwind("text-base text-white ml-2 flex-1")}>
编辑资料
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
创作者功能
{data?.role === 3 ? "创作者功能" : "完善资料后解锁"}
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
/>
</TouchableOpacity>
{data?.role === 3 && (
<TouchableOpacity
onPress={() =>
remainCompleteInformation(() =>
navigation.navigate("EditStreamerInfo")
)
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
<NativeImage
source={require("../../assets/icon/32DP/editprofile.png")}
/>
<Text style={tailwind("text-base text-white ml-2 flex-1")}>
编辑资料
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
{data?.role === 3 ? "创作者功能" : "完善资料后解锁"}
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
/>
</TouchableOpacity>
)}
<TouchableOpacity
onPress={() =>
navigation.navigate("WebWithHeader", {
title: "我的专属链接",
uri:
process.env.EXPO_PUBLIC_WEB_URL +
"/generatelink/" +
data?.user_id,
})
remainCompleteInformation(() =>
navigation.navigate("WebWithHeader", {
title: "我的专属链接",
uri:
process.env.EXPO_PUBLIC_WEB_URL +
"/generatelink/" +
data?.user_id,
})
)
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
@ -515,7 +611,7 @@ export default function My({ navigation }) {
生成分享页
</Text>
<Text style={{ ...tailwind("text-xs"), color: "#FFFFFF80" }}>
创作者功能
{data?.role === 3 ? "创作者功能" : "完善资料后解锁"}
</Text>
<NativeImage
source={require("../../assets/icon/32DP/smalllink.png")}
@ -558,7 +654,11 @@ export default function My({ navigation }) {
/>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigation.navigate("StreamerVerification")}
onPress={() =>
navigation.navigate("StreamerVerification", {
screen: "JoinStreamer",
})
}
style={tailwind("flex flex-row h-12 items-center pr-2 pl-4")}
>
<NativeImage

View File

@ -1,8 +1,8 @@
import { View, Text } from "react-native";
import { View, Text, ScrollView } from "react-native";
import React, { useState, useEffect } from "react";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Icon } from "@rneui/themed";
import { Icon, Button } from "@rneui/themed";
import baseRequest from "../../../utils/baseRequest";
import Toast from "react-native-toast-message";
import { generateSignature } from "../../../utils/crypto";
@ -53,35 +53,75 @@ export default function AfterSubmitStreamerVerification({ navigation, route }) {
}, []);
return (
<View
<ScrollView
style={{
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1 py-4 items-center"),
...tailwind("flex-1"),
}}
>
<Icon name="checkmark-circle" type="ionicon" color="#27F5B7" size={100} />
<Text style={tailwind("text-2xl text-white font-medium mb-2")}>
提交成功
</Text>
<Text
style={tailwind("text-base text-white font-medium text-center w-2/3")}
>
请添加工作人员
<Text style={tailwind("text-[#F53030]")}>微信{wechatList[0]}</Text>
直接商讨合作事宜如未添加可能影响审核进度请及时添加
</Text>
<View style={tailwind("mt-4")}>
{wechatList.map((item, index) => {
if (index === 0) return;
return (
<Text key={index} style={tailwind("text-base text-[#F53030]")}>
备用微信{index}{item}
</Text>
);
})}
<View style={tailwind("flex flex-col items-center p-4")}>
<Icon
name="checkmark-circle"
type="ionicon"
color="#27F5B7"
size={100}
/>
<Text style={tailwind("text-2xl text-white font-medium mb-2")}>
提交成功
</Text>
<Text style={tailwind("text-base text-center text-white font-medium")}>
请添加工作人员
<Text style={tailwind("text-[#F53030]")}>微信{wechatList[0]}</Text>
直接商讨合作事宜如未添加可能影响审核进度请及时添加您可以选择继续完善资料这将加快您的审核进度
</Text>
<View style={tailwind("mt-4")}>
{wechatList.map((item, index) => {
if (index === 0) return;
return (
<Text key={index} style={tailwind("text-base text-[#F53030]")}>
备用微信{index}{item}
</Text>
);
})}
</View>
<View style={tailwind("flex flex-col w-full px-4")}>
<Button
onPress={() => navigation.replace("CompleteStreamerInformation")}
color="#FF669E"
radius="999"
size="md"
titleStyle={tailwind("text-base")}
containerStyle={tailwind("my-4 w-full")}
>
<View style={tailwind("flex flex-col items-center")}>
<Text style={tailwind("text-base text-white")}>前往完善资料</Text>
<Text style={tailwind("text-xs text-white")}>
一次填完更快审核哦
</Text>
</View>
</Button>
<Button
onPress={() => navigation.goBack()}
color="#FFFFFF1A"
radius="999"
size="md"
titleStyle={tailwind("text-base")}
containerStyle={{
marginBottom: insets.bottom + 60,
...tailwind("w-full"),
}}
>
<View style={tailwind("flex flex-col items-center")}>
<Text style={tailwind("text-base text-white")}>返回主页</Text>
<Text style={tailwind("text-xs text-white")}>
可在我的继续完善资料
</Text>
</View>
</Button>
</View>
</View>
</View>
</ScrollView>
);
}

View File

@ -18,15 +18,15 @@ import Picker from "../../../components/Picker";
import MediaPickerModal from "../../../components/MediaPickerModal";
import MediaPicker from "../../../components/MediaPicker";
import Toast from "react-native-toast-message";
import { StackActions } from "@react-navigation/native";
import { get } from "../../../utils/storeInfo";
import { multiUpload } from "../../../utils/upload";
import baseRequest from "../../../utils/baseRequest";
import { generateSignature } from "../../../utils/crypto";
import MediaGrid from "../../../components/MediaGrid";
const blurhash = "LcKUTa%gOYWBYRt6xuoJo~s8V@fk";
export default function StreamerVerificationForm({ navigation, route }) {
export default function CompleteStreamerInformation({ navigation, route }) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
@ -41,8 +41,10 @@ export default function StreamerVerificationForm({ navigation, route }) {
const [displayVideo, setDisplayVideo] = useState([]);
const [wechatInputShow, setWechatInputShow] = useState(1);
//
//
const [photos, setPhotos] = useState([]);
//
const [oldPhotos, setOldPhotos] = useState([]);
//
const [tags, setTags] = useState([]);
@ -88,9 +90,6 @@ export default function StreamerVerificationForm({ navigation, route }) {
);
};
//
const [accountImages, setAccountImages] = useState([]);
//
const generateItems = useCallback((min, max) => {
const items = [];
@ -154,17 +153,106 @@ export default function StreamerVerificationForm({ navigation, route }) {
];
//
const [data, setData] = useState({ tag: {} });
const [data, setData] = useState();
const [allTag, setAllTag] = useState({});
//
const [isLoading, setIsloading] = useState(true);
const [isWaitingReview, setIsWaitingReview] = useState(false);
useEffect(() => {
const getData = async () => {
const account = await get("account");
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const base = await baseRequest();
const signature = await generateSignature({
...base,
});
try {
const response = await fetch(
//
const body = {
...base,
};
const signature = await generateSignature(body);
const statusResponse = await fetch(
`${apiUrl}/api/streamer_auth_approval/get_statuses?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const statusData = await statusResponse.json();
if (statusData.ret === -1) {
Toast.show({
type: "error",
text1: statusData.msg,
topOffset: 60,
});
return;
}
if (statusData?.data?.details_status === 0) setIsWaitingReview(true);
if (statusData?.data?.details_status !== 2) {
setData({ ...account, streamer: {} });
return;
}
//
const body2 = {
approve_status: 2,
...base,
};
const signature2 = await generateSignature(body2);
const _response = await fetch(
`${apiUrl}/api/streamer_auth_approval_his/list_details?signature=${signature2}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body2),
}
);
const _data = await _response.json();
if (_data.ret === -1) {
Toast.show({
type: "error",
text1: _data.msg,
topOffset: 60,
});
return;
}
setData({ ...account, streamer: _data.data.list[0] });
setWechatInputShow(_data.data.list[0].wechat_lock_type);
setTags(_data.data.list[0].tag);
if (_data.data.list[0])
setDisplayImage([
{
notChanged: true,
id: { image_ids: _data.data.list[0].cover.image_ids },
uri: _data.data.list[0].cover.images[0].urls[0],
},
]);
setDisplayVideo([
{
notChanged: true,
id: { video_ids: _data.data.list[0].shorts?.video_ids },
old_uri: _data.data.list[0].shorts?.videos[0]?.cover_urls[0],
},
]);
setOldPhotos(_data.data.list[0].album.images);
} catch (error) {
console.error(error);
} finally {
setIsloading(false);
}
};
const getAllTag = async () => {
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
const base = await baseRequest();
try {
//
const signature = await generateSignature({
...base,
});
const _response = await fetch(
`${apiUrl}/api/streamer_tag/list?signature=${signature}`,
{
method: "POST",
@ -176,7 +264,7 @@ export default function StreamerVerificationForm({ navigation, route }) {
}),
}
);
const tagData = await response.json();
const tagData = await _response.json();
if (tagData.ret === -1) {
Toast.show({
type: "error",
@ -185,12 +273,13 @@ export default function StreamerVerificationForm({ navigation, route }) {
});
return;
}
setData({ ...account, tag: tagData.data });
setAllTag(tagData.data);
} catch (error) {
console.error(error);
}
};
getData();
getAllTag();
}, []);
//
@ -199,6 +288,38 @@ export default function StreamerVerificationForm({ navigation, route }) {
//ScrollView
const [dragging, setDragging] = useState(false);
//loading
if (isLoading) {
return (
<ActivityIndicator style={tailwind("mt-32")} size="large" color="white" />
);
}
//
if (isWaitingReview) {
return (
<ScrollView
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1"),
}}
>
<View style={tailwind("flex flex-col items-center p-4")}>
<Icon
name="information-circle"
type="ionicon"
color="#27F5B7"
size={100}
/>
<Text style={tailwind("text-2xl text-white font-medium")}>
正在审核中请耐心等待
</Text>
</View>
</ScrollView>
);
}
return (
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
@ -210,38 +331,45 @@ export default function StreamerVerificationForm({ navigation, route }) {
}}
>
<ScrollView scrollEnabled={!dragging} style={tailwind("px-4 py-4")}>
{data.streamer?.remarks && (
<View style={tailwind("mb-4")}>
<View style={tailwind("p-4 rounded-2xl bg-[#FFFFFF1A]")}>
<Text style={tailwind("text-sm font-medium text-white")}>
<Text style={tailwind("text-[#F53030]")}>驳回原因</Text>
{data.streamer?.remarks}
</Text>
</View>
</View>
)}
<Formik
initialValues={{
name: "",
fans: "",
platforms: "",
gender: "",
contact: "",
wechat_add_way: "1",
wechat: "",
price: "",
info: "",
age: "",
height: "",
weight: "",
constellation: "",
location: "",
auto_response_message: "",
fans: data?.streamer?.fans?.toString(),
gender: data?.streamer?.gender?.toString(),
wechat_add_way: data?.streamer?.wechat_lock_type?.toString(),
wechat: data?.streamer?.wechat_contact?.toString(),
price:
data?.streamer?.wechat_coin_price === undefined
? ""
: (data?.streamer?.wechat_coin_price / 10)?.toString(),
info: data?.streamer?.bio?.toString(),
age: data?.streamer?.age?.toString(),
height: data?.streamer?.height?.toString(),
weight: data?.streamer?.weight?.toString(),
constellation: data?.streamer?.constellation?.toString(),
location: data?.streamer?.city?.toString(),
auto_response_message:
data?.streamer?.auto_response_message?.toString(),
}}
enableReinitialize
onSubmit={async (values) => {
if (
!values.name ||
!values.fans ||
!values.gender ||
!values.platforms ||
!values.contact ||
accountImages.length === 0 ||
!values.wechat_add_way ||
!values.price ||
!values.info ||
displayImage.length === 0 ||
displayVideo.length === 0 ||
photos.length === 0 ||
!values.age ||
!values.height ||
!values.weight ||
@ -283,17 +411,40 @@ export default function StreamerVerificationForm({ navigation, route }) {
});
return;
}
//2
if (oldPhotos.length + photos.length < 2) {
Toast.show({
type: "error",
text1: "相册至少需要上传2张照片哦",
topOffset: 60,
});
return;
}
//9
if (oldPhotos.length + photos.length > 9) {
Toast.show({
type: "error",
text1: "相册最多只能上传9张照片哦",
topOffset: 60,
});
return;
}
setIsSubmitting(true);
const account = await get("account");
const cover = await multiUpload(displayImage);
const shorts = await multiUpload(displayVideo);
const album = await multiUpload(photos);
const account_shot = await multiUpload(accountImages);
const cover = displayImage[0].notChanged
? displayImage[0].id
: await multiUpload(displayImage);
const shorts = displayVideo[0].notChanged
? displayVideo[0].id
: await multiUpload(displayVideo);
const newPhotosIds = await multiUpload(photos);
const oldPhotosIds = oldPhotos.map((item) => item.id);
const album = {
image_ids: [...oldPhotosIds, ...newPhotosIds?.image_ids],
};
if (
!cover.image_ids.length ||
!shorts.video_ids.length ||
!album.image_ids.length ||
!account_shot.image_ids.length
!album.image_ids.length
) {
Toast.show({
type: "error",
@ -303,27 +454,14 @@ export default function StreamerVerificationForm({ navigation, route }) {
setIsSubmitting(false);
return;
}
if (album.image_ids.length < 2) {
Toast.show({
type: "error",
text1: "相册至少需要上传2张照片哦",
topOffset: 60,
});
setIsSubmitting(false);
return;
}
//
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
//
const base = await baseRequest();
const signature = await generateSignature({
mid: account?.mid,
avatar: { image_ids: [account?.avatar.images[0].id] },
name: values.name,
const body = {
gender: parseInt(values.gender, 10),
contact_way: values.contact,
wechat_contact: values.wechat,
bio: values.info,
cover: cover,
@ -336,46 +474,21 @@ export default function StreamerVerificationForm({ navigation, route }) {
city: values.location,
tag: tags,
wechat_lock_type: parseInt(values.wechat_add_way, 10),
account_shot: account_shot,
fans: parseInt(values.fans, 10),
main_platform: values.platforms,
wechat_coin_price: parseInt(values.price, 10) * 10,
auto_response_message: values.auto_response_message,
...base,
});
};
const signature = await generateSignature(body);
try {
const response = await fetch(
`${apiUrl}/api/streamer_auth_approval/create?signature=${signature}`,
`${apiUrl}/api/streamer_auth_approval/create_details?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mid: account?.mid,
avatar: { image_ids: [account?.avatar.images[0].id] },
name: values.name,
gender: parseInt(values.gender, 10),
contact_way: values.contact,
wechat_contact: values.wechat,
bio: values.info,
cover: cover,
shorts: shorts,
album: album,
age: parseInt(values.age, 10),
height: parseInt(values.height, 10),
weight: parseInt(values.weight, 10),
constellation: values.constellation,
city: values.location,
tag: tags,
wechat_lock_type: parseInt(values.wechat_add_way, 10),
account_shot: account_shot,
fans: parseInt(values.fans, 10),
main_platform: values.platforms,
wechat_coin_price: parseInt(values.price, 10) * 10,
auto_response_message: values.auto_response_message,
...base,
}),
body: JSON.stringify(body),
}
);
const streamerData = await response.json();
@ -387,10 +500,13 @@ export default function StreamerVerificationForm({ navigation, route }) {
});
return;
}
//
navigation.dispatch(
StackActions.replace("AfterSubmitStreamerVerification")
);
//toast
Toast.show({
type: "success",
text1: "提交成功",
topOffset: 60,
});
navigation.goBack();
} catch (error) {
console.error(error);
} finally {
@ -400,97 +516,6 @@ export default function StreamerVerificationForm({ navigation, route }) {
>
{({ handleChange, handleSubmit, values, setFieldValue }) => (
<>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
审核资料仅用于审核不对外展示
</Text>
<View style={tailwind("my-2 bg-[#FFFFFF1A] p-2 rounded-2xl")}>
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
昵称
</Text>
<View
style={tailwind("flex-row flex-1 justify-end items-center")}
>
<TextInput
placeholder="请输入可搜索到您的昵称"
placeholderTextColor="#FFFFFF80"
style={tailwind("text-white flex-1")}
underlineColorAndroid="transparent"
textAlign="right"
onChangeText={handleChange("name")}
value={values.name}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
主营平台
</Text>
<View
style={tailwind("flex-row flex-1 justify-end items-center")}
>
<TextInput
placeholder="若有多个,按粉丝从多到少排序"
placeholderTextColor="#FFFFFF80"
style={tailwind("text-white flex-1")}
underlineColorAndroid="transparent"
textAlign="right"
onChangeText={handleChange("platforms")}
value={values.platforms}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
联系方式
</Text>
<View
style={tailwind("flex-row flex-1 justify-end items-center")}
>
<TextInput
placeholder="注明方式,如“电话:xxxxx”"
placeholderTextColor="#FFFFFF80"
style={tailwind("text-white flex-1")}
underlineColorAndroid="transparent"
textAlign="right"
onChangeText={handleChange("contact")}
value={values.contact}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
<View>
<View
style={tailwind("flex-row justify-between items-center")}
>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
账号截图
</Text>
<Text
style={tailwind("text-xs text-[#FFFFFF80] font-medium")}
>
各平台账号截图最多9张
</Text>
</View>
<MediaPicker
setDragging={setDragging}
maxCount={9}
type="image"
setAssets={setAccountImages}
/>
</View>
</View>
<Text style={tailwind("text-base text-white font-medium mt-2")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
展示资料将在个人主页大厅展示
</Text>
<View style={tailwind("my-2 bg-[#FFFFFF1A] p-2 rounded-2xl")}>
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
@ -557,6 +582,7 @@ export default function StreamerVerificationForm({ navigation, route }) {
},
{ label: "男", value: "0" },
]}
value={values.gender}
onChange={handleChange("gender")}
/>
</View>
@ -568,7 +594,7 @@ export default function StreamerVerificationForm({ navigation, route }) {
添加标签
</Text>
<View style={tailwind("flex-row flex-wrap")}>
{Object.entries(data?.tag).map(([tag, label]) => {
{Object.entries(allTag).map(([tag, label]) => {
return <TagItem key={tag} tag={label} label={label} />;
})}
</View>
@ -810,6 +836,11 @@ export default function StreamerVerificationForm({ navigation, route }) {
将在主页展示29
</Text>
</View>
<MediaGrid
setDragging={setDragging}
assets={oldPhotos}
setAssets={setOldPhotos}
/>
<MediaPicker
setDragging={setDragging}
maxCount={9}
@ -824,7 +855,11 @@ export default function StreamerVerificationForm({ navigation, route }) {
年龄
</Text>
<View style={tailwind("w-1/2")}>
<Picker items={ages} onChange={handleChange("age")} />
<Picker
items={ages}
value={values.age}
onChange={handleChange("age")}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
@ -834,7 +869,11 @@ export default function StreamerVerificationForm({ navigation, route }) {
身高cm
</Text>
<View style={tailwind("w-1/2")}>
<Picker items={heights} onChange={handleChange("height")} />
<Picker
items={heights}
value={values.height}
onChange={handleChange("height")}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
@ -844,7 +883,11 @@ export default function StreamerVerificationForm({ navigation, route }) {
体重kg
</Text>
<View style={tailwind("w-1/2")}>
<Picker items={weights} onChange={handleChange("weight")} />
<Picker
items={weights}
value={values.weight}
onChange={handleChange("weight")}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
@ -855,6 +898,7 @@ export default function StreamerVerificationForm({ navigation, route }) {
<View style={tailwind("w-1/2")}>
<Picker
items={constellations}
value={values.constellation}
onChange={handleChange("constellation")}
/>
</View>
@ -867,6 +911,7 @@ export default function StreamerVerificationForm({ navigation, route }) {
<View style={tailwind("w-1/2")}>
<Picker
items={provinces}
value={values.location}
onChange={handleChange("location")}
/>
</View>

View File

@ -0,0 +1,238 @@
import {
View,
Text,
ScrollView,
TextInput,
KeyboardAvoidingView,
Platform,
ActivityIndicator,
} from "react-native";
import React, { useState } from "react";
import { useTailwind } from "tailwind-rn";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Divider, Button } from "@rneui/themed";
import { Formik } from "formik";
import MediaPicker from "../../../components/MediaPicker";
import Toast from "react-native-toast-message";
import { get } from "../../../utils/storeInfo";
import { multiUpload } from "../../../utils/upload";
import baseRequest from "../../../utils/baseRequest";
import { generateSignature } from "../../../utils/crypto";
export default function JoinStreamer({ navigation, route }) {
const tailwind = useTailwind();
const insets = useSafeAreaInsets();
//
const [accountImages, setAccountImages] = useState([]);
//
const [isSubmitting, setIsSubmitting] = useState(false);
//ScrollView
const [dragging, setDragging] = useState(false);
return (
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "height"}
keyboardVerticalOffset={insets.bottom + 60}
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
...tailwind("flex-1"),
}}
>
<ScrollView scrollEnabled={!dragging} style={tailwind("px-4 py-4")}>
<Formik
initialValues={{
name: "",
platforms: "",
contact: "",
}}
onSubmit={async (values) => {
if (
!values.name ||
!values.platforms ||
!values.contact ||
accountImages.length === 0
) {
Toast.show({
type: "error",
text1: "请完善信息后提交",
topOffset: 60,
});
return;
}
setIsSubmitting(true);
const account = await get("account");
const account_shot = await multiUpload(accountImages);
if (!account_shot.image_ids.length) {
Toast.show({
type: "error",
text1: "上传失败,请联系客服进行上传",
topOffset: 60,
});
setIsSubmitting(false);
return;
}
//
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
//
const base = await baseRequest();
const body = {
avatar: { image_ids: [account?.avatar.images[0].id] },
name: values.name,
contact_way: values.contact,
account_shot: account_shot,
main_platform: values.platforms,
...base,
};
const signature = await generateSignature(body);
try {
const response = await fetch(
`${apiUrl}/api/streamer_auth_approval/create_basic?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const streamerData = await response.json();
if (streamerData.ret === -1) {
Toast.show({
type: "error",
text1: streamerData.msg,
topOffset: 60,
});
return;
}
//
navigation.replace("AfterSubmitStreamerVerification");
} catch (error) {
console.error(error);
} finally {
setIsSubmitting(false);
}
}}
>
{({ handleChange, handleSubmit, values }) => (
<>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
审核资料仅用于审核不对外展示
</Text>
<View style={tailwind("my-2 bg-[#FFFFFF1A] p-2 rounded-2xl")}>
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
昵称
</Text>
<View
style={tailwind("flex-row flex-1 justify-end items-center")}
>
<TextInput
placeholder="请输入可搜索到您的昵称"
placeholderTextColor="#FFFFFF80"
style={tailwind("text-white flex-1")}
underlineColorAndroid="transparent"
textAlign="right"
onChangeText={handleChange("name")}
value={values.name}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
主营平台
</Text>
<View
style={tailwind("flex-row flex-1 justify-end items-center")}
>
<TextInput
placeholder="若有多个,按粉丝从多到少排序"
placeholderTextColor="#FFFFFF80"
style={tailwind("text-white flex-1")}
underlineColorAndroid="transparent"
textAlign="right"
onChangeText={handleChange("platforms")}
value={values.platforms}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
<View style={tailwind("flex-row justify-between items-center")}>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
联系方式
</Text>
<View
style={tailwind("flex-row flex-1 justify-end items-center")}
>
<TextInput
placeholder="注明方式,如“电话:xxxxx”"
placeholderTextColor="#FFFFFF80"
style={tailwind("text-white flex-1")}
underlineColorAndroid="transparent"
textAlign="right"
onChangeText={handleChange("contact")}
value={values.contact}
/>
</View>
</View>
<Divider style={tailwind("my-2")} />
<View>
<View
style={tailwind("flex-row justify-between items-center")}
>
<Text style={tailwind("text-base text-white font-medium")}>
<Text style={tailwind("text-[#F53030]")}>*</Text>
账号截图
</Text>
<Text
style={tailwind("text-xs text-[#FFFFFF80] font-medium")}
>
各平台账号截图最多9张
</Text>
</View>
<MediaPicker
setDragging={setDragging}
maxCount={9}
type="image"
setAssets={setAccountImages}
/>
</View>
</View>
<Button
color="#FF669E"
radius="999"
size="md"
disabled={isSubmitting}
disabledStyle={tailwind("bg-[#FFFFFF80]")}
disabledTitleStyle={tailwind("text-white")}
onPress={(e) => {
handleSubmit(e);
}}
titleStyle={tailwind("text-base")}
containerStyle={{
marginBottom: insets.bottom + 60,
...tailwind("mt-4"),
}}
>
{isSubmitting && (
<ActivityIndicator size="small" color="white" />
)}
{isSubmitting ? "正在提交..." : "提交"}
</Button>
</>
)}
</Formik>
</ScrollView>
</KeyboardAvoidingView>
);
}

View File

@ -1,8 +1,9 @@
import React from "react";
import { Text, TouchableOpacity } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import StreamerVerificationForm from "./StreamerVerificationForm";
import CompleteStreamerInformation from "./CompleteStreamerInformation";
import AfterSubmitStreamerVerification from "./AfterSubmitStreamerVerification";
import JoinStreamer from "./JoinStreamer";
import { Icon } from "@rneui/themed";
const StreamerVerificationStack = createNativeStackNavigator();
@ -11,8 +12,38 @@ export default function StreamerVerification() {
return (
<StreamerVerificationStack.Navigator>
<StreamerVerificationStack.Screen
name="StreamerVerificationForm"
component={StreamerVerificationForm}
name="JoinStreamer"
component={JoinStreamer}
options={({ navigation }) => ({
headerLeft: () => (
<Icon
type="ionicon"
name="chevron-back"
size={32}
color="white"
onPress={() => navigation.goBack()}
/>
),
headerRight: () => (
<TouchableOpacity
onPress={() =>
navigation.navigate("WebWithHeader", {
title: "申请入驻",
uri: `${process.env.EXPO_PUBLIC_WEB_URL}/doc/platformguidelines`,
})
}
>
<Text style={{ color: "#FF669E", fontSize: 16 }}>平台准则</Text>
</TouchableOpacity>
),
title: "申请入驻",
headerTitleStyle: { color: "white" },
headerStyle: { backgroundColor: "#07050A" },
})}
/>
<StreamerVerificationStack.Screen
name="CompleteStreamerInformation"
component={CompleteStreamerInformation}
options={({ navigation }) => ({
headerLeft: () => (
<Icon
@ -35,7 +66,7 @@ export default function StreamerVerification() {
<Text style={{ color: "#FF669E", fontSize: 16 }}>平台准则</Text>
</TouchableOpacity>
),
title: "申请入驻",
title: "完善信息",
headerTitleStyle: { color: "white" },
headerStyle: { backgroundColor: "#07050A" },
})}