|
@@ -1,38 +1,73 @@
|
|
|
import { Images } from '@/constants/images';
|
|
import { Images } from '@/constants/images';
|
|
|
-import { Image } from 'expo-image';
|
|
|
|
|
|
|
+import { getParamConfig } from '@/services/user';
|
|
|
import React, { forwardRef, useImperativeHandle, useState } from 'react';
|
|
import React, { forwardRef, useImperativeHandle, useState } from 'react';
|
|
|
-import { ImageBackground, Modal, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
|
|
|
|
|
+import { Dimensions, ImageBackground, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
|
|
+
|
|
|
|
|
+const { width: SCREEN_WIDTH } = Dimensions.get('window');
|
|
|
|
|
|
|
|
export interface WishRuleModalRef {
|
|
export interface WishRuleModalRef {
|
|
|
show: () => void;
|
|
show: () => void;
|
|
|
close: () => void;
|
|
close: () => void;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 简单的HTML标签清理函数
|
|
|
|
|
+const stripHtmlTags = (html: string): string => {
|
|
|
|
|
+ if (!html) return '';
|
|
|
|
|
+ return html
|
|
|
|
|
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
|
|
|
|
|
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
|
|
|
|
|
+ .replace(/<[^>]+>/g, '\n')
|
|
|
|
|
+ .replace(/ /g, ' ')
|
|
|
|
|
+ .replace(/</g, '<')
|
|
|
|
|
+ .replace(/>/g, '>')
|
|
|
|
|
+ .replace(/&/g, '&')
|
|
|
|
|
+ .replace(/\n\s*\n/g, '\n\n') // Merge multiple newlines
|
|
|
|
|
+ .trim();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
export const WishRuleModal = forwardRef<WishRuleModalRef, {}>((props, ref) => {
|
|
export const WishRuleModal = forwardRef<WishRuleModalRef, {}>((props, ref) => {
|
|
|
const [visible, setVisible] = useState(false);
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
|
+ const [content, setContent] = useState('');
|
|
|
|
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
useImperativeHandle(ref, () => ({
|
|
|
- show: () => setVisible(true),
|
|
|
|
|
|
|
+ show: () => {
|
|
|
|
|
+ setVisible(true);
|
|
|
|
|
+ loadRule();
|
|
|
|
|
+ },
|
|
|
close: () => setVisible(false),
|
|
close: () => setVisible(false),
|
|
|
}));
|
|
}));
|
|
|
|
|
|
|
|
|
|
+ const loadRule = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getParamConfig('wish_rule');
|
|
|
|
|
+ if (res && res.data) {
|
|
|
|
|
+ setContent(stripHtmlTags(res.data));
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载祈愿规则失败:', error);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
if (!visible) return null;
|
|
if (!visible) return null;
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<Modal visible={visible} transparent animationType="fade" onRequestClose={() => setVisible(false)}>
|
|
<Modal visible={visible} transparent animationType="fade" onRequestClose={() => setVisible(false)}>
|
|
|
<View style={styles.overlay}>
|
|
<View style={styles.overlay}>
|
|
|
- <View style={styles.contentContainer}>
|
|
|
|
|
- <ImageBackground style={styles.content} source={{ uri: Images.welfare.welfareDialogBg }} resizeMode="contain">
|
|
|
|
|
- <View style={styles.titleBox}>
|
|
|
|
|
- <Image style={styles.title} source={{ uri: Images.welfare.qijiWelfareDollRule }} resizeMode="contain" />
|
|
|
|
|
- </View>
|
|
|
|
|
- <View style={styles.closeBox}>
|
|
|
|
|
- <TouchableOpacity onPress={() => setVisible(false)}>
|
|
|
|
|
- <Image style={styles.close} source={{ uri: Images.common.closeBut }} />
|
|
|
|
|
- </TouchableOpacity>
|
|
|
|
|
- </View>
|
|
|
|
|
- <Image source={{ uri: Images.welfare.catchDollRule }} style={styles.ruleImage} contentFit="contain" />
|
|
|
|
|
|
|
+ <View style={styles.windowSection}>
|
|
|
|
|
+ <ImageBackground style={styles.main} source={{ uri: Images.common.windBg }} resizeMode="stretch">
|
|
|
|
|
+ <ScrollView
|
|
|
|
|
+ style={styles.scrollView}
|
|
|
|
|
+ contentContainerStyle={styles.scrollContent}
|
|
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Text style={styles.text}>{content || '暂无规则内容'}</Text>
|
|
|
|
|
+ </ScrollView>
|
|
|
</ImageBackground>
|
|
</ImageBackground>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 关闭按钮 - 移到底部 */}
|
|
|
|
|
+ <TouchableOpacity style={styles.closeBtn} onPress={() => setVisible(false)}>
|
|
|
|
|
+ <ImageBackground source={{ uri: Images.common.closeBut }} style={styles.closeIcon} resizeMode="contain" />
|
|
|
|
|
+ </TouchableOpacity>
|
|
|
</View>
|
|
</View>
|
|
|
</View>
|
|
</View>
|
|
|
</Modal>
|
|
</Modal>
|
|
@@ -48,40 +83,37 @@ const styles = StyleSheet.create({
|
|
|
justifyContent: 'center',
|
|
justifyContent: 'center',
|
|
|
alignItems: 'center',
|
|
alignItems: 'center',
|
|
|
},
|
|
},
|
|
|
- contentContainer: {
|
|
|
|
|
- width: 300,
|
|
|
|
|
- height: 400,
|
|
|
|
|
|
|
+ windowSection: {
|
|
|
|
|
+ width: SCREEN_WIDTH,
|
|
|
alignItems: 'center',
|
|
alignItems: 'center',
|
|
|
- justifyContent: 'center',
|
|
|
|
|
},
|
|
},
|
|
|
- content: {
|
|
|
|
|
- width: '100%',
|
|
|
|
|
- height: '100%',
|
|
|
|
|
|
|
+ main: {
|
|
|
|
|
+ width: 360, // 720rpx
|
|
|
|
|
+ height: 302, // 604rpx
|
|
|
|
|
+ paddingTop: 90, // 180rpx
|
|
|
|
|
+ paddingHorizontal: 30, // 60rpx
|
|
|
alignItems: 'center',
|
|
alignItems: 'center',
|
|
|
- justifyContent: 'center',
|
|
|
|
|
- },
|
|
|
|
|
- titleBox: {
|
|
|
|
|
- position: 'absolute',
|
|
|
|
|
- top: -20,
|
|
|
|
|
zIndex: 1,
|
|
zIndex: 1,
|
|
|
|
|
+ marginBottom: 20, // Space between modal and close button
|
|
|
|
|
+ },
|
|
|
|
|
+ scrollView: {
|
|
|
|
|
+ width: '100%',
|
|
|
|
|
+ height: 190, // 380rpx
|
|
|
},
|
|
},
|
|
|
- title: {
|
|
|
|
|
- width: 200,
|
|
|
|
|
- height: 50,
|
|
|
|
|
|
|
+ scrollContent: {
|
|
|
|
|
+ paddingBottom: 20,
|
|
|
},
|
|
},
|
|
|
- closeBox: {
|
|
|
|
|
- position: 'absolute',
|
|
|
|
|
- top: 0,
|
|
|
|
|
- right: -10,
|
|
|
|
|
- zIndex: 2,
|
|
|
|
|
|
|
+ text: {
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ color: '#8B4513',
|
|
|
|
|
+ lineHeight: 22,
|
|
|
},
|
|
},
|
|
|
- close: {
|
|
|
|
|
- width: 30,
|
|
|
|
|
- height: 30,
|
|
|
|
|
|
|
+ closeBtn: {
|
|
|
|
|
+ width: 35,
|
|
|
|
|
+ height: 35,
|
|
|
},
|
|
},
|
|
|
- ruleImage: {
|
|
|
|
|
- width: 260,
|
|
|
|
|
- height: 300,
|
|
|
|
|
- marginTop: 20,
|
|
|
|
|
|
|
+ closeIcon: {
|
|
|
|
|
+ width: '100%',
|
|
|
|
|
+ height: '100%',
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|