Browse Source

改成https

main
Mac 4 weeks ago
parent
commit
0fb5fe6c15
  1. 2
      app.json
  2. 5
      app/constants/config.ts
  3. 7
      app/screens/HomeScreen.tsx
  4. 4
      app/screens/LoginScreen.tsx
  5. 164
      app/screens/ProductCard.tsx
  6. 13
      app/screens/ProductDetailScreen.tsx
  7. 8
      app/services/api/addressApi.ts
  8. 108
      app/services/api/apiClient.ts
  9. 10
      app/services/api/cart.ts
  10. 20
      app/services/api/orders.ts
  11. 4
      app/services/api/payApi.ts
  12. 4
      app/services/api/productApi.ts
  13. 12
      app/services/api/setting.ts
  14. 10
      app/services/api/userApi.ts
  15. BIN
      assets/img/banner en (3)_compressed.png
  16. BIN
      assets/img/banner en (4)_compressed.png
  17. BIN
      assets/img/banner en (5)_compressed.png
  18. 12080
      package-lock.json
  19. 6
      package.json
  20. 5176
      yarn.lock

2
app.json

@ -27,6 +27,8 @@
} }
}, },
"android": { "android": {
"permissions": ["INTERNET", "ACCESS_NETWORK_STATE"],
"usesCleartextTraffic": true,
"adaptiveIcon": { "adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png", "foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"

5
app/constants/config.ts

@ -1,5 +1,8 @@
// API配置 // API配置
export const API_BASE_URL = 'http://ec2-13-245-224-109.af-south-1.compute.amazonaws.com:8080/'; // 替换为您的实际API基础URL const DEV_API_URL = 'https://api.brainnel.com/backend';
const PROD_API_URL = 'https://api.brainnel.com/backend';
export const API_BASE_URL = PROD_API_URL
// 环境变量配置 // 环境变量配置
export const ENV = { export const ENV = {

7
app/screens/HomeScreen.tsx

@ -69,16 +69,15 @@ export const HomeScreen = () => {
page: 1, page: 1,
page_size: 20, page_size: 20,
sort_order: "desc", sort_order: "desc",
category_id: null,
sort_by: "default", sort_by: "default",
language: "en", language: "en",
}); });
const [products, setProducts] = useState<Product[]>([]); const [products, setProducts] = useState<Product[]>([]);
const flatListRef = useRef<FlatList>(null); const flatListRef = useRef<FlatList>(null);
const data = [ const data = [
{ imgUrl: require("../../assets/img/banner en (5).png"),add:'TikTokScreen' }, { imgUrl: require("../../assets/img/banner en (5)_compressed.png"),add:'TikTokScreen' },
{ imgUrl: require("../../assets/img/banner en (3).png"),add:'MemberIntroduction' }, { imgUrl: require("../../assets/img/banner en (3)_compressed.png"),add:'MemberIntroduction' },
{ imgUrl: require("../../assets/img/banner en (4).png"),add:'CompanyScreen' }, { imgUrl: require("../../assets/img/banner en (4)_compressed.png"),add:'CompanyScreen' },
]; ];
const getProductData = async () => { const getProductData = async () => {

4
app/screens/LoginScreen.tsx

@ -341,8 +341,8 @@ export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
if (res.access_token) { if (res.access_token) {
const token = res.token_type + " " + res.access_token; const token = res.token_type + " " + res.access_token;
await AsyncStorage.setItem("token", token); await AsyncStorage.setItem("token", token);
const data = await settingApi.postFirstLogin(221); // const data = await settingApi.postFirstLogin(221);
setSettings(data); // setSettings(data);
const user = await userApi.getProfile() const user = await userApi.getProfile()
setUser(user); setUser(user);
navigation.navigate("MainTabs", { screen: "Home" }); navigation.navigate("MainTabs", { screen: "Home" });

164
app/screens/ProductCard.tsx

@ -286,84 +286,86 @@ const ProductCard: React.FC<ProductCardProps> = ({
<View style={styles.productTit}> <View style={styles.productTit}>
<Text style={styles.productTitText}>{sizeTitle}</Text> <Text style={styles.productTitText}>{sizeTitle}</Text>
</View> </View>
<ScrollView <View style={{ flex: 1 }}>
style={styles.sizePrice} <ScrollView
showsHorizontalScrollIndicator={false} style={styles.sizePrice}
showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false}
> showsVerticalScrollIndicator={false}
<View style={styles.sizePriceBox}> >
{hasImg && <View style={styles.sizePriceBox}>
hasImg.attributes {hasImg &&
?.find((item) => item.has_color) hasImg.attributes
?.list.map((list, index1) => ( ?.find((item) => item.has_color)
<View style={styles.sizePriceBoxItems} key={index1}> ?.list.map((list, index1) => (
<View style={styles.sizePriceBoxItem}> <View style={styles.sizePriceBoxItems} key={index1}>
<View style={styles.sizePriceBoxItemTextBox}> <View style={styles.sizePriceBoxItem}>
{(list?.size ?? 0) > 0 && ( <View style={styles.sizePriceBoxItemTextBox}>
<Text style={styles.selectedNumText}> {(list?.size ?? 0) > 0 && (
x{list?.size} <Text style={styles.selectedNumText}>
x{list?.size}
</Text>
)}
<Text style={styles.priceText}>
{list.offer_price || price}
</Text> </Text>
)} <Text
<Text style={styles.priceText}> style={styles.sizePriceBoxItemText}
{list.offer_price || price} numberOfLines={1}
ellipsizeMode="tail"
>
{list.attributes[0].value}
</Text>
</View>
<Text style={styles.amountText}>
{list?.amount_on_sale}
</Text> </Text>
<Text </View>
style={styles.sizePriceBoxItemText} <View style={styles.sizePriceBoxStepForward}>
numberOfLines={1} <TouchableOpacity
ellipsizeMode="tail" style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"-",
index1,
list.amount_on_sale
)
}
> >
{list.attributes[0].value} <Text>-</Text>
</Text> </TouchableOpacity>
<TextInput
style={styles.sizePriceBoxStepForwardInput}
value={list.size?.toString() ?? "0"}
keyboardType="numeric"
onChangeText={(text) =>
handleSizeSelect(
list?.attributes[0]?.value,
text,
index1,
list.amount_on_sale
)
}
/>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"+",
index1,
list.amount_on_sale
)
}
>
<Text>+</Text>
</TouchableOpacity>
</View> </View>
<Text style={styles.amountText}>
{list?.amount_on_sale}
</Text>
</View>
<View style={styles.sizePriceBoxStepForward}>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"-",
index1,
list.amount_on_sale
)
}
>
<Text>-</Text>
</TouchableOpacity>
<TextInput
style={styles.sizePriceBoxStepForwardInput}
value={list.size?.toString() ?? "0"}
keyboardType="numeric"
onChangeText={(text) =>
handleSizeSelect(
list?.attributes[0]?.value,
text,
index1,
list.amount_on_sale
)
}
/>
<TouchableOpacity
style={styles.sizePriceBoxStepForwardButton}
onPress={() =>
handleSizeSelect(
list?.attributes[0]?.value,
"+",
index1,
list.amount_on_sale
)
}
>
<Text>+</Text>
</TouchableOpacity>
</View> </View>
</View> ))}
))} </View>
</View> </ScrollView>
</ScrollView> </View>
</View> </View>
)} )}
{/* 两个都是文字 */} {/* 两个都是文字 */}
@ -397,7 +399,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
<Text style={styles.productTitText}>{sizeTitle}</Text> <Text style={styles.productTitText}>{sizeTitle}</Text>
</View> </View>
<ScrollView <ScrollView
style={styles.sizePrice} style={[styles.sizePrice, { maxHeight: 200 }]}
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
> >
@ -483,7 +485,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
<Text style={styles.productTitText}>{sizeTitle}</Text> <Text style={styles.productTitText}>{sizeTitle}</Text>
</View> </View>
<ScrollView <ScrollView
style={styles.sizePriceBox} style={[styles.sizePrice, { maxHeight: 200 }]}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
> >
{noImgList && {noImgList &&
@ -565,7 +567,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
<Text style={styles.productTitText}>{sizeTitle}</Text> <Text style={styles.productTitText}>{sizeTitle}</Text>
</View> </View>
<ScrollView <ScrollView
style={styles.sizePriceBox} style={[styles.sizePrice, { maxHeight: 200 }]}
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
> >
@ -846,6 +848,8 @@ const styles = StyleSheet.create({
productBox: { productBox: {
marginTop: 10, marginTop: 10,
flex: 1, flex: 1,
display: 'flex',
flexDirection: 'column',
}, },
productTit: { productTit: {
flexDirection: "row", flexDirection: "row",
@ -885,11 +889,13 @@ const styles = StyleSheet.create({
height: "100%", height: "100%",
borderRadius: 10, borderRadius: 10,
}, },
sizePrice: {}, sizePrice: {
flex: 1,
width: '100%',
},
sizePriceBox: { sizePriceBox: {
width: "100%", width: "100%",
height: "100%", paddingBottom: 10,
flex: 1,
}, },
sizePriceBoxItem: { sizePriceBoxItem: {
width: "70%", width: "70%",

13
app/screens/ProductDetailScreen.tsx

@ -248,9 +248,12 @@ export const ProductDetailScreen = () => {
}; };
const getProductDetail = async () => { const getProductDetail = async () => {
if (!route.params?.offer_id) return; if (!route.params?.offer_id) return;
const startTime = Date.now();
console.log('开始时间:', startTime);
setIsLoading(true); setIsLoading(true);
try { try {
const res = await productApi.getProductDetail(route.params.offer_id); const res = await productApi.getProductDetail(route.params.offer_id);
console.log('API 请求完成');
if (res.skus != null) { if (res.skus != null) {
const priceSelectedSku = res.skus.find( const priceSelectedSku = res.skus.find(
(item) => item.offer_price === route.params.price (item) => item.offer_price === route.params.price
@ -294,10 +297,14 @@ export const ProductDetailScreen = () => {
const limitedImageUrls = imageUrls.length > 5 ? imageUrls.slice(0, 5) : imageUrls; const limitedImageUrls = imageUrls.length > 5 ? imageUrls.slice(0, 5) : imageUrls;
setImageUrls(limitedImageUrls); setImageUrls(limitedImageUrls);
setGroupList(list); setGroupList(list);
console.log('数据处理完成');
} catch (error) { } catch (error) {
console.error("Error fetching product details:", error); console.error("Error fetching product details:", error);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
const endTime = Date.now();
console.log('结束时间:', endTime);
console.log('总执行时间:', endTime - startTime, '毫秒');
} }
}; };
const getSimilars = () => { const getSimilars = () => {
@ -348,11 +355,7 @@ export const ProductDetailScreen = () => {
}, },
[navigation] [navigation]
); );
useEffect(() => {
if (showBottomSheet) {
console.log(123);
}
}, [showBottomSheet])
return ( return (
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
{isLoading ? ( {isLoading ? (

8
app/services/api/addressApi.ts

@ -38,20 +38,20 @@ export interface addressData {
export const addressApi = { export const addressApi = {
getAddress: () => { getAddress: () => {
return apiService.get<Address>("/api/addresses"); return apiService.get<Address>("/api/addresses/");
}, },
postAddress: (data: any) => { postAddress: (data: any) => {
return apiService.post("/api/addresses", data ); return apiService.post("/api/addresses/", data );
}, },
addressesDefault: () => { addressesDefault: () => {
return apiService.get<addressData>("/api/addresses/default/"); return apiService.get<addressData>("/api/addresses/default/");
}, },
updateAddress: (data: any) => { updateAddress: (data: any) => {
return apiService.put(`/api/addresses/${data.address_id}`, data); return apiService.put(`/api/addresses/${data.address_id}/`, data);
}, },
deleteAddress: (address_id: number) => { deleteAddress: (address_id: number) => {
return apiService.delete(`/api/addresses/${address_id}`); return apiService.delete(`/api/addresses/${address_id}/`);
}, },
}; };

108
app/services/api/apiClient.ts

@ -11,6 +11,9 @@ import {
DEFAULT_HEADERS, DEFAULT_HEADERS,
STORAGE_KEYS, STORAGE_KEYS,
} from "../../constants/config"; } from "../../constants/config";
import { Platform } from "react-native";
// import https from 'https';
// import { Platform } from "react-native";
// 定义响应类型接口 // 定义响应类型接口
export interface ApiResponse<T = any> { export interface ApiResponse<T = any> {
@ -27,6 +30,12 @@ export interface ApiError {
data?: any; data?: any;
} }
// 扩展 AxiosRequestConfig 类型
interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
retry?: number;
retryDelay?: (retryCount: number) => number;
}
// 创建axios实例 // 创建axios实例
const apiClient: AxiosInstance = axios.create({ const apiClient: AxiosInstance = axios.create({
baseURL: API_BASE_URL, baseURL: API_BASE_URL,
@ -34,11 +43,26 @@ const apiClient: AxiosInstance = axios.create({
headers: DEFAULT_HEADERS, headers: DEFAULT_HEADERS,
}); });
// if (__DEV__ && Platform.OS === "android") {
// apiClient.defaults.httpsAgent = new https.Agent({ rejectUnauthorized: false });
// }
// 请求拦截器 // 请求拦截器
apiClient.interceptors.request.use( apiClient.interceptors.request.use(
async (config: InternalAxiosRequestConfig) => { async (config: InternalAxiosRequestConfig) => {
const fullUrl = `${config.baseURL}${config.url}`; const baseUrl = config.baseURL || '';
console.log("完整请求地址:", fullUrl); // 例如: https://api.example.com/api/user let fullUrl = baseUrl + config.url;
if (config.params) {
const params = new URLSearchParams(config.params);
fullUrl += (fullUrl.includes('?') ? '&' : '?') + params.toString();
}
// console.log("环境:", __DEV__ ? "开发环境" : "生产环境");
// console.log("平台:", Platform.OS);
// console.log("请求方法:", config.method);
// console.log("完整URL:", fullUrl);
// console.log("请求头:", config.headers);
// console.log("请求参数:", config.params);
// console.log("请求数据:", config.data);
// 从AsyncStorage获取token // 从AsyncStorage获取token
const token = await AsyncStorage.getItem("token"); const token = await AsyncStorage.getItem("token");
@ -49,6 +73,7 @@ apiClient.interceptors.request.use(
return config; return config;
}, },
(error: AxiosError) => { (error: AxiosError) => {
console.error("请求拦截器错误:", error);
return Promise.reject(error); return Promise.reject(error);
} }
); );
@ -57,19 +82,53 @@ apiClient.interceptors.request.use(
apiClient.interceptors.response.use( apiClient.interceptors.response.use(
(response: AxiosResponse) => { (response: AxiosResponse) => {
// 成功响应处理 // 成功响应处理
// console.log("响应成功:", {
// status: response.status,
// statusText: response.statusText,
// headers: response.headers,
// data: response.data,
// });
return response; return response;
}, },
async (error: AxiosError<any>) => { async (error: AxiosError<any>) => {
// 错误响应处理 // 错误响应处理
const { response } = error; const { response, config } = error;
console.error("响应错误:", {
status: response?.status,
statusText: response?.statusText,
data: response?.data,
url: config?.url,
method: config?.method,
message: error.message,
code: error.code,
stack: error.stack,
});
// 处理网络错误
if (!response) {
console.error("网络错误:", {
message: error.message,
code: error.code,
stack: error.stack,
});
// 如果是网络错误,尝试重试
const customConfig = config as CustomAxiosRequestConfig;
if (customConfig && customConfig.retry) {
customConfig.retry -= 1;
if (customConfig.retry > 0) {
const delay = customConfig.retryDelay ? customConfig.retryDelay(customConfig.retry) : 1000;
console.log(`重试请求 (${customConfig.retry}): ${customConfig.url}`);
await new Promise(resolve => setTimeout(resolve, delay));
return apiClient(customConfig);
}
}
}
// 处理401错误 (未授权) // 处理401错误 (未授权)
if (response && response.status === 401) { if (response && response.status === 401) {
// 清除存储的token console.log("未授权错误,清除token");
await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN); await AsyncStorage.removeItem(STORAGE_KEYS.AUTH_TOKEN);
// 这里可以添加重定向到登录页面的逻辑
// 例如使用事件发射器或全局状态管理
} }
// 构建标准化的错误对象 // 构建标准化的错误对象
@ -88,7 +147,12 @@ export const apiService = {
// GET请求 // GET请求
async get<T>(url: string, params?: any, config?: any): Promise<T> { async get<T>(url: string, params?: any, config?: any): Promise<T> {
try { try {
const response = await apiClient.get<T>(url, { params, ...config }); const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.get<T>(url, { params, ...customConfig });
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@ -98,7 +162,12 @@ export const apiService = {
// POST请求 // POST请求
async post<T>(url: string, data?: any, config?: any): Promise<T> { async post<T>(url: string, data?: any, config?: any): Promise<T> {
try { try {
const response = await apiClient.post<T>(url, data, config); const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.post<T>(url, data, customConfig);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@ -108,7 +177,12 @@ export const apiService = {
// PUT请求 // PUT请求
async put<T>(url: string, data?: any, config?: any): Promise<T> { async put<T>(url: string, data?: any, config?: any): Promise<T> {
try { try {
const response = await apiClient.put<T>(url, data, config); const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.put<T>(url, data, customConfig);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@ -118,7 +192,12 @@ export const apiService = {
// PATCH请求 // PATCH请求
async patch<T>(url: string, data?: any, config?: any): Promise<T> { async patch<T>(url: string, data?: any, config?: any): Promise<T> {
try { try {
const response = await apiClient.patch<T>(url, data, config); const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.patch<T>(url, data, customConfig);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@ -128,7 +207,12 @@ export const apiService = {
// DELETE请求 // DELETE请求
async delete<T>(url: string, config?: any): Promise<T> { async delete<T>(url: string, config?: any): Promise<T> {
try { try {
const response = await apiClient.delete<T>(url, config); const customConfig: CustomAxiosRequestConfig = {
...config,
retry: 3,
retryDelay: (retryCount) => retryCount * 1000,
};
const response = await apiClient.delete<T>(url, customConfig);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;

10
app/services/api/cart.ts

@ -50,23 +50,23 @@ export interface GetCartList {
skus:CartSku[] skus:CartSku[]
} }
export const cartApi = (data: AddToCartParams) => { export const cartApi = (data: AddToCartParams) => {
return apiService.post('/api/cart', data); return apiService.post('/api/cart/', data);
} }
export const getCartList = () => { export const getCartList = () => {
return apiService.get<GetCartListResponse>('/api/cart'); return apiService.get<GetCartListResponse>('https://api.brainnel.com/backend/api/cart/');
} }
export const updateCartItem = (cart_id:number,data?:{cart_item_id?:number | null,selected:number | null,quantity:number | null}) => { export const updateCartItem = (cart_id:number,data?:{cart_item_id?:number | null,selected:number | null,quantity:number | null}) => {
return apiService.put(`/api/cart/${cart_id}`,data); return apiService.put(`/api/cart/${cart_id}/`,data);
} }
// 批量更新选中状态 // 批量更新选中状态
export const updateBatchCartSelected = (data?:{cart_id?:number | null,selected:number | null,offer_ids:Array<number> | null}) => { export const updateBatchCartSelected = (data?:{cart_id?:number | null,selected:number | null,offer_ids:Array<number> | null}) => {
return apiService.patch(`/api/cart/selected`,data); return apiService.patch(`/api/cart/selected/`,data);
} }
export const deleteCartItem = (cart_id:number,cart_item_id:number) => { export const deleteCartItem = (cart_id:number,cart_item_id:number) => {
return apiService.delete(`/api/cart/${cart_id}?cart_item_id=${cart_item_id}`); return apiService.delete(`/api/cart/${cart_id}/?cart_item_id=${cart_item_id}`);
} }

20
app/services/api/orders.ts

@ -339,43 +339,43 @@ interface Address {
} }
} }
export const ordersApi = { export const ordersApi = {
getOrders: (data:OrderPreviewData) => apiService.post<OrderData>("/api/orders/preview",data), getOrders: (data:OrderPreviewData) => apiService.post<OrderData>("/api/orders/preview/",data),
// 获得价格 // 获得价格
freightForwarderAddress: (transport_mode:number | null) => freightForwarderAddress: (transport_mode:number | null) =>
apiService.get<AddressDataItem>(`/api/freight_forwarder_address/?transport_mode=${transport_mode}`), apiService.get<AddressDataItem>(`/api/freight_forwarder_address/?transport_mode=${transport_mode}`),
// 获得价格 // 获得价格
calcShippingFee: (data:ShippingFeeData) => calcShippingFee: (data:ShippingFeeData) =>
apiService.post<CartShippingFeeData>(`/api/orders/calc_shipping_fee`,data), apiService.post<CartShippingFeeData>(`/api/orders/calc_shipping_fee/`,data),
// 获得国内价格 // 获得国内价格
calcDomesticShippingFee: (data:ShippingFeeData) => calcDomesticShippingFee: (data:ShippingFeeData) =>
apiService.post<CartShippingFeeData>(`/api/orders/calc_domestic_shipping`,data), apiService.post<CartShippingFeeData>(`/api/orders/calc_domestic_shipping/`,data),
// 创建订单 // 创建订单
createOrder: (data: CreateOrderRequest) => createOrder: (data: CreateOrderRequest) =>
apiService.post<Order>('/api/orders/cart', data), apiService.post<Order>('/api/orders/cart/', data),
// 获取所有订单 // 获取所有订单
getAllOrders: (data:PaginatedOrderRequest) => getAllOrders: (data:PaginatedOrderRequest) =>
apiService.get<PaginatedOrderResponse>(`/api/orders`,data), apiService.get<PaginatedOrderResponse>(`/api/orders/`,data),
// 获取订单指定信息 // 获取订单指定信息
getOrderDetails: (order_id:string) => getOrderDetails: (order_id:string) =>
apiService.get<OrderDetailsType>(`/api/orders/${order_id}`), apiService.get<OrderDetailsType>(`/api/orders/${order_id}/`),
// 删除订单 // 删除订单
deleteOrder: (order_id:string) => deleteOrder: (order_id:string) =>
apiService.delete<void>(`/api/orders/${order_id}`), apiService.delete<void>(`/api/orders/${order_id}/`),
// 修改订单 // 修改订单
changeOrder: (order_id:string,status:number) => changeOrder: (order_id:string,status:number) =>
apiService.patch<void>(`/api/orders/${order_id}/status?status=${status}`), apiService.patch<void>(`/api/orders/${order_id}/status/?status=${status}`),
// 修改物流信息 // 修改物流信息
updateOrderShippingInfo: (order_id:string,data:UpdateOrderShippingInfo) => updateOrderShippingInfo: (order_id:string,data:UpdateOrderShippingInfo) =>
apiService.patch<void>(`/api/orders/${order_id}/shipping`,data), apiService.patch<void>(`/api/orders/${order_id}/shipping/`,data),
}; };

4
app/services/api/payApi.ts

@ -33,11 +33,11 @@ export interface PayInfoBody {
export const payApi = { export const payApi = {
// 获取当前国家支付方式 // 获取当前国家支付方式
getCountryPaymentMethods: () => { getCountryPaymentMethods: () => {
return apiService.get<PaymentMethodsResponse>('/api/payment/country_payment_methods'); return apiService.get<PaymentMethodsResponse>('/api/payment/country_payment_methods/');
}, },
// 获取支付信息 // 获取支付信息
getPayInfo: (data: PayInfoBody) => { getPayInfo: (data: PayInfoBody) => {
return apiService.post<PaymentInfoResponse>(`/api/payment/initiate`, data); return apiService.post<PaymentInfoResponse>(`/api/payment/initiate/`, data);
}, },
}; };

4
app/services/api/productApi.ts

@ -175,11 +175,11 @@ export type Products = Product[]
}, },
// 获取商品详情 // 获取商品详情
getProductDetail: (offer_id: string) => { getProductDetail: (offer_id: string) => {
return apiService.get<ProductDetailParams>('/api/products/'+offer_id); return apiService.get<ProductDetailParams>(`/api/products/${offer_id}/`);
}, },
// 获取相似商品 // 获取相似商品
getSimilarProducts: (offer_id: string) => { getSimilarProducts: (offer_id: string) => {
return apiService.get<Similars>('/api/products/'+offer_id+'/similar?limit=5'); return apiService.get<Similars>(`/api/products/${offer_id}/similar/?limit=5`);
} }
} }

12
app/services/api/setting.ts

@ -42,10 +42,10 @@ export interface FirstLogin {
export const settingApi = { export const settingApi = {
getCountryList: () => apiService.get<Country[]>('/api/user_settings/countries'), getCountryList: () => apiService.get<Country[]>('/api/user_settings/countries/'),
getCurrencyList: () => apiService.get<string[]>('/api/user_settings/currencies'), getCurrencyList: () => apiService.get<string[]>('/api/user_settings/currencies/'),
getLanguageList: () => apiService.get<string[]>('/api/user_settings/languages'), getLanguageList: () => apiService.get<string[]>('/api/user_settings/languages/'),
getMySetting: () => apiService.get<MySetting>('/api/user_settings/me'), getMySetting: () => apiService.get<MySetting>('/api/user_settings/me/'),
postFirstLogin: (country: number) => apiService.post<FirstLogin>(`/api/user_settings/first_login?country=${country}`), postFirstLogin: (country: number) => apiService.post<FirstLogin>(`/api/user_settings/first_login/?country=${country}`),
putSetting: (setting: object) => apiService.put<MySetting>('/api/user_settings/me', setting), putSetting: (setting: object) => apiService.put<MySetting>('/api/user_settings/me/', setting),
} }

10
app/services/api/userApi.ts

@ -84,27 +84,27 @@ export const userApi = {
// 获取用户信息 // 获取用户信息
getProfile: () => { getProfile: () => {
return apiService.get<User>('/api/users/me'); return apiService.get<User>('/api/users/me/');
}, },
// 更新用户信息 // 更新用户信息
updateProfile: (data: Partial<User>) => { updateProfile: (data: Partial<User>) => {
return apiService.put<User>('/user/profile', data); return apiService.put<User>('/user/profile/', data);
}, },
// 更新用户头像 // 更新用户头像
updateAvatar: (file: FormData) => { updateAvatar: (file: FormData) => {
return apiService.upload<{avatar: string}>('/user/avatar', file); return apiService.upload<{avatar: string}>('/user/avatar/', file);
}, },
// 退出登录 // 退出登录
logout: () => { logout: () => {
return apiService.post('/auth/logout'); return apiService.post('/auth/logout/');
}, },
// 检查邮箱是否可用 // 检查邮箱是否可用
checkEmailAvailability: (email: string) => { checkEmailAvailability: (email: string) => {
return apiService.get<{available: boolean}>('/auth/check-email', { email }); return apiService.get<{available: boolean}>('/auth/check-email/', { email });
} }
}; };

BIN
assets/img/banner en (3)_compressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
assets/img/banner en (4)_compressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
assets/img/banner en (5)_compressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

12080
package-lock.json generated

File diff suppressed because it is too large Load Diff

6
package.json

@ -7,10 +7,12 @@
"start": "expo start", "start": "expo start",
"android": "expo start --android", "android": "expo start --android",
"ios": "expo start --ios", "ios": "expo start --ios",
"web": "expo start --web" "web": "expo start --web",
"build:web": "expo export:web"
}, },
"dependencies": { "dependencies": {
"@expo/metro-runtime": "~4.0.1", "@expo/metro-runtime": "~4.0.1",
"@expo/webpack-config": "^19.0.1",
"@react-native-async-storage/async-storage": "^2.1.2", "@react-native-async-storage/async-storage": "^2.1.2",
"@react-native-community/checkbox": "^0.5.17", "@react-native-community/checkbox": "^0.5.17",
"@react-native-community/datetimepicker": "8.2.0", "@react-native-community/datetimepicker": "8.2.0",
@ -22,7 +24,6 @@
"events": "^3.3.0", "events": "^3.3.0",
"expo": "~52.0.41", "expo": "~52.0.41",
"expo-auth-session": "~6.0.3", "expo-auth-session": "~6.0.3",
"expo-dev-client": "~5.0.20",
"expo-image": "~2.0.7", "expo-image": "~2.0.7",
"expo-linear-gradient": "~14.0.2", "expo-linear-gradient": "~14.0.2",
"expo-localization": "^16.0.1", "expo-localization": "^16.0.1",
@ -64,6 +65,7 @@
"@hancleee/babel-plugin-react-native-pxtodp": "^1.0.8", "@hancleee/babel-plugin-react-native-pxtodp": "^1.0.8",
"@types/react": "~18.3.12", "@types/react": "~18.3.12",
"@types/react-native-vector-icons": "^6.4.18", "@types/react-native-vector-icons": "^6.4.18",
"expo-module-scripts": "^4.1.7",
"react-native-svg-transformer": "^1.5.0", "react-native-svg-transformer": "^1.5.0",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },

5176
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save