feat(vip): 限制底部栏自定义功能为VIP专享
非VIP用户尝试配置底部栏时将显示会员购买弹窗, 只有VIP会员才能自由开启或关闭导航标签。 包含会员权益说明的国际化支持和存储结构重构。
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
||||
import { useSafeAreaTop } from '@/hooks/useSafeAreaWithPadding';
|
||||
import { useVipService } from '@/hooks/useVipService';
|
||||
import {
|
||||
resetToDefault,
|
||||
selectTabBarConfigs,
|
||||
@@ -9,7 +10,7 @@ import {
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useRouter } from 'expo-router';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
Alert,
|
||||
ScrollView,
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
View
|
||||
} from 'react-native';
|
||||
|
||||
import { MembershipModal } from '@/components/model/MembershipModal';
|
||||
import { HeaderBar } from '@/components/ui/HeaderBar';
|
||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||
import { palette } from '@/constants/Colors';
|
||||
@@ -31,15 +33,38 @@ export default function TabBarConfigScreen() {
|
||||
const dispatch = useAppDispatch();
|
||||
const safeAreaTop = useSafeAreaTop(60);
|
||||
const configs = useAppSelector(selectTabBarConfigs);
|
||||
const { isVip } = useVipService();
|
||||
const [showMembershipModal, setShowMembershipModal] = useState(false);
|
||||
|
||||
// 处理开关切换
|
||||
const handleToggle = useCallback(
|
||||
(tabId: string) => {
|
||||
dispatch(toggleTabEnabled(tabId));
|
||||
// 直接检查用户是否是 VIP(底部栏配置不是权益类功能,而是基础功能)
|
||||
if (isVip) {
|
||||
// VIP 用户可以正常切换
|
||||
dispatch(toggleTabEnabled(tabId));
|
||||
} else {
|
||||
// 非 VIP 用户显示购买弹窗
|
||||
setShowMembershipModal(true);
|
||||
}
|
||||
},
|
||||
[dispatch]
|
||||
[dispatch, isVip]
|
||||
);
|
||||
|
||||
// 页面加载时检查 VIP 状态
|
||||
useEffect(() => {
|
||||
if (!isVip) {
|
||||
// 非 VIP 用户进入页面时立即显示购买弹窗
|
||||
setShowMembershipModal(true);
|
||||
}
|
||||
}, [isVip]);
|
||||
|
||||
// 购买成功回调
|
||||
const handlePurchaseSuccess = useCallback(() => {
|
||||
// 购买成功后可以执行一些操作,比如刷新用户信息
|
||||
console.log('会员购买成功');
|
||||
}, []);
|
||||
|
||||
// 恢复默认设置
|
||||
const handleReset = useCallback(() => {
|
||||
Alert.alert(
|
||||
@@ -80,6 +105,11 @@ export default function TabBarConfigScreen() {
|
||||
{t('personal.tabBarConfig.cannotDisable')}
|
||||
</Text>
|
||||
)}
|
||||
{item.canBeDisabled && !isVip && (
|
||||
<Text style={styles.vipSubtitle}>
|
||||
{t('personal.tabBarConfig.vipOnly')}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -87,7 +117,7 @@ export default function TabBarConfigScreen() {
|
||||
<Switch
|
||||
value={item.enabled}
|
||||
onValueChange={() => handleToggle(item.id)}
|
||||
disabled={!item.canBeDisabled}
|
||||
disabled={!item.canBeDisabled || !isVip}
|
||||
trackColor={{ false: '#E5E5E5', true: '#9370DB' }}
|
||||
thumbColor="#FFFFFF"
|
||||
style={styles.switch}
|
||||
@@ -153,6 +183,13 @@ export default function TabBarConfigScreen() {
|
||||
</View>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
{/* 会员购买弹窗 */}
|
||||
<MembershipModal
|
||||
visible={showMembershipModal}
|
||||
onClose={() => setShowMembershipModal(false)}
|
||||
onPurchaseSuccess={handlePurchaseSuccess}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -253,6 +290,10 @@ const styles = StyleSheet.create({
|
||||
fontSize: 12,
|
||||
color: '#9370DB',
|
||||
},
|
||||
vipSubtitle: {
|
||||
fontSize: 12,
|
||||
color: '#FF6B6B',
|
||||
},
|
||||
switch: {
|
||||
transform: [{ scaleX: 0.9 }, { scaleY: 0.9 }],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user