Browse Source

设置国家,语言,货币重启app

main
Your Name 2 weeks ago
parent
commit
f39472760a
  1. 2
      app/navigation/types.ts
  2. 12
      app/screens/CategoryScreen.tsx
  3. 4
      app/screens/HomeScreen.tsx
  4. 16
      app/screens/SearchResultScreen.tsx
  5. 20
      app/screens/setting/CountrySetting.tsx
  6. 1
      app/services/api/categories.ts
  7. 11
      package-lock.json
  8. 1
      package.json
  9. 5
      yarn.lock

2
app/navigation/types.ts

@ -7,7 +7,7 @@ export type RootStackParamList = {
EmailLogin: undefined; EmailLogin: undefined;
MainTabs: undefined; MainTabs: undefined;
Search: undefined; Search: undefined;
SearchResult: { keyword: string, formData?: FormData }; SearchResult: { keyword?: string, category_id?: number, formData?: FormData };
ImageSearchResultScreen: { image?: string, type?: number }; ImageSearchResultScreen: { image?: string, type?: number };
ProductDetail: { productId: string; searchKeyword?: string }; ProductDetail: { productId: string; searchKeyword?: string };
Balance: undefined; Balance: undefined;

12
app/screens/CategoryScreen.tsx

@ -18,7 +18,7 @@ import widthUtils from '../utils/widthUtils';
import { categoriesApi, Category } from '../services/api/categories'; import { categoriesApi, Category } from '../services/api/categories';
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { RootStackParamList } from '../types/navigation'; import { RootStackParamList } from '../navigation/types';
const { width: SCREEN_WIDTH } = Dimensions.get('window'); const { width: SCREEN_WIDTH } = Dimensions.get('window');
const MENU_WIDTH = widthUtils(120, 120).width; const MENU_WIDTH = widthUtils(120, 120).width;
@ -99,11 +99,11 @@ export const CategoryScreen = () => {
<TouchableOpacity <TouchableOpacity
style={styles.subCategoryItem} style={styles.subCategoryItem}
onPress={() => { onPress={() => {
navigation.navigate('SearchResult', { keyword: item.name_en.trim() }); navigation.navigate('SearchResult', { category_id: item.category_id });
}} }}
> >
<Image <Image
source={item.image_url ? { uri: item.image_url } : require('../../assets/img/1034058.png')} source={item.image ? { uri: item.image } : require('../../assets/img/1034058.png')}
style={styles.subCategoryImage} style={styles.subCategoryImage}
resizeMode="cover" resizeMode="cover"
/> />
@ -134,6 +134,9 @@ export const CategoryScreen = () => {
<View style={styles.container}> <View style={styles.container}>
<View style={styles.leftMenu}> <View style={styles.leftMenu}>
<FlatList <FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
data={mainCategories} data={mainCategories}
renderItem={renderMainCategoryItem} renderItem={renderMainCategoryItem}
keyExtractor={(item) => item.category_id.toString()} keyExtractor={(item) => item.category_id.toString()}
@ -147,6 +150,9 @@ export const CategoryScreen = () => {
) : ( ) : (
<FlatList <FlatList
data={subCategories} data={subCategories}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
renderItem={renderSubCategoryItem} renderItem={renderSubCategoryItem}
keyExtractor={(item) => item.category_id.toString()} keyExtractor={(item) => item.category_id.toString()}
numColumns={NUM_COLUMNS} numColumns={NUM_COLUMNS}

4
app/screens/HomeScreen.tsx

@ -41,6 +41,7 @@ import { getSubjectTransLanguage } from "../utils/languageUtils";
import useUserStore from "../store/user"; import useUserStore from "../store/user";
import * as ImagePicker from "expo-image-picker"; import * as ImagePicker from "expo-image-picker";
import * as FileSystem from "expo-file-system"; import * as FileSystem from "expo-file-system";
import { useGlobalStore } from "../store/useGlobalStore";
// 为图标定义类型 // 为图标定义类型
type IconProps = { type IconProps = {
name: string; name: string;
@ -434,10 +435,11 @@ export const HomeScreen = () => {
setRefreshing(false); setRefreshing(false);
} }
}, [searchParams]); }, [searchParams]);
const { country, currency, language } = useGlobalStore();
useEffect(() => { useEffect(() => {
console.log("userStore.user", userStore.user); console.log("userStore.user", userStore.user);
getProductData(); getProductData();
}, [userStore.user]); }, [userStore.user, country, currency, language]);
const categories = [ const categories = [
"Tous", "Tous",
"Bijoux", "Bijoux",

16
app/screens/SearchResultScreen.tsx

@ -40,7 +40,8 @@ const IconComponent = React.memo(
); );
// 路由参数类型 // 路由参数类型
type SearchResultRouteParams = { type SearchResultRouteParams = {
keyword: string; keyword?: string;
category_id?: number;
}; };
// 组件Props类型 // 组件Props类型
type SearchResultScreenProps = { type SearchResultScreenProps = {
@ -148,7 +149,7 @@ const ProductItem = React.memo(
{/* 产品分类 */} {/* 产品分类 */}
<View style={styles.productInfo}> <View style={styles.productInfo}>
<Text style={styles.categoryText} numberOfLines={2}> <Text style={styles.categoryText} numberOfLines={2}>
{getSubjectTransLanguage(product)} {getSubjectTransLanguage(product) || product.subject_trans}
</Text> </Text>
{/* 价格信息 */} {/* 价格信息 */}
<View style={styles.beautyProductInfoRow}> <View style={styles.beautyProductInfoRow}>
@ -218,7 +219,16 @@ export const SearchResultScreen = ({ route, navigation }: SearchResultScreenProp
setSearchParams(newParams); setSearchParams(newParams);
searchProducts(newParams); searchProducts(newParams);
} }
}, [route.params?.keyword]); if (route.params?.category_id) {
setShowSkeleton(true);
const newParams = {
...searchParams,
category_id: route.params.category_id,
};
setSearchParams(newParams);
searchProducts(newParams)
}
}, [route.params?.keyword,route.params?.category_id]);
// 搜索产品的API调用 // 搜索产品的API调用
const searchProducts = useCallback( const searchProducts = useCallback(
async (params: ProductParams, isLoadMore = false) => { async (params: ProductParams, isLoadMore = false) => {

20
app/screens/setting/CountrySetting.tsx

@ -1,11 +1,11 @@
import { View, Text, StyleSheet, TouchableOpacity, Image, SafeAreaView, StatusBar, Platform } from "react-native"; import { View, Text, StyleSheet, TouchableOpacity, Image, SafeAreaView, StatusBar } from "react-native";
import BackIcon from "../../components/BackIcon"; import BackIcon from "../../components/BackIcon";
import fontSize from "../../utils/fontsizeUtils"; import fontSize from "../../utils/fontsizeUtils";
import { useNavigation, useRoute, RouteProp } from "@react-navigation/native"; import { useNavigation, useRoute, RouteProp } from "@react-navigation/native";
import { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { RootStackParamList } from "../../navigation/types"; import { RootStackParamList } from "../../navigation/types";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { settingApi, Country } from "../../services/api/setting"; import { settingApi } from "../../services/api/setting";
import { FlatList } from "react-native"; import { FlatList } from "react-native";
import flagMap from "../../utils/flagMap"; import flagMap from "../../utils/flagMap";
import CheckIcon from "../../components/CheckIcon"; import CheckIcon from "../../components/CheckIcon";
@ -13,7 +13,10 @@ import Toast from "react-native-toast-message";
import { eventBus } from "../../utils/eventBus"; import { eventBus } from "../../utils/eventBus";
import { changeLanguage } from "../../i18n"; import { changeLanguage } from "../../i18n";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import RNRestart from 'react-native-restart'; import { useGlobalStore } from "../../store/useGlobalStore";
import { userApi } from "../../services/api/userApi";
import useUserStore from "../../store/user";
// Define CountryList type to match API response // Define CountryList type to match API response
@ -30,6 +33,7 @@ type CountryList = {
export const CountrySetting = () => { export const CountrySetting = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { setGlobalCountry, setGlobalCurrency, setGlobalLanguage } = useGlobalStore();
const navigation = const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList>>(); useNavigation<NativeStackNavigationProp<RootStackParamList>>();
const route = useRoute<RouteProp<RootStackParamList, "CountrySetting">>(); const route = useRoute<RouteProp<RootStackParamList, "CountrySetting">>();
@ -40,6 +44,8 @@ export const CountrySetting = () => {
const [country, setCountry] = useState<number>(0); const [country, setCountry] = useState<number>(0);
const [currency, setCurrency] = useState<string>(""); const [currency, setCurrency] = useState<string>("");
const [language, setLanguage] = useState<string>(""); const [language, setLanguage] = useState<string>("");
const { setUser } = useUserStore();
const getCountry = async () => { const getCountry = async () => {
const res = await settingApi.getCountryList(); const res = await settingApi.getCountryList();
setCountryList(res); setCountryList(res);
@ -67,13 +73,15 @@ export const CountrySetting = () => {
const putSettinghandel = async () => { const putSettinghandel = async () => {
// Only include the property that corresponds to the active tab // Only include the property that corresponds to the active tab
let data = {}; let data = {};
if (changeType === "country") { if (changeType === "country") {
data = { country: country }; data = { country: country };
setGlobalCountry({ country: country.toString() });
} else if (changeType === "currency") { } else if (changeType === "currency") {
data = { currency: currency }; data = { currency: currency };
setGlobalCurrency({ currency: currency });
} else if (changeType === "language") { } else if (changeType === "language") {
data = { language: language }; data = { language: language };
setGlobalLanguage({ language: language });
} }
Toast.show({ Toast.show({
@ -86,8 +94,8 @@ export const CountrySetting = () => {
await changeLanguage(language); await changeLanguage(language);
} }
eventBus.emit("refreshSetting"); eventBus.emit("refreshSetting");
const userData = await userApi.getProfile();
RNRestart.Restart(); setUser(userData);
}; };
return ( return (
<SafeAreaView style={styles.safeArea}> <SafeAreaView style={styles.safeArea}>

1
app/services/api/categories.ts

@ -5,6 +5,7 @@ export interface Category {
name: string; name: string;
name_cn: string; name_cn: string;
name_en: string; name_en: string;
image:string
level: number; level: number;
is_leaf: boolean; is_leaf: boolean;
image_url?: string; image_url?: string;

11
package-lock.json generated

@ -52,7 +52,6 @@
"react-native-reanimated-carousel": "^4.0.2", "react-native-reanimated-carousel": "^4.0.2",
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-responsive-fontsize": "^0.5.1", "react-native-responsive-fontsize": "^0.5.1",
"react-native-restart": "^0.0.27",
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0", "react-native-screens": "~4.4.0",
"react-native-svg": "^15.11.2", "react-native-svg": "^15.11.2",
@ -19548,16 +19547,6 @@
"react-native": ">=0.42.0" "react-native": ">=0.42.0"
} }
}, },
"node_modules/react-native-restart": {
"version": "0.0.27",
"resolved": "https://registry.npmmirror.com/react-native-restart/-/react-native-restart-0.0.27.tgz",
"integrity": "sha512-8KScVICrXwcTSJ1rjWkqVTHyEKQIttm5AIMGSK1QG1+RS5owYlE4z/1DykOTdWfVl9l16FIk0w9Xzk9ZO6jxlA==",
"license": "MIT",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-safe-area-context": { "node_modules/react-native-safe-area-context": {
"version": "4.12.0", "version": "4.12.0",
"resolved": "https://registry.npmmirror.com/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz", "resolved": "https://registry.npmmirror.com/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz",

1
package.json

@ -54,7 +54,6 @@
"react-native-reanimated-carousel": "^4.0.2", "react-native-reanimated-carousel": "^4.0.2",
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-responsive-fontsize": "^0.5.1", "react-native-responsive-fontsize": "^0.5.1",
"react-native-restart": "^0.0.27",
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0", "react-native-screens": "~4.4.0",
"react-native-svg": "^15.11.2", "react-native-svg": "^15.11.2",

5
yarn.lock

@ -10083,11 +10083,6 @@ react-native-responsive-fontsize@^0.5.1:
dependencies: dependencies:
react-native-iphone-x-helper "^1.3.1" react-native-iphone-x-helper "^1.3.1"
react-native-restart@^0.0.27:
version "0.0.27"
resolved "https://registry.npmmirror.com/react-native-restart/-/react-native-restart-0.0.27.tgz"
integrity sha512-8KScVICrXwcTSJ1rjWkqVTHyEKQIttm5AIMGSK1QG1+RS5owYlE4z/1DykOTdWfVl9l16FIk0w9Xzk9ZO6jxlA==
react-native-safe-area-context@4.12.0: react-native-safe-area-context@4.12.0:
version "4.12.0" version "4.12.0"
resolved "https://registry.npmmirror.com/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz" resolved "https://registry.npmmirror.com/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz"

Loading…
Cancel
Save