WishRuleModal.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { Images } from '@/constants/images';
  2. import { getParamConfig } from '@/services/user';
  3. import React, { forwardRef, useImperativeHandle, useState } from 'react';
  4. import { Dimensions, ImageBackground, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
  5. const { width: SCREEN_WIDTH } = Dimensions.get('window');
  6. export interface WishRuleModalRef {
  7. show: () => void;
  8. close: () => void;
  9. }
  10. // 简单的HTML标签清理函数
  11. const stripHtmlTags = (html: string): string => {
  12. if (!html) return '';
  13. return html
  14. .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
  15. .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
  16. .replace(/<[^>]+>/g, '\n')
  17. .replace(/&nbsp;/g, ' ')
  18. .replace(/&lt;/g, '<')
  19. .replace(/&gt;/g, '>')
  20. .replace(/&amp;/g, '&')
  21. .replace(/\n\s*\n/g, '\n\n') // Merge multiple newlines
  22. .trim();
  23. };
  24. export const WishRuleModal = forwardRef<WishRuleModalRef, {}>((props, ref) => {
  25. const [visible, setVisible] = useState(false);
  26. const [content, setContent] = useState('');
  27. useImperativeHandle(ref, () => ({
  28. show: () => {
  29. setVisible(true);
  30. loadRule();
  31. },
  32. close: () => setVisible(false),
  33. }));
  34. const loadRule = async () => {
  35. try {
  36. const res = await getParamConfig('wish_rule');
  37. if (res && res.data) {
  38. setContent(stripHtmlTags(res.data));
  39. }
  40. } catch (error) {
  41. console.error('加载祈愿规则失败:', error);
  42. }
  43. };
  44. if (!visible) return null;
  45. return (
  46. <Modal visible={visible} transparent animationType="fade" onRequestClose={() => setVisible(false)}>
  47. <View style={styles.overlay}>
  48. <View style={styles.windowSection}>
  49. <ImageBackground style={styles.main} source={{ uri: Images.common.windBg }} resizeMode="stretch">
  50. <ScrollView
  51. style={styles.scrollView}
  52. contentContainerStyle={styles.scrollContent}
  53. showsVerticalScrollIndicator={false}
  54. >
  55. <Text style={styles.text}>{content || '暂无规则内容'}</Text>
  56. <Text style={[styles.text, { marginTop: 15, color: '#999', fontSize: 12 }]}>特别声明:本祈愿福利活动由艾斯潮盒官方发起,与苹果公司(Apple Inc.)无关。苹果公司不是活动的赞助商,也没有以任何形式参与。</Text>
  57. </ScrollView>
  58. </ImageBackground>
  59. {/* 关闭按钮 - 移到底部 */}
  60. <TouchableOpacity style={styles.closeBtn} onPress={() => setVisible(false)}>
  61. <ImageBackground source={{ uri: Images.common.closeBut }} style={styles.closeIcon} resizeMode="contain" />
  62. </TouchableOpacity>
  63. </View>
  64. </View>
  65. </Modal>
  66. );
  67. });
  68. export default WishRuleModal;
  69. const styles = StyleSheet.create({
  70. overlay: {
  71. flex: 1,
  72. backgroundColor: 'rgba(0,0,0,0.7)',
  73. justifyContent: 'center',
  74. alignItems: 'center',
  75. },
  76. windowSection: {
  77. width: SCREEN_WIDTH,
  78. alignItems: 'center',
  79. },
  80. main: {
  81. width: 360, // 720rpx
  82. height: 302, // 604rpx
  83. paddingTop: 90, // 180rpx
  84. paddingHorizontal: 30, // 60rpx
  85. alignItems: 'center',
  86. zIndex: 1,
  87. marginBottom: 20, // Space between modal and close button
  88. },
  89. scrollView: {
  90. width: '100%',
  91. height: 190, // 380rpx
  92. },
  93. scrollContent: {
  94. paddingBottom: 20,
  95. },
  96. text: {
  97. fontSize: 14,
  98. color: '#8B4513',
  99. lineHeight: 22,
  100. },
  101. closeBtn: {
  102. width: 35,
  103. height: 35,
  104. },
  105. closeIcon: {
  106. width: '100%',
  107. height: '100%',
  108. },
  109. });