| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import { useLocalSearchParams, useRouter } from 'expo-router';
- import React, { useEffect, useState } from 'react';
- import {
- ActivityIndicator,
- ScrollView,
- StatusBar,
- StyleSheet,
- Text,
- TouchableOpacity,
- View
- } from 'react-native';
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
- import { getParamConfig } from '@/services/user';
- // 简单的HTML标签清理函数
- const stripHtmlTags = (html: string): string => {
- if (!html) return '';
- // 移除HTML标签,保留文本内容
- 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(/"/g, '"')
- .replace(/\n\s*\n/g, '\n\n')
- .trim();
- };
- export default function AgreementScreen() {
- const router = useRouter();
- const insets = useSafeAreaInsets();
- const params = useLocalSearchParams<{ type: string }>();
-
- const [loading, setLoading] = useState(true);
- const [title, setTitle] = useState('');
- const [content, setContent] = useState('');
- useEffect(() => {
- loadContent();
- }, [params.type]);
- const loadContent = async () => {
- try {
- setLoading(true);
- const type = params.type || 'user.html';
- console.log('加载协议类型:', type);
- const res = await getParamConfig(type) as any;
- console.log('协议内容返回:', res);
-
- if (res) {
- // API返回的数据结构: { title: string, data: string (HTML内容) }
- const titleText = res.title || (type === 'user.html' ? '用户协议' : '隐私协议');
- setTitle(titleText);
- // 清理HTML标签,只保留纯文本
- const rawContent = res.data || res || '';
- setContent(stripHtmlTags(typeof rawContent === 'string' ? rawContent : JSON.stringify(rawContent)));
- }
- } catch (error) {
- console.error('获取协议内容失败:', error);
- } finally {
- setLoading(false);
- }
- };
- const handleBack = () => {
- router.back();
- };
- return (
- <View style={styles.container}>
- <StatusBar barStyle="light-content" />
-
- {/* 顶部导航 */}
- <View style={[styles.header, { paddingTop: insets.top }]}>
- <TouchableOpacity style={styles.backBtn} onPress={handleBack}>
- <Text style={styles.backIcon}>‹</Text>
- </TouchableOpacity>
- <Text style={styles.headerTitle}>{title || '协议'}</Text>
- <View style={styles.placeholder} />
- </View>
- {loading ? (
- <View style={styles.loadingBox}>
- <ActivityIndicator size="large" color="#FC7D2E" />
- </View>
- ) : content ? (
- <ScrollView
- style={styles.scrollView}
- contentContainerStyle={styles.scrollContent}
- showsVerticalScrollIndicator={false}
- >
- <Text style={styles.contentText}>{content}</Text>
- </ScrollView>
- ) : (
- <View style={styles.emptyBox}>
- <Text style={styles.emptyText}>暂无内容</Text>
- </View>
- )}
- </View>
- );
- }
- const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#333',
- },
- header: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- paddingHorizontal: 10,
- height: 80,
- backgroundColor: '#333',
- },
- backBtn: {
- width: 40,
- height: 40,
- justifyContent: 'center',
- alignItems: 'center',
- },
- backIcon: {
- fontSize: 32,
- color: '#fff',
- fontWeight: 'bold',
- },
- headerTitle: {
- fontSize: 16,
- fontWeight: 'bold',
- color: '#fff',
- },
- placeholder: {
- width: 40,
- },
- loadingBox: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#fff',
- },
- scrollView: {
- flex: 1,
- backgroundColor: '#fff',
- },
- scrollContent: {
- padding: 15,
- paddingBottom: 50,
- },
- contentText: {
- fontSize: 14,
- lineHeight: 22,
- color: '#333',
- },
- emptyBox: {
- flex: 1,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: '#fff',
- },
- emptyText: {
- fontSize: 14,
- color: '#999',
- },
- });
|