|
|
|
import {
|
|
|
|
View,
|
|
|
|
StyleSheet,
|
|
|
|
Text,
|
|
|
|
ScrollView,
|
|
|
|
TouchableOpacity,
|
|
|
|
Image,
|
|
|
|
ActivityIndicator,
|
|
|
|
} from "react-native";
|
|
|
|
import { useRoute, RouteProp } from "@react-navigation/native";
|
|
|
|
import { productStatus } from "../../constants/productStatus";
|
|
|
|
import BackIcon from "../../components/BackIcon";
|
|
|
|
import MassageIcon from "../../components/MassageIcon";
|
|
|
|
import { useEffect, useState, useRef } from "react";
|
|
|
|
import fontSize from "../../utils/fontsizeUtils";
|
|
|
|
import widthUtils from "../../utils/widthUtils";
|
|
|
|
import {
|
|
|
|
ordersApi,
|
|
|
|
PaginatedOrderResponse,
|
|
|
|
PaginatedOrderRequest,
|
|
|
|
} from "../../services/api/orders";
|
|
|
|
import { useNavigation } from "@react-navigation/native";
|
|
|
|
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
|
|
|
|
// import ImageView from "react-native-image-viewing";
|
|
|
|
|
|
|
|
type StatusScreenRouteProp = RouteProp<
|
|
|
|
{
|
|
|
|
Status: { status: number };
|
|
|
|
},
|
|
|
|
"Status"
|
|
|
|
>;
|
|
|
|
|
|
|
|
export function Status() {
|
|
|
|
const navigation = useNavigation<NativeStackNavigationProp<any>>();
|
|
|
|
const route = useRoute<StatusScreenRouteProp>();
|
|
|
|
const [statusList, setStatusList] = useState(() => {
|
|
|
|
const initialList = [...productStatus];
|
|
|
|
initialList.unshift({
|
|
|
|
text: "全部",
|
|
|
|
status: null,
|
|
|
|
icon: BackIcon,
|
|
|
|
});
|
|
|
|
return initialList;
|
|
|
|
});
|
|
|
|
const [status, setStatus] = useState<number | null>(null);
|
|
|
|
const [orderList, setOrderList] = useState<PaginatedOrderResponse>();
|
|
|
|
const [page, setPage] = useState(1);
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
const [total, setTotal] = useState(0);
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const [imageViewerVisible, setImageViewerVisible] = useState(false);
|
|
|
|
const [currentImageIndex, setCurrentImageIndex] = useState(0);
|
|
|
|
const [images, setImages] = useState<string[]>([]);
|
|
|
|
const statusScrollViewRef = useRef<ScrollView>(null);
|
|
|
|
const statusItemRef = useRef<React.ElementRef<typeof TouchableOpacity>>(null);
|
|
|
|
|
|
|
|
const getAllOrders = async () => {
|
|
|
|
setLoading(true);
|
|
|
|
try {
|
|
|
|
const data = {
|
|
|
|
page: page,
|
|
|
|
page_size: pageSize,
|
|
|
|
};
|
|
|
|
const response = await ordersApi.getAllOrders(data);
|
|
|
|
setOrderList((prev) => ({
|
|
|
|
...response,
|
|
|
|
items:
|
|
|
|
page === 1
|
|
|
|
? response.items
|
|
|
|
: [...(prev?.items || []), ...response.items],
|
|
|
|
}));
|
|
|
|
setTotal(response.total);
|
|
|
|
} finally {
|
|
|
|
setLoading(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const scrollToStatus = () => {
|
|
|
|
const itemIndex = statusList.findIndex(
|
|
|
|
(item) => item.status === route.params.status
|
|
|
|
);
|
|
|
|
console.log(itemIndex);
|
|
|
|
statusItemRef.current?.measure((x, y, width, height, pageX, pageY) => {
|
|
|
|
if (width) {
|
|
|
|
statusScrollViewRef.current?.scrollTo({
|
|
|
|
x: width * (itemIndex - 1),
|
|
|
|
animated: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
useEffect(() => {
|
|
|
|
setStatus(route.params.status);
|
|
|
|
scrollToStatus();
|
|
|
|
setPage(1);
|
|
|
|
getAllOrders();
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const getStatus = (status: number) => {
|
|
|
|
return status === 0
|
|
|
|
? "待付款"
|
|
|
|
: status === 1
|
|
|
|
? "待发货"
|
|
|
|
: status === 2
|
|
|
|
? "待收货"
|
|
|
|
: status === 3
|
|
|
|
? "已完成"
|
|
|
|
: status === 4
|
|
|
|
? "已取消"
|
|
|
|
: status === 5
|
|
|
|
? "已退款"
|
|
|
|
: "未知状态";
|
|
|
|
};
|
|
|
|
|
|
|
|
// const handleImagePress = (imageUrl: string) => {
|
|
|
|
// setImages([imageUrl]);
|
|
|
|
// setCurrentImageIndex(0);
|
|
|
|
// setImageViewerVisible(true);
|
|
|
|
// };
|
|
|
|
|
|
|
|
const changeStatus = async (status: number) => {
|
|
|
|
setLoading(true);
|
|
|
|
setPage(1);
|
|
|
|
const data: PaginatedOrderRequest = {
|
|
|
|
page: page,
|
|
|
|
page_size: pageSize,
|
|
|
|
};
|
|
|
|
if (status) {
|
|
|
|
data.status = status;
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
const response = await ordersApi.getAllOrders(data);
|
|
|
|
setOrderList((prev) => ({
|
|
|
|
...response,
|
|
|
|
items:
|
|
|
|
page === 1
|
|
|
|
? response.items
|
|
|
|
: [...(prev?.items || []), ...response.items],
|
|
|
|
}));
|
|
|
|
// 滚动状态列表到选中项
|
|
|
|
} finally {
|
|
|
|
setLoading(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleOrderDetailsPress = (orderId: number) => {
|
|
|
|
navigation.navigate("OrderDetails", { orderId });
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<View style={styles.container}>
|
|
|
|
<View style={styles.statusHeader}>
|
|
|
|
<TouchableOpacity onPress={() => navigation.goBack()}>
|
|
|
|
<BackIcon />
|
|
|
|
</TouchableOpacity>
|
|
|
|
<Text style={styles.statusTitle}>订单状态</Text>
|
|
|
|
<MassageIcon size={26} />
|
|
|
|
</View>
|
|
|
|
<View style={styles.statusList}>
|
|
|
|
<ScrollView
|
|
|
|
ref={statusScrollViewRef}
|
|
|
|
style={styles.statusListScr}
|
|
|
|
horizontal={true}
|
|
|
|
pagingEnabled={false}
|
|
|
|
showsHorizontalScrollIndicator={false}
|
|
|
|
>
|
|
|
|
{statusList.map((item, index) => (
|
|
|
|
<TouchableOpacity
|
|
|
|
ref={statusItemRef}
|
|
|
|
style={[
|
|
|
|
styles.statusItem,
|
|
|
|
status === item.status ? styles.statusItemActive : null,
|
|
|
|
]}
|
|
|
|
key={index}
|
|
|
|
onPress={() => {
|
|
|
|
setStatus(item.status as number);
|
|
|
|
changeStatus(item.status as number);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<Text
|
|
|
|
style={[
|
|
|
|
styles.statusItemText,
|
|
|
|
status === item.status ? styles.statusItemActiveText : null,
|
|
|
|
]}
|
|
|
|
>
|
|
|
|
{item.text}
|
|
|
|
</Text>
|
|
|
|
</TouchableOpacity>
|
|
|
|
))}
|
|
|
|
</ScrollView>
|
|
|
|
</View>
|
|
|
|
|
|
|
|
<View style={styles.orderContent}>
|
|
|
|
{loading && page === 1 ? (
|
|
|
|
<View style={styles.loadingContainer}>
|
|
|
|
<ActivityIndicator size="large" color="#f77f3a" />
|
|
|
|
</View>
|
|
|
|
) : (
|
|
|
|
<ScrollView
|
|
|
|
horizontal={false}
|
|
|
|
showsVerticalScrollIndicator={false}
|
|
|
|
scrollEventThrottle={16}
|
|
|
|
onMomentumScrollEnd={(event) => {
|
|
|
|
const { contentOffset, contentSize, layoutMeasurement } =
|
|
|
|
event.nativeEvent;
|
|
|
|
const isAtBottom =
|
|
|
|
contentOffset.y + layoutMeasurement.height >=
|
|
|
|
contentSize.height;
|
|
|
|
|
|
|
|
if (isAtBottom) {
|
|
|
|
setLoading(true);
|
|
|
|
setPage(page + 1);
|
|
|
|
getAllOrders();
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{orderList?.items.map((item, index) => (
|
|
|
|
<View style={styles.orderItem} key={index}>
|
|
|
|
<View style={styles.orderStatus}>
|
|
|
|
<Text style={styles.orderStatusOrderText}>
|
|
|
|
{item.order_id}
|
|
|
|
</Text>
|
|
|
|
<Text style={styles.orderStatusText}>
|
|
|
|
{getStatus(item.order_status)}
|
|
|
|
</Text>
|
|
|
|
</View>
|
|
|
|
<View style={styles.orderProductList}>
|
|
|
|
{item.items.map((item, index) => (
|
|
|
|
<View style={styles.orderProductItem} key={index}>
|
|
|
|
<TouchableOpacity style={styles.orderProductItemImage}>
|
|
|
|
<Image
|
|
|
|
source={{ uri: item.product_image }}
|
|
|
|
style={styles.orderProductItemImage}
|
|
|
|
/>
|
|
|
|
</TouchableOpacity>
|
|
|
|
<View style={styles.orderProductItemInfo}>
|
|
|
|
<Text style={styles.orderProductItemInfoName}>
|
|
|
|
{item.product_name}
|
|
|
|
</Text>
|
|
|
|
{item.sku_attributes?.map((attr, index) => (
|
|
|
|
<Text
|
|
|
|
style={styles.orderProductItemInfoPrice}
|
|
|
|
key={index}
|
|
|
|
>
|
|
|
|
{attr.attribute_name}:{attr.attribute_value}
|
|
|
|
</Text>
|
|
|
|
))}
|
|
|
|
</View>
|
|
|
|
</View>
|
|
|
|
))}
|
|
|
|
</View>
|
|
|
|
<View style={styles.orderProductPrice}>
|
|
|
|
<View style={styles.orderProductPriceItem}>
|
|
|
|
<Text style={styles.orderProductTotalText}>商品总价:</Text>
|
|
|
|
<Text style={styles.orderProductPriceText}>
|
|
|
|
{item.actual_amount}
|
|
|
|
</Text>
|
|
|
|
</View>
|
|
|
|
<TouchableOpacity
|
|
|
|
style={styles.orderProductView}
|
|
|
|
onPress={() => handleOrderDetailsPress(item.order_id)}
|
|
|
|
>
|
|
|
|
<Text style={styles.orderProductViewText}>
|
|
|
|
View Details
|
|
|
|
</Text>
|
|
|
|
</TouchableOpacity>
|
|
|
|
</View>
|
|
|
|
</View>
|
|
|
|
))}
|
|
|
|
{loading && page > 1 && (
|
|
|
|
<View style={styles.loadingMoreContainer}>
|
|
|
|
<ActivityIndicator size="small" color="#f77f3a" />
|
|
|
|
</View>
|
|
|
|
)}
|
|
|
|
</ScrollView>
|
|
|
|
)}
|
|
|
|
</View>
|
|
|
|
{/* <ImageView
|
|
|
|
images={images.map(uri => ({ uri }))}
|
|
|
|
imageIndex={currentImageIndex}
|
|
|
|
visible={imageViewerVisible}
|
|
|
|
onRequestClose={() => setImageViewerVisible(false)}
|
|
|
|
swipeToCloseEnabled={true}
|
|
|
|
doubleTapToZoomEnabled={true}
|
|
|
|
/> */}
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
|
container: {
|
|
|
|
flex: 1,
|
|
|
|
backgroundColor: "#f3f3f3",
|
|
|
|
},
|
|
|
|
statusHeader: {
|
|
|
|
width: "100%",
|
|
|
|
backgroundColor: "white",
|
|
|
|
padding: 16,
|
|
|
|
justifyContent: "space-between",
|
|
|
|
flexDirection: "row",
|
|
|
|
alignItems: "center",
|
|
|
|
},
|
|
|
|
statusTitle: {
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
fontWeight: "600",
|
|
|
|
},
|
|
|
|
statusList: {
|
|
|
|
width: "100%",
|
|
|
|
borderTopWidth: 1,
|
|
|
|
borderColor: "#f5f5f5",
|
|
|
|
},
|
|
|
|
statusListScr: {
|
|
|
|
width: "100%",
|
|
|
|
},
|
|
|
|
statusItem: {
|
|
|
|
width: widthUtils(100,100).width,
|
|
|
|
padding: 16,
|
|
|
|
backgroundColor: "white",
|
|
|
|
},
|
|
|
|
statusItemText: {
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
textAlign: "center",
|
|
|
|
},
|
|
|
|
statusItemTextActive: {
|
|
|
|
color: "#f77f3a",
|
|
|
|
borderBottomWidth: 1,
|
|
|
|
borderColor: "#f77f3a",
|
|
|
|
},
|
|
|
|
statusItemActive: {
|
|
|
|
borderBottomWidth: 2,
|
|
|
|
borderColor: "#f77f3a",
|
|
|
|
},
|
|
|
|
statusItemActiveText: {
|
|
|
|
color: "#f77f3a",
|
|
|
|
},
|
|
|
|
orderContent: {
|
|
|
|
padding: 20,
|
|
|
|
flex: 1,
|
|
|
|
},
|
|
|
|
orderItem: {
|
|
|
|
width: "100%",
|
|
|
|
backgroundColor: "white",
|
|
|
|
borderRadius: 10,
|
|
|
|
marginBottom: 10,
|
|
|
|
},
|
|
|
|
orderStatus: {
|
|
|
|
width: "100%",
|
|
|
|
padding: 10,
|
|
|
|
borderBottomWidth: 1,
|
|
|
|
flexDirection: "row",
|
|
|
|
borderColor: "#f5f5f5",
|
|
|
|
justifyContent: "space-between",
|
|
|
|
},
|
|
|
|
orderStatusOrderText: {
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
fontWeight: "600",
|
|
|
|
},
|
|
|
|
orderStatusText: {
|
|
|
|
color: "#f77f3a",
|
|
|
|
},
|
|
|
|
orderProductList: {
|
|
|
|
width: "100%",
|
|
|
|
padding: 10,
|
|
|
|
},
|
|
|
|
orderProductItem: {
|
|
|
|
flexDirection: "row",
|
|
|
|
paddingBottom: 10,
|
|
|
|
paddingTop: 10,
|
|
|
|
borderBottomWidth: 1,
|
|
|
|
borderColor: "#f5f5f5",
|
|
|
|
},
|
|
|
|
orderProductItemImage: {
|
|
|
|
width: widthUtils(30,30).width,
|
|
|
|
height: widthUtils(30,30).height,
|
|
|
|
marginRight: 10,
|
|
|
|
},
|
|
|
|
orderProductItemInfo: {
|
|
|
|
flex: 1,
|
|
|
|
},
|
|
|
|
orderProductItemInfoName: {
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
fontWeight: "600",
|
|
|
|
},
|
|
|
|
orderProductItemInfoPrice: {
|
|
|
|
fontSize: fontSize(14),
|
|
|
|
color: "#666",
|
|
|
|
},
|
|
|
|
orderProductPrice: {
|
|
|
|
padding: 10,
|
|
|
|
flexDirection: "row",
|
|
|
|
justifyContent: "space-between",
|
|
|
|
},
|
|
|
|
orderProductView: {
|
|
|
|
padding: 5,
|
|
|
|
borderRadius: 8,
|
|
|
|
borderWidth: 1,
|
|
|
|
borderColor: "#f77f3a",
|
|
|
|
},
|
|
|
|
orderProductViewText: {
|
|
|
|
color: "#f77f3a",
|
|
|
|
fontSize: fontSize(14),
|
|
|
|
},
|
|
|
|
orderProductPriceText: {
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
fontWeight: "600",
|
|
|
|
color: "#f77f3a",
|
|
|
|
},
|
|
|
|
orderProductTotalText: {
|
|
|
|
fontSize: fontSize(16),
|
|
|
|
fontWeight: "600",
|
|
|
|
},
|
|
|
|
orderProductPriceItem: {
|
|
|
|
flexDirection: "row",
|
|
|
|
},
|
|
|
|
loadingContainer: {
|
|
|
|
flex: 1,
|
|
|
|
justifyContent: "center",
|
|
|
|
alignItems: "center",
|
|
|
|
},
|
|
|
|
loadingMoreContainer: {
|
|
|
|
paddingVertical: 10,
|
|
|
|
alignItems: "center",
|
|
|
|
},
|
|
|
|
});
|