analytics.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import { SectionHeader } from '@/components/ui/section-header';
  2. import { Ionicons } from '@expo/vector-icons';
  3. import React, { useCallback, useState } from 'react';
  4. import { Pressable, ScrollView, Text, View } from 'react-native';
  5. import { SafeAreaView } from 'react-native-safe-area-context';
  6. import { UploadComponent } from '../credit/upload';
  7. type AnalysisMode = 'fast' | 'deep';
  8. type AnalysisRecord = {
  9. id: string;
  10. customerName: string;
  11. time: string;
  12. status: '解析中' | '已完成' | '解析失败';
  13. progress?: number;
  14. score?: string;
  15. };
  16. const ANALYSIS_RECORDS: AnalysisRecord[] = [
  17. { id: '1', customerName: '张德发', time: '今天 10:42', status: '已完成', score: 'B+' },
  18. { id: '2', customerName: '钱进', time: '今天 10:05', status: '解析中', progress: 72 },
  19. { id: '3', customerName: '李美华', time: '昨天 15:20', status: '已完成', score: 'A' },
  20. { id: '4', customerName: '赵丽', time: '3天前', status: '解析失败' },
  21. ];
  22. export default function AnalyticsScreen() {
  23. const [analysisMode, setAnalysisMode] = useState<AnalysisMode>('fast');
  24. const onUploadCredit = useCallback(() => {
  25. }, []);
  26. return (
  27. <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
  28. <ScrollView
  29. className="flex-1"
  30. contentContainerClassName="px-5 pt-3 pb-24"
  31. showsVerticalScrollIndicator={false}
  32. >
  33. <Text className="mb-2 text-3xl font-extrabold tracking-tight text-on-surface">
  34. 征信分析
  35. </Text>
  36. <Text className="mb-6 text-base leading-7 text-on-surface-variant">
  37. 先选择客户,再上传征信文件,系统会自动生成评分和建议动作
  38. </Text>
  39. <View className="mb-3 rounded-2xl border border-outline-variant bg-surface-container-lowest p-4">
  40. <Text className="mb-3 text-xs font-bold uppercase tracking-widest text-outline">
  41. 选择客户
  42. </Text>
  43. <Pressable
  44. className="flex-row items-center rounded-2xl bg-surface-container-low px-4 py-3.5"
  45. style={({ pressed }) => ({
  46. opacity: pressed ? 0.9 : 1,
  47. })}
  48. >
  49. <Ionicons name="person-outline" size={18} color="#737686" />
  50. <Text className="ml-3 flex-1 text-base font-medium text-on-surface">
  51. 张德发(138****8888)
  52. </Text>
  53. <Ionicons name="chevron-down" size={18} color="#c3c6d7" />
  54. </Pressable>
  55. </View>
  56. <UploadComponent onCompolete={onUploadCredit} />
  57. <SectionHeader title="解析记录" actionText="查看全部" />
  58. <View className="gap-3">
  59. {ANALYSIS_RECORDS.map((record) => (
  60. <Pressable
  61. key={record.id}
  62. className="flex-row items-center rounded-2xl border border-outline-variant bg-surface-container-lowest px-4 py-3.5"
  63. style={({ pressed }) => ({
  64. opacity: pressed ? 0.93 : 1,
  65. })}
  66. >
  67. <View
  68. className={`mr-3 h-11 w-11 items-center justify-center rounded-full ${record.status === '已完成'
  69. ? 'bg-green-50'
  70. : record.status === '解析中'
  71. ? 'bg-blue-50'
  72. : 'bg-error-container'
  73. }`}
  74. >
  75. <Ionicons
  76. name={
  77. record.status === '已完成'
  78. ? 'checkmark-circle'
  79. : record.status === '解析中'
  80. ? 'hourglass-outline'
  81. : 'alert-circle'
  82. }
  83. size={20}
  84. color={
  85. record.status === '已完成'
  86. ? '#16a34a'
  87. : record.status === '解析中'
  88. ? '#2563eb'
  89. : '#ba1a1a'
  90. }
  91. />
  92. </View>
  93. <View className="flex-1">
  94. <View className="mb-1 flex-row items-center justify-between gap-3">
  95. <Text className="text-base font-bold text-on-surface">
  96. {record.customerName}
  97. </Text>
  98. <Text className="text-xs text-on-surface-variant">{record.time}</Text>
  99. </View>
  100. {record.status === '解析中' && record.progress != null ? (
  101. <View>
  102. <View className="mb-2 flex-row items-center justify-between">
  103. <Text className="text-sm text-on-surface-variant">正在解析征信数据...</Text>
  104. <Text className="text-sm font-bold text-primary">
  105. {record.progress}%
  106. </Text>
  107. </View>
  108. <View className="h-1.5 rounded-full bg-surface-container">
  109. <View
  110. className="h-full rounded-full bg-primary-container"
  111. style={{ width: `${record.progress}%` }}
  112. />
  113. </View>
  114. </View>
  115. ) : record.status === '已完成' ? (
  116. <View className="flex-row items-center gap-2">
  117. <Text className="text-sm text-on-surface-variant">征信评分</Text>
  118. <View className="rounded-full bg-primary-fixed px-2.5 py-1">
  119. <Text className="text-xs font-bold text-primary">{record.score}</Text>
  120. </View>
  121. </View>
  122. ) : (
  123. <Text className="text-sm text-error">解析失败,请重新上传文件后重试</Text>
  124. )}
  125. </View>
  126. <Ionicons name="chevron-forward" size={18} color="#c3c6d7" />
  127. </Pressable>
  128. ))}
  129. </View>
  130. </ScrollView>
  131. </SafeAreaView>
  132. );
  133. }