import React, { useEffect, useMemo, useState } from 'react'; import { View, StyleSheet, TouchableOpacity, Alert, ScrollView } from 'react-native'; import { useNavigation, useRoute, RouteProp } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import { SafeAreaView } from 'react-native-safe-area-context'; import { colors, spacing, borderRadius, shadows } from '../../theme'; import { Avatar, Text } from '../../components/common'; import { RootStackParamList } from '../../navigation/types'; import { groupService } from '../../services/groupService'; import { groupManager } from '../../stores/groupManager'; import { userManager } from '../../stores/userManager'; import { GroupInfoSummaryCard, DecisionFooter } from './components/GroupRequestShared'; type Route = RouteProp; type Navigation = NativeStackNavigationProp; const GroupRequestDetailScreen: React.FC = () => { const route = useRoute(); const navigation = useNavigation(); const { message } = route.params; const { extra_data } = message; const [submitting, setSubmitting] = useState(false); const [memberCount, setMemberCount] = useState(null); const [loadingGroup, setLoadingGroup] = useState(false); const requestType = extra_data?.request_type; const requestStatus = extra_data?.request_status; const reviewerName = extra_data?.actor_name || extra_data?.operator_name || '管理员'; const canAction = requestStatus === 'pending' && (message.system_type === 'group_join_apply' || message.system_type === 'group_invite'); const processedText = requestStatus === 'accepted' ? `${reviewerName}已同意` : requestStatus === 'rejected' ? `${reviewerName}已拒绝` : '该请求已处理'; const applicantName = useMemo(() => { if (requestType === 'invite') { return extra_data?.target_user_name || '被邀请用户'; } return extra_data?.actor_name || '申请用户'; }, [requestType, extra_data]); const applicantAvatar = useMemo(() => { if (requestType === 'invite') { return extra_data?.target_user_avatar || ''; } return extra_data?.avatar_url || ''; }, [requestType, extra_data]); const applicantId = useMemo(() => { if (requestType === 'invite') { return extra_data?.target_user_id; } return extra_data?.actor_id_str; }, [requestType, extra_data]); useEffect(() => { const loadGroupInfo = async () => { if (!extra_data?.group_id) return; setLoadingGroup(true); try { const group = await groupManager.getGroup(extra_data.group_id); setMemberCount(group.member_count ?? null); } catch { setMemberCount(null); } finally { setLoadingGroup(false); } }; loadGroupInfo(); }, [extra_data?.group_id]); const handleDecision = async (approve: boolean) => { const flag = extra_data?.flag; const groupId = extra_data?.group_id; if (!flag) { Alert.alert('提示', '缺少请求标识,无法处理'); return; } if (!groupId) { Alert.alert('提示', '缺少群组标识,无法处理'); return; } setSubmitting(true); try { if (message.system_type === 'group_invite') { await groupService.respondInvite(groupId, { flag, approve, }); } else { await groupService.reviewJoinRequest(groupId, { flag, approve, }); } Alert.alert('成功', approve ? '已同意申请' : '已拒绝申请', [ { text: '确定', onPress: () => navigation.goBack() }, ]); } catch (error) { Alert.alert('操作失败', '请稍后重试'); } finally { setSubmitting(false); } }; const handleOpenUser = async () => { if (!applicantId) return; const user = await userManager.getUserById(applicantId); if (user?.id) { navigation.navigate('UserProfile', { userId: String(user.id) }); } }; return ( 用户信息 {applicantName} {requestType === 'invite' ? '被邀请加入' : '申请加入'} {applicantId ? ( ) : null} {requestType === 'invite' && ( 邀请人:{extra_data?.actor_name || '群成员'} )} handleDecision(false)} onApprove={() => handleDecision(true)} processedText={processedText} /> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: colors.background.default, }, scrollView: { flex: 1, }, scrollContent: { padding: spacing.lg, paddingBottom: spacing.xl, }, card: { backgroundColor: colors.background.paper, borderRadius: borderRadius.lg, padding: spacing.lg, marginBottom: spacing.md, ...shadows.sm, }, sectionTitle: { marginBottom: spacing.sm, }, row: { flexDirection: 'row', alignItems: 'center', }, meta: { marginLeft: spacing.md, flex: 1, }, name: { marginBottom: 2, }, subDesc: { marginTop: spacing.sm, }, }); export default GroupRequestDetailScreen;