|
|
@@ -1,8 +1,11 @@
|
|
|
-import { StatusBadge } from '@/components/ui/status-badge';
|
|
|
import { Ionicons } from '@expo/vector-icons';
|
|
|
+import { BlurView } from 'expo-blur';
|
|
|
+import { Stack } from 'expo-router';
|
|
|
import React, { useState } from 'react';
|
|
|
-import { Pressable, ScrollView, Text, View } from 'react-native';
|
|
|
-import { SafeAreaView } from 'react-native-safe-area-context';
|
|
|
+import { Pressable, Text, View } from 'react-native';
|
|
|
+import Animated, { Extrapolation, interpolate, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
|
|
|
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
+import { StatusBadge } from '@/components/ui/status-badge';
|
|
|
|
|
|
type ReportTab = '全部' | '征信报告' | '匹配结果';
|
|
|
|
|
|
@@ -91,6 +94,15 @@ function getStatusVariant(status: Report['status']) {
|
|
|
|
|
|
export default function ReportsScreen() {
|
|
|
const [activeTab, setActiveTab] = useState<ReportTab>('全部');
|
|
|
+ const insets = useSafeAreaInsets();
|
|
|
+
|
|
|
+ const scrollOffsetY = useSharedValue(0);
|
|
|
+ const scrollHandler = useAnimatedScrollHandler((e) => {
|
|
|
+ scrollOffsetY.value = e.contentOffset.y;
|
|
|
+ });
|
|
|
+ const headerStyle = useAnimatedStyle(() => ({
|
|
|
+ opacity: interpolate(scrollOffsetY.value, [0, 24 + insets.top], [0, 1], Extrapolation.CLAMP),
|
|
|
+ }));
|
|
|
|
|
|
const filteredReports = REPORTS.filter(
|
|
|
(item) => activeTab === '全部' || item.type === activeTab
|
|
|
@@ -99,205 +111,218 @@ export default function ReportsScreen() {
|
|
|
const completedCount = REPORTS.filter((item) => item.status === '已完成').length;
|
|
|
|
|
|
return (
|
|
|
- <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
|
|
|
- <ScrollView
|
|
|
- className="flex-1"
|
|
|
- contentContainerClassName="px-5 pt-3 pb-24"
|
|
|
- showsVerticalScrollIndicator={false}
|
|
|
- >
|
|
|
- <Text className="mb-2 text-3xl font-extrabold tracking-tight text-on-surface">
|
|
|
- 报表
|
|
|
- </Text>
|
|
|
- <Text className="mb-5 text-base leading-7 text-on-surface-variant">
|
|
|
- 汇总查看征信分析结果、匹配建议和当前处理进度
|
|
|
- </Text>
|
|
|
|
|
|
- <View className="mb-5 flex-row gap-2.5">
|
|
|
- <View className="flex-1 items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-3 py-3.5">
|
|
|
- <Text className="text-2xl font-extrabold text-primary">{REPORTS.length}</Text>
|
|
|
- <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
- 总报告数
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
- <View className="flex-1 items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-3 py-3.5">
|
|
|
- <Text className="text-2xl font-extrabold text-primary">{completedCount}</Text>
|
|
|
- <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
- 已完成
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
- <View className="flex-1 items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-3 py-3.5">
|
|
|
- <Text className="text-2xl font-extrabold text-primary">92%</Text>
|
|
|
- <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
- 最高匹配
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
+ <Animated.ScrollView
|
|
|
+ className="flex-1"
|
|
|
+ contentInset={{ top: insets.top, bottom: insets.bottom }}
|
|
|
+ automaticallyAdjustContentInsets
|
|
|
+ contentContainerClassName="px-5 pt-3 pb-24"
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ onScroll={scrollHandler}
|
|
|
+ scrollEventThrottle={16}
|
|
|
+ >
|
|
|
+ <Stack.Screen options={{
|
|
|
+ headerShown: true,
|
|
|
+ headerTransparent: true,
|
|
|
+ header: () => (
|
|
|
+ <Animated.View style={headerStyle} className="border-b border-outline-variant/60 android:bg-surface-container-lowest/90">
|
|
|
+ <BlurView tint="light" className="bg-background">
|
|
|
+ <Text style={{ marginTop: insets.top }} className="pl-10 h-[44px] text-3xl font-extrabold tracking-tight text-on-surface">
|
|
|
+ 报表
|
|
|
+ </Text>
|
|
|
+ </BlurView>
|
|
|
+ </Animated.View>
|
|
|
+ ),
|
|
|
+ }} />
|
|
|
+ <Text className="h-[44px] text-3xl font-extrabold tracking-tight text-on-surface">
|
|
|
+ 报表
|
|
|
+ </Text>
|
|
|
+ <Text className="mb-5 text-base leading-7 text-on-surface-variant">
|
|
|
+ 汇总查看征信分析结果、匹配建议和当前处理进度
|
|
|
+ </Text>
|
|
|
+
|
|
|
+ <View className="mb-5 flex-row gap-2.5">
|
|
|
+ <View className="flex-1 items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-3 py-3.5">
|
|
|
+ <Text className="text-2xl font-extrabold text-primary">{REPORTS.length}</Text>
|
|
|
+ <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
+ 总报告数
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <View className="flex-1 items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-3 py-3.5">
|
|
|
+ <Text className="text-2xl font-extrabold text-primary">{completedCount}</Text>
|
|
|
+ <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
+ 已完成
|
|
|
+ </Text>
|
|
|
</View>
|
|
|
+ <View className="flex-1 items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-3 py-3.5">
|
|
|
+ <Text className="text-2xl font-extrabold text-primary">92%</Text>
|
|
|
+ <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
|
|
|
+ 最高匹配
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="mb-5 rounded-2xl bg-surface-container-low p-1">
|
|
|
- <View className="flex-row">
|
|
|
- {TABS.map((tab) => {
|
|
|
- const active = activeTab === tab;
|
|
|
- return (
|
|
|
- <Pressable
|
|
|
- key={tab}
|
|
|
- onPress={() => setActiveTab(tab)}
|
|
|
- className={`flex-1 rounded-xl py-2.5 ${
|
|
|
- active ? 'bg-surface-container-lowest' : ''
|
|
|
+ <View className="mb-5 rounded-2xl bg-surface-container-low p-1">
|
|
|
+ <View className="flex-row">
|
|
|
+ {TABS.map((tab) => {
|
|
|
+ const active = activeTab === tab;
|
|
|
+ return (
|
|
|
+ <Pressable
|
|
|
+ key={tab}
|
|
|
+ onPress={() => setActiveTab(tab)}
|
|
|
+ className={`flex-1 rounded-xl py-2.5 ${active ? 'bg-surface-container-lowest' : ''
|
|
|
}`}
|
|
|
- style={({ pressed }) => ({
|
|
|
- opacity: pressed ? 0.88 : 1,
|
|
|
- })}
|
|
|
- >
|
|
|
- <Text
|
|
|
- className={`text-center text-sm font-bold ${
|
|
|
- active ? 'text-primary' : 'text-on-surface-variant'
|
|
|
+ style={({ pressed }) => ({
|
|
|
+ opacity: pressed ? 0.88 : 1,
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ <Text
|
|
|
+ className={`text-center text-sm font-bold ${active ? 'text-primary' : 'text-on-surface-variant'
|
|
|
}`}
|
|
|
- >
|
|
|
- {tab}
|
|
|
- </Text>
|
|
|
- </Pressable>
|
|
|
- );
|
|
|
- })}
|
|
|
- </View>
|
|
|
+ >
|
|
|
+ {tab}
|
|
|
+ </Text>
|
|
|
+ </Pressable>
|
|
|
+ );
|
|
|
+ })}
|
|
|
</View>
|
|
|
+ </View>
|
|
|
|
|
|
- <View className="gap-3">
|
|
|
- {filteredReports.map((report) => (
|
|
|
- <Pressable
|
|
|
- key={report.id}
|
|
|
- className="rounded-2xl border border-outline-variant bg-surface-container-lowest px-4 py-4"
|
|
|
- style={({ pressed }) => ({
|
|
|
- opacity: pressed ? 0.93 : 1,
|
|
|
- })}
|
|
|
- >
|
|
|
- <View className="mb-3 flex-row items-start justify-between gap-3">
|
|
|
- <View className="flex-1 flex-row items-center gap-3">
|
|
|
- <View
|
|
|
- className={`h-11 w-11 items-center justify-center rounded-2xl ${
|
|
|
- report.type === '征信报告' ? 'bg-blue-50' : 'bg-green-50'
|
|
|
+ <View className="gap-3">
|
|
|
+ {filteredReports.map((report) => (
|
|
|
+ <Pressable
|
|
|
+ key={report.id}
|
|
|
+ className="rounded-2xl border border-outline-variant bg-surface-container-lowest px-4 py-4"
|
|
|
+ style={({ pressed }) => ({
|
|
|
+ opacity: pressed ? 0.93 : 1,
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ <View className="mb-3 flex-row items-start justify-between gap-3">
|
|
|
+ <View className="flex-1 flex-row items-center gap-3">
|
|
|
+ <View
|
|
|
+ className={`h-11 w-11 items-center justify-center rounded-2xl ${report.type === '征信报告' ? 'bg-blue-50' : 'bg-green-50'
|
|
|
}`}
|
|
|
- >
|
|
|
- <Ionicons
|
|
|
- name={
|
|
|
- report.type === '征信报告'
|
|
|
- ? 'document-text-outline'
|
|
|
- : 'git-compare-outline'
|
|
|
- }
|
|
|
- size={20}
|
|
|
- color={report.type === '征信报告' ? '#2563eb' : '#16a34a'}
|
|
|
- />
|
|
|
- </View>
|
|
|
- <View className="flex-1">
|
|
|
- <Text className="text-lg font-bold text-on-surface">
|
|
|
- {report.customerName}
|
|
|
- </Text>
|
|
|
- <Text className="mt-1 text-sm text-on-surface-variant">
|
|
|
- {report.type}
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
- </View>
|
|
|
- <View className="items-end">
|
|
|
- <Text className="mb-1.5 text-xs text-on-surface-variant">{report.time}</Text>
|
|
|
- <StatusBadge
|
|
|
- text={report.status}
|
|
|
- variant={getStatusVariant(report.status)}
|
|
|
+ >
|
|
|
+ <Ionicons
|
|
|
+ name={
|
|
|
+ report.type === '征信报告'
|
|
|
+ ? 'document-text-outline'
|
|
|
+ : 'git-compare-outline'
|
|
|
+ }
|
|
|
+ size={20}
|
|
|
+ color={report.type === '征信报告' ? '#2563eb' : '#16a34a'}
|
|
|
/>
|
|
|
</View>
|
|
|
- </View>
|
|
|
-
|
|
|
- {report.type === '征信报告' && report.status === '已完成' ? (
|
|
|
- <View>
|
|
|
- <View className="mb-3 flex-row items-center gap-3">
|
|
|
- <View className="h-14 w-14 items-center justify-center rounded-full border-4 border-primary-fixed bg-surface-container-lowest">
|
|
|
- <Text className="text-lg font-extrabold text-primary">
|
|
|
- {report.score}
|
|
|
- </Text>
|
|
|
- </View>
|
|
|
- <View className="flex-1">
|
|
|
- <Text className="mb-1.5 text-sm text-on-surface-variant">关键标签</Text>
|
|
|
- <View className="flex-row flex-wrap gap-2">
|
|
|
- {report.tags?.map((tag) => (
|
|
|
- <StatusBadge
|
|
|
- key={`${report.id}-${tag.text}`}
|
|
|
- text={tag.text}
|
|
|
- variant={tag.variant}
|
|
|
- />
|
|
|
- ))}
|
|
|
- </View>
|
|
|
- </View>
|
|
|
- </View>
|
|
|
- <Text className="text-sm leading-6 text-on-surface-variant">
|
|
|
- 建议可申请额度:20万-35万,优先推荐更看重流水稳定性的产品。
|
|
|
+ <View className="flex-1">
|
|
|
+ <Text className="text-lg font-bold text-on-surface">
|
|
|
+ {report.customerName}
|
|
|
+ </Text>
|
|
|
+ <Text className="mt-1 text-sm text-on-surface-variant">
|
|
|
+ {report.type}
|
|
|
</Text>
|
|
|
</View>
|
|
|
- ) : null}
|
|
|
+ </View>
|
|
|
+ <View className="items-end">
|
|
|
+ <Text className="mb-1.5 text-xs text-on-surface-variant">{report.time}</Text>
|
|
|
+ <StatusBadge
|
|
|
+ text={report.status}
|
|
|
+ variant={getStatusVariant(report.status)}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
|
|
|
- {report.type === '匹配结果' && report.status === '已完成' ? (
|
|
|
- <View className="flex-row gap-2.5">
|
|
|
- <View className="flex-1 rounded-xl bg-surface-container-low px-4 py-3.5">
|
|
|
- <Text className="text-2xl font-bold text-on-surface">
|
|
|
- {report.matchCount}
|
|
|
- </Text>
|
|
|
- <Text className="mt-1 text-xs text-on-surface-variant">匹配产品数</Text>
|
|
|
- </View>
|
|
|
- <View className="flex-1 rounded-xl bg-surface-container-low px-4 py-3.5">
|
|
|
- <Text className="text-2xl font-bold text-primary">
|
|
|
- {report.matchRate}
|
|
|
+ {report.type === '征信报告' && report.status === '已完成' ? (
|
|
|
+ <View>
|
|
|
+ <View className="mb-3 flex-row items-center gap-3">
|
|
|
+ <View className="h-14 w-14 items-center justify-center rounded-full border-4 border-primary-fixed bg-surface-container-lowest">
|
|
|
+ <Text className="text-lg font-extrabold text-primary">
|
|
|
+ {report.score}
|
|
|
</Text>
|
|
|
- <Text className="mt-1 text-xs text-on-surface-variant">最高匹配度</Text>
|
|
|
- </View>
|
|
|
- </View>
|
|
|
- ) : null}
|
|
|
-
|
|
|
- {report.status === '解析中' ? (
|
|
|
- <View className="mt-1">
|
|
|
- <View className="mb-2 flex-row items-center justify-between">
|
|
|
- <Text className="text-sm text-on-surface-variant">正在生成报告...</Text>
|
|
|
- <Text className="text-sm font-bold text-primary">72%</Text>
|
|
|
</View>
|
|
|
- <View className="h-1.5 rounded-full bg-surface-container">
|
|
|
- <View
|
|
|
- className="h-full rounded-full bg-primary-container"
|
|
|
- style={{ width: '72%' }}
|
|
|
- />
|
|
|
+ <View className="flex-1">
|
|
|
+ <Text className="mb-1.5 text-sm text-on-surface-variant">关键标签</Text>
|
|
|
+ <View className="flex-row flex-wrap gap-2">
|
|
|
+ {report.tags?.map((tag) => (
|
|
|
+ <StatusBadge
|
|
|
+ key={`${report.id}-${tag.text}`}
|
|
|
+ text={tag.text}
|
|
|
+ variant={tag.variant}
|
|
|
+ />
|
|
|
+ ))}
|
|
|
+ </View>
|
|
|
</View>
|
|
|
</View>
|
|
|
- ) : null}
|
|
|
-
|
|
|
- {report.status === '待匹配' ? (
|
|
|
<Text className="text-sm leading-6 text-on-surface-variant">
|
|
|
- 当前客户信息已同步,待进入智能匹配流程生成推荐结果。
|
|
|
+ 建议可申请额度:20万-35万,优先推荐更看重流水稳定性的产品。
|
|
|
</Text>
|
|
|
- ) : null}
|
|
|
+ </View>
|
|
|
+ ) : null}
|
|
|
|
|
|
- {report.status === '已完成' ? (
|
|
|
- <View className="mt-3 flex-row gap-2.5">
|
|
|
- <Pressable
|
|
|
- className="flex-1 items-center rounded-xl bg-primary-container py-2.5"
|
|
|
- style={({ pressed }) => ({
|
|
|
- opacity: pressed ? 0.88 : 1,
|
|
|
- })}
|
|
|
- >
|
|
|
- <Text className="text-sm font-bold text-on-primary">
|
|
|
- {report.type === '征信报告' ? '查看详情' : '查看匹配'}
|
|
|
- </Text>
|
|
|
- </Pressable>
|
|
|
- <Pressable
|
|
|
- className="flex-1 items-center rounded-xl bg-surface-container-high py-2.5"
|
|
|
- style={({ pressed }) => ({
|
|
|
- opacity: pressed ? 0.88 : 1,
|
|
|
- })}
|
|
|
- >
|
|
|
- <Text className="text-sm font-semibold text-on-surface">
|
|
|
- {report.type === '征信报告' ? '智能匹配' : '重新匹配'}
|
|
|
- </Text>
|
|
|
- </Pressable>
|
|
|
+ {report.type === '匹配结果' && report.status === '已完成' ? (
|
|
|
+ <View className="flex-row gap-2.5">
|
|
|
+ <View className="flex-1 rounded-xl bg-surface-container-low px-4 py-3.5">
|
|
|
+ <Text className="text-2xl font-bold text-on-surface">
|
|
|
+ {report.matchCount}
|
|
|
+ </Text>
|
|
|
+ <Text className="mt-1 text-xs text-on-surface-variant">匹配产品数</Text>
|
|
|
</View>
|
|
|
- ) : null}
|
|
|
- </Pressable>
|
|
|
- ))}
|
|
|
- </View>
|
|
|
- </ScrollView>
|
|
|
- </SafeAreaView>
|
|
|
+ <View className="flex-1 rounded-xl bg-surface-container-low px-4 py-3.5">
|
|
|
+ <Text className="text-2xl font-bold text-primary">
|
|
|
+ {report.matchRate}
|
|
|
+ </Text>
|
|
|
+ <Text className="mt-1 text-xs text-on-surface-variant">最高匹配度</Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {report.status === '解析中' ? (
|
|
|
+ <View className="mt-1">
|
|
|
+ <View className="mb-2 flex-row items-center justify-between">
|
|
|
+ <Text className="text-sm text-on-surface-variant">正在生成报告...</Text>
|
|
|
+ <Text className="text-sm font-bold text-primary">72%</Text>
|
|
|
+ </View>
|
|
|
+ <View className="h-1.5 rounded-full bg-surface-container">
|
|
|
+ <View
|
|
|
+ className="h-full rounded-full bg-primary-container"
|
|
|
+ style={{ width: '72%' }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {report.status === '待匹配' ? (
|
|
|
+ <Text className="text-sm leading-6 text-on-surface-variant">
|
|
|
+ 当前客户信息已同步,待进入智能匹配流程生成推荐结果。
|
|
|
+ </Text>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {report.status === '已完成' ? (
|
|
|
+ <View className="mt-3 flex-row gap-2.5">
|
|
|
+ <Pressable
|
|
|
+ className="flex-1 items-center rounded-xl bg-primary-container py-2.5"
|
|
|
+ style={({ pressed }) => ({
|
|
|
+ opacity: pressed ? 0.88 : 1,
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ <Text className="text-sm font-bold text-on-primary">
|
|
|
+ {report.type === '征信报告' ? '查看详情' : '查看匹配'}
|
|
|
+ </Text>
|
|
|
+ </Pressable>
|
|
|
+ <Pressable
|
|
|
+ className="flex-1 items-center rounded-xl bg-surface-container-high py-2.5"
|
|
|
+ style={({ pressed }) => ({
|
|
|
+ opacity: pressed ? 0.88 : 1,
|
|
|
+ })}
|
|
|
+ >
|
|
|
+ <Text className="text-sm font-semibold text-on-surface">
|
|
|
+ {report.type === '征信报告' ? '智能匹配' : '重新匹配'}
|
|
|
+ </Text>
|
|
|
+ </Pressable>
|
|
|
+ </View>
|
|
|
+ ) : null}
|
|
|
+ </Pressable>
|
|
|
+ ))}
|
|
|
+ </View>
|
|
|
+ </Animated.ScrollView>
|
|
|
);
|
|
|
}
|