599 lines
19 KiB
React
599 lines
19 KiB
React
|
import {
|
|||
|
View,
|
|||
|
Text,
|
|||
|
ScrollView,
|
|||
|
TouchableOpacity,
|
|||
|
TextInput,
|
|||
|
Modal,
|
|||
|
Alert,
|
|||
|
ActivityIndicator,
|
|||
|
} from "react-native";
|
|||
|
import React, { useState, useEffect } from "react";
|
|||
|
import { useTailwind } from "tailwind-rn";
|
|||
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|||
|
import { Button, Icon } from "@rneui/themed";
|
|||
|
import { Image } from "expo-image";
|
|||
|
import Picker from "../../components/Picker";
|
|||
|
import baseRequest from "../../utils/baseRequest";
|
|||
|
import { get } from "../../utils/storeInfo";
|
|||
|
import Toast from "react-native-toast-message";
|
|||
|
import { generateSignature } from "../../utils/crypto";
|
|||
|
|
|||
|
export default function EditPlatformOrder({ navigation, route }) {
|
|||
|
const tailwind = useTailwind();
|
|||
|
const insets = useSafeAreaInsets();
|
|||
|
|
|||
|
const [platform, setPlatform] = useState([]);
|
|||
|
const [allPlatforms, setAllPlatforms] = useState([]);
|
|||
|
|
|||
|
//正在加载数据
|
|||
|
const [isLoading, setIsloading] = useState(true);
|
|||
|
//获取现有平台数据
|
|||
|
useEffect(() => {
|
|||
|
const getAllPlatforms = async () => {
|
|||
|
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
|
|||
|
try {
|
|||
|
const base = await baseRequest();
|
|||
|
const signature = await generateSignature({
|
|||
|
...base,
|
|||
|
});
|
|||
|
//获取当前所有平台
|
|||
|
const detailResponse = await fetch(
|
|||
|
`${apiUrl}/api/platform/list?signature=${signature}`,
|
|||
|
{
|
|||
|
method: "POST",
|
|||
|
headers: {
|
|||
|
"Content-Type": "application/json",
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
...base,
|
|||
|
}),
|
|||
|
}
|
|||
|
);
|
|||
|
const detailData = await detailResponse.json();
|
|||
|
if (detailData.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
type: "error",
|
|||
|
text1: detailData.msg,
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
const detailDataValues = Object.entries(detailData.data);
|
|||
|
const temAllPlatforms = detailDataValues.map((item) => {
|
|||
|
return {
|
|||
|
label: item[1].name,
|
|||
|
value: {
|
|||
|
link_no: parseInt(item[0], 10),
|
|||
|
link_name: item[1].name,
|
|||
|
link_icon: item[1].icon,
|
|||
|
},
|
|||
|
};
|
|||
|
});
|
|||
|
setAllPlatforms(temAllPlatforms);
|
|||
|
//获取主播当前所有平台
|
|||
|
const account = await get("account");
|
|||
|
const signature2 = await generateSignature({
|
|||
|
mid: account?.mid,
|
|||
|
...base,
|
|||
|
});
|
|||
|
const streamerPlatformResponse = await fetch(
|
|||
|
`${apiUrl}/api/streamer_link/list_by_mid?signature=${signature2}`,
|
|||
|
{
|
|||
|
method: "POST",
|
|||
|
headers: {
|
|||
|
"Content-Type": "application/json",
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
mid: account?.mid,
|
|||
|
...base,
|
|||
|
}),
|
|||
|
}
|
|||
|
);
|
|||
|
const streamerPlatformData = await streamerPlatformResponse.json();
|
|||
|
if (streamerPlatformData.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
type: "error",
|
|||
|
text1: streamerPlatformData.msg,
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
const platformsWithIcon = streamerPlatformData.data.list.map((item) => {
|
|||
|
return {
|
|||
|
...item,
|
|||
|
link_icon: detailData.data[item.link_no].icon,
|
|||
|
};
|
|||
|
});
|
|||
|
setPlatform(platformsWithIcon);
|
|||
|
setIsloading(false);
|
|||
|
} catch (error) {
|
|||
|
console.error(error);
|
|||
|
}
|
|||
|
};
|
|||
|
getAllPlatforms();
|
|||
|
}, []);
|
|||
|
|
|||
|
//点击添加/编辑按钮涉及的state
|
|||
|
const [platformEditable, setPlatformEditable] = useState(true);
|
|||
|
const [addModalVisible, setAddModalVisible] = useState(false);
|
|||
|
const [selectedPlatform, setSelectedPlatform] = useState();
|
|||
|
const [nickname, setNickname] = useState();
|
|||
|
const [url, setUrl] = useState();
|
|||
|
|
|||
|
//点击关闭弹窗
|
|||
|
const handleCloseModal = () => {
|
|||
|
setAddModalVisible(false);
|
|||
|
setSelectedPlatform();
|
|||
|
setNickname();
|
|||
|
setUrl("");
|
|||
|
setPlatformEditable(true);
|
|||
|
};
|
|||
|
|
|||
|
//点击添加按钮
|
|||
|
const handleAdd = () => {
|
|||
|
if (!selectedPlatform || !nickname || !url) {
|
|||
|
Alert.alert(null, "请完整填写信息");
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!url.startsWith("https://")) {
|
|||
|
Alert.alert(null, "链接必须以https://开头");
|
|||
|
return;
|
|||
|
}
|
|||
|
const updatedPlatform = [...platform];
|
|||
|
const matched = updatedPlatform.filter(
|
|||
|
(item) => item.link_name === selectedPlatform.link_name
|
|||
|
);
|
|||
|
if (matched.length > 0) {
|
|||
|
updatedPlatform[updatedPlatform.indexOf(matched[0])] = {
|
|||
|
link_name: selectedPlatform.link_name,
|
|||
|
link_icon: selectedPlatform.link_icon,
|
|||
|
link_no: selectedPlatform.link_no,
|
|||
|
nickname: nickname,
|
|||
|
url: url,
|
|||
|
};
|
|||
|
} else {
|
|||
|
updatedPlatform.push({
|
|||
|
link_name: selectedPlatform.link_name,
|
|||
|
link_icon: selectedPlatform.link_icon,
|
|||
|
link_no: selectedPlatform.link_no,
|
|||
|
nickname: nickname,
|
|||
|
url: url,
|
|||
|
});
|
|||
|
}
|
|||
|
updatedPlatform.forEach((item, index) => (item.order = index + 1));
|
|||
|
setPlatform(updatedPlatform);
|
|||
|
handleCloseModal();
|
|||
|
};
|
|||
|
|
|||
|
//点击删除按钮
|
|||
|
const handleDelete = (item) => {
|
|||
|
const updatedPlatform = [...platform];
|
|||
|
const index = updatedPlatform.findIndex(
|
|||
|
(element) => element.link_name === item.link_name
|
|||
|
);
|
|||
|
updatedPlatform.splice(index, 1);
|
|||
|
updatedPlatform.forEach((item, index) => (item.order = index + 1));
|
|||
|
setPlatform(updatedPlatform);
|
|||
|
};
|
|||
|
|
|||
|
//点击编辑按钮
|
|||
|
const handleEdit = (item) => {
|
|||
|
setPlatformEditable(false);
|
|||
|
setAddModalVisible(true);
|
|||
|
setSelectedPlatform({
|
|||
|
link_name: item.link_name,
|
|||
|
link_icon: item.link_icon,
|
|||
|
link_no: item.link_no,
|
|||
|
});
|
|||
|
setNickname(item.nickname);
|
|||
|
setUrl(item.url);
|
|||
|
};
|
|||
|
|
|||
|
//点击上升按钮
|
|||
|
const handleIndexChangeUp = (item) => {
|
|||
|
if (item.order === 1) return;
|
|||
|
const updatedPlatform = [...platform];
|
|||
|
const index = updatedPlatform.findIndex(
|
|||
|
(element) => element.link_name === item.link_name
|
|||
|
);
|
|||
|
const temp = updatedPlatform[index];
|
|||
|
updatedPlatform[index] = updatedPlatform[index - 1];
|
|||
|
updatedPlatform[index - 1] = temp;
|
|||
|
updatedPlatform.forEach((item, index) => (item.order = index + 1));
|
|||
|
setPlatform(updatedPlatform);
|
|||
|
};
|
|||
|
|
|||
|
//点击下降按钮
|
|||
|
const handleIndexChangeDown = (item) => {
|
|||
|
if (item.order === platform.length) return;
|
|||
|
const updatedPlatform = [...platform];
|
|||
|
const index = updatedPlatform.findIndex(
|
|||
|
(element) => element.link_name === item.link_name
|
|||
|
);
|
|||
|
const temp = updatedPlatform[index];
|
|||
|
updatedPlatform[index] = updatedPlatform[index + 1];
|
|||
|
updatedPlatform[index + 1] = temp;
|
|||
|
updatedPlatform.forEach((item, index) => (item.order = index + 1));
|
|||
|
setPlatform(updatedPlatform);
|
|||
|
};
|
|||
|
|
|||
|
//正在提交状态
|
|||
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|||
|
|
|||
|
//点击提交按钮
|
|||
|
const handleSubmit = async () => {
|
|||
|
setIsSubmitting(true);
|
|||
|
const account = await get("account");
|
|||
|
const newPlatforms = platform.map((item) => ({
|
|||
|
mid: account.mid,
|
|||
|
link_no: item.link_no,
|
|||
|
link_name: item.link_name,
|
|||
|
url: item.url,
|
|||
|
order: item.order,
|
|||
|
nickname: item.nickname,
|
|||
|
}));
|
|||
|
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
|
|||
|
try {
|
|||
|
const base = await baseRequest();
|
|||
|
const signature = await generateSignature({
|
|||
|
mid: account?.mid,
|
|||
|
...base,
|
|||
|
});
|
|||
|
//获取主播当前所有平台
|
|||
|
const streamerPlatformResponse = await fetch(
|
|||
|
`${apiUrl}/api/streamer_link/list_by_mid?signature=${signature}`,
|
|||
|
{
|
|||
|
method: "POST",
|
|||
|
headers: {
|
|||
|
"Content-Type": "application/json",
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
mid: account?.mid,
|
|||
|
...base,
|
|||
|
}),
|
|||
|
}
|
|||
|
);
|
|||
|
const streamerPlatformData = await streamerPlatformResponse.json();
|
|||
|
if (streamerPlatformData.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
type: "error",
|
|||
|
text1: streamerPlatformData.msg,
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
//删除全部现有平台
|
|||
|
const ids = streamerPlatformData.data.list.map((item) => item.id);
|
|||
|
if (ids.length !== 0) {
|
|||
|
const signature2 = await generateSignature({
|
|||
|
ids: ids,
|
|||
|
...base,
|
|||
|
});
|
|||
|
const deleteResponse = await fetch(
|
|||
|
`${apiUrl}/api/streamer_link/delete_batch?signature=${signature2}`,
|
|||
|
{
|
|||
|
method: "POST",
|
|||
|
headers: {
|
|||
|
"Content-Type": "application/json",
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
ids: ids,
|
|||
|
...base,
|
|||
|
}),
|
|||
|
}
|
|||
|
);
|
|||
|
const deleteData = await deleteResponse.json();
|
|||
|
if (deleteData.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
type: "error",
|
|||
|
text1: deleteData.msg,
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
//批量创建新的平台
|
|||
|
if (newPlatforms.length === 0) {
|
|||
|
Toast.show({
|
|||
|
type: "success",
|
|||
|
text1: "更改成功",
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
const signature3 = await generateSignature({
|
|||
|
streamer_links: newPlatforms,
|
|||
|
...base,
|
|||
|
});
|
|||
|
const response = await fetch(
|
|||
|
`${apiUrl}/api/streamer_link/create_batch?signature=${signature3}`,
|
|||
|
{
|
|||
|
method: "POST",
|
|||
|
headers: {
|
|||
|
"Content-Type": "application/json",
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
streamer_links: newPlatforms,
|
|||
|
...base,
|
|||
|
}),
|
|||
|
}
|
|||
|
);
|
|||
|
const data = await response.json();
|
|||
|
if (data.ret === -1) {
|
|||
|
Toast.show({
|
|||
|
type: "error",
|
|||
|
text1: data.msg,
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
return;
|
|||
|
}
|
|||
|
Toast.show({
|
|||
|
type: "success",
|
|||
|
text1: "更改成功",
|
|||
|
topOffset: 60,
|
|||
|
});
|
|||
|
navigation.goBack();
|
|||
|
} catch (error) {
|
|||
|
console.error(error);
|
|||
|
} finally {
|
|||
|
setIsSubmitting(false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//按index从小到大排序
|
|||
|
const sortedPlatform = [...platform].sort((a, b) => a.order - b.order);
|
|||
|
|
|||
|
//loading时展示加载中
|
|||
|
if (isLoading) {
|
|||
|
return (
|
|||
|
<ActivityIndicator style={tailwind("mt-32")} size="large" color="white" />
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
return (
|
|||
|
<View style={tailwind("flex-1")}>
|
|||
|
<ScrollView
|
|||
|
style={{
|
|||
|
paddingBottom: insets.bottom,
|
|||
|
paddingLeft: insets.left,
|
|||
|
paddingRight: insets.right,
|
|||
|
...tailwind("flex-1"),
|
|||
|
}}
|
|||
|
>
|
|||
|
<View style={tailwind("p-4")}>
|
|||
|
<TouchableOpacity
|
|||
|
style={tailwind(
|
|||
|
"flex-row rounded-lg h-12 justify-center items-center border border-dashed border-white mb-4"
|
|||
|
)}
|
|||
|
onPress={() => setAddModalVisible(true)}
|
|||
|
>
|
|||
|
<Icon
|
|||
|
type="ionicon"
|
|||
|
name="add-outline"
|
|||
|
size={24}
|
|||
|
color="white"
|
|||
|
containerStyle={tailwind("mr-2")}
|
|||
|
/>
|
|||
|
<Text style={tailwind("text-base text-white font-medium")}>
|
|||
|
添加
|
|||
|
</Text>
|
|||
|
</TouchableOpacity>
|
|||
|
{sortedPlatform.map((item, index) => (
|
|||
|
<View
|
|||
|
key={index}
|
|||
|
style={tailwind("flex-row bg-[#13121F] rounded-lg mb-2 p-2")}
|
|||
|
>
|
|||
|
<View style={tailwind("flex-1")}>
|
|||
|
<View style={tailwind("flex-row items-center")}>
|
|||
|
<Text style={tailwind("text-base text-white font-medium")}>
|
|||
|
平台:
|
|||
|
</Text>
|
|||
|
<Image
|
|||
|
source={item?.link_icon?.images[0]?.urls[0]}
|
|||
|
style={{ aspectRatio: "1/1", ...tailwind("w-6 mx-1") }}
|
|||
|
/>
|
|||
|
<Text style={tailwind("text-base text-white font-medium")}>
|
|||
|
{item?.link_name}
|
|||
|
</Text>
|
|||
|
</View>
|
|||
|
<View style={tailwind("flex-row")}>
|
|||
|
<Text style={tailwind("text-base text-white font-medium")}>
|
|||
|
昵称:
|
|||
|
</Text>
|
|||
|
<Text
|
|||
|
style={tailwind(
|
|||
|
"text-base text-white font-medium ml-1 flex-1"
|
|||
|
)}
|
|||
|
>
|
|||
|
{item?.nickname}
|
|||
|
</Text>
|
|||
|
</View>
|
|||
|
<View style={tailwind("flex-row")}>
|
|||
|
<Text style={tailwind("text-base text-white font-medium")}>
|
|||
|
链接:
|
|||
|
</Text>
|
|||
|
<Text
|
|||
|
style={tailwind(
|
|||
|
"text-base text-white font-medium ml-1 flex-1"
|
|||
|
)}
|
|||
|
>
|
|||
|
{item?.url}
|
|||
|
</Text>
|
|||
|
</View>
|
|||
|
</View>
|
|||
|
<View style={tailwind("ml-2 items-end")}>
|
|||
|
<View style={tailwind("flex-row items-center")}>
|
|||
|
<Icon
|
|||
|
type="ionicon"
|
|||
|
name="trash-outline"
|
|||
|
size={24}
|
|||
|
color="white"
|
|||
|
onPress={() => handleDelete(item)}
|
|||
|
containerStyle={tailwind("mr-2")}
|
|||
|
/>
|
|||
|
<Icon
|
|||
|
type="ionicon"
|
|||
|
name="create-outline"
|
|||
|
size={24}
|
|||
|
color="white"
|
|||
|
onPress={() => handleEdit(item)}
|
|||
|
/>
|
|||
|
</View>
|
|||
|
<Icon
|
|||
|
type="ionicon"
|
|||
|
name="chevron-up-outline"
|
|||
|
size={30}
|
|||
|
color="white"
|
|||
|
onPress={() => handleIndexChangeUp(item)}
|
|||
|
containerStyle={tailwind("mt-4")}
|
|||
|
/>
|
|||
|
<Icon
|
|||
|
type="ionicon"
|
|||
|
name="chevron-down-outline"
|
|||
|
color="white"
|
|||
|
size={30}
|
|||
|
onPress={() => handleIndexChangeDown(item)}
|
|||
|
/>
|
|||
|
</View>
|
|||
|
</View>
|
|||
|
))}
|
|||
|
{/* 添加平台Modal */}
|
|||
|
<Modal
|
|||
|
visible={addModalVisible}
|
|||
|
transparent={true}
|
|||
|
statusBarTranslucent
|
|||
|
animationType="fade"
|
|||
|
>
|
|||
|
<TouchableOpacity
|
|||
|
activeOpacity={1}
|
|||
|
onPress={handleCloseModal}
|
|||
|
style={{
|
|||
|
backgroundColor: "#00000080",
|
|||
|
...tailwind("flex-1 justify-center items-center"),
|
|||
|
}}
|
|||
|
>
|
|||
|
<TouchableOpacity
|
|||
|
activeOpacity={1}
|
|||
|
style={tailwind("w-2/3 rounded-lg bg-[#1E1C29]")}
|
|||
|
>
|
|||
|
<View style={tailwind("w-full p-4")}>
|
|||
|
<Text
|
|||
|
style={tailwind(
|
|||
|
"text-lg text-white font-medium text-center mb-2"
|
|||
|
)}
|
|||
|
>
|
|||
|
编辑/添加平台
|
|||
|
</Text>
|
|||
|
<View style={tailwind("flex-row items-center my-1")}>
|
|||
|
<Text
|
|||
|
style={tailwind("text-base text-white font-medium mr-1")}
|
|||
|
>
|
|||
|
平台:
|
|||
|
</Text>
|
|||
|
{platformEditable ? (
|
|||
|
<View style={tailwind("w-1/2 ")}>
|
|||
|
<Picker
|
|||
|
items={allPlatforms}
|
|||
|
onChange={(value) => setSelectedPlatform(value)}
|
|||
|
/>
|
|||
|
</View>
|
|||
|
) : (
|
|||
|
<Text
|
|||
|
style={tailwind(
|
|||
|
"text-base text-white font-medium mr-1"
|
|||
|
)}
|
|||
|
>
|
|||
|
{selectedPlatform?.link_name}
|
|||
|
</Text>
|
|||
|
)}
|
|||
|
</View>
|
|||
|
<View style={tailwind("flex-row items-center my-1")}>
|
|||
|
<Text
|
|||
|
style={tailwind("text-base text-white font-medium mr-1")}
|
|||
|
>
|
|||
|
昵称:
|
|||
|
</Text>
|
|||
|
<TextInput
|
|||
|
placeholder="请输入昵称"
|
|||
|
placeholderTextColor="#FFFFFF80"
|
|||
|
underlineColorAndroid="transparent"
|
|||
|
onChangeText={(value) => setNickname(value)}
|
|||
|
value={nickname}
|
|||
|
style={tailwind(
|
|||
|
"flex-1 border border-[#2c2b2f] text-white font-medium rounded-lg h-10 px-2"
|
|||
|
)}
|
|||
|
/>
|
|||
|
</View>
|
|||
|
<View style={tailwind("flex-row my-1")}>
|
|||
|
<Text
|
|||
|
style={tailwind("text-base text-white font-medium mr-1")}
|
|||
|
>
|
|||
|
链接:
|
|||
|
</Text>
|
|||
|
<TextInput
|
|||
|
placeholder="请输入链接"
|
|||
|
placeholderTextColor="#FFFFFF80"
|
|||
|
multiline
|
|||
|
textAlignVertical="top"
|
|||
|
underlineColorAndroid="transparent"
|
|||
|
onChangeText={(value) => setUrl(value)}
|
|||
|
value={url}
|
|||
|
style={tailwind(
|
|||
|
"flex-1 border border-[#2c2b2f] text-white font-medium rounded-lg h-24 p-2"
|
|||
|
)}
|
|||
|
/>
|
|||
|
</View>
|
|||
|
</View>
|
|||
|
<View style={tailwind("flex-row justify-around")}>
|
|||
|
<TouchableOpacity
|
|||
|
onPress={handleAdd}
|
|||
|
style={tailwind(
|
|||
|
"border-r border-t border-[#2c2b2f] basis-1/2 py-2 justify-center items-center"
|
|||
|
)}
|
|||
|
>
|
|||
|
<Text style={tailwind("text-base text-white font-medium")}>
|
|||
|
确认
|
|||
|
</Text>
|
|||
|
</TouchableOpacity>
|
|||
|
<TouchableOpacity
|
|||
|
onPress={handleCloseModal}
|
|||
|
style={tailwind(
|
|||
|
"border-t border-[#2c2b2f] basis-1/2 py-2 justify-center items-center"
|
|||
|
)}
|
|||
|
>
|
|||
|
<Text style={tailwind("text-base text-gray-400")}>
|
|||
|
取消
|
|||
|
</Text>
|
|||
|
</TouchableOpacity>
|
|||
|
</View>
|
|||
|
</TouchableOpacity>
|
|||
|
</TouchableOpacity>
|
|||
|
</Modal>
|
|||
|
</View>
|
|||
|
</ScrollView>
|
|||
|
{/* 查看微信按钮 */}
|
|||
|
<View
|
|||
|
style={tailwind(
|
|||
|
"w-full h-12 px-4 absolute bottom-12 items-center justify-center"
|
|||
|
)}
|
|||
|
>
|
|||
|
<Button
|
|||
|
color="#FF669E"
|
|||
|
radius="999"
|
|||
|
size="md"
|
|||
|
disabled={isSubmitting}
|
|||
|
disabledStyle={tailwind("bg-[#FFFFFF80]")}
|
|||
|
disabledTitleStyle={tailwind("text-white")}
|
|||
|
onPress={handleSubmit}
|
|||
|
titleStyle={tailwind("text-base")}
|
|||
|
containerStyle={tailwind("w-full")}
|
|||
|
>
|
|||
|
{isSubmitting && <ActivityIndicator size="small" color="white" />}
|
|||
|
{isSubmitting ? "正在提交..." : "确认修改"}
|
|||
|
</Button>
|
|||
|
</View>
|
|||
|
</View>
|
|||
|
);
|
|||
|
}
|