import UIButton from "@/components/ui/UIButton";
import { Colors } from "@/constants/theme";
import { ActionSheet, ActivityIndicator, Icon, Modal, Toast } from "@ant-design/react-native";
import { Ionicons } from '@expo/vector-icons';
import { Platform, Pressable, Text, View } from "react-native";
import api from "@/utils/api";
import { openSystemSettings } from "@/utils/os";
import clsx from "clsx";
import { DocumentPickerAsset, getDocumentAsync } from 'expo-document-picker';
import { File } from 'expo-file-system';
import { ImagePickerAsset, launchCameraAsync, launchImageLibraryAsync, requestCameraPermissionsAsync, requestMediaLibraryPermissionsAsync } from 'expo-image-picker';
import { Link } from "expo-router";
import { useCallback, useEffect, useState } from "react";
const takePhoto = async (upload: (assets: ImagePickerAsset[] | DocumentPickerAsset[]) => void) => {
const permission = await requestCameraPermissionsAsync();
if (!permission.granted) {
Modal.alert("请允许相册权限", "如果点击“确认“按钮后没有跳转,请自己前往系统设置开启相关权限", [
{
text: "确认",
onPress: openSystemSettings,
}
]);
// 跳转到 ios/android 相关设置页面
return;
}
const l = Toast.loading('正在打开相机...');
try {
const result = await launchCameraAsync({
allowsEditing: false, // 是否允许裁剪
quality: 0.9, // 照片质量
});
if (!result.canceled) {
upload(result.assets);
}
} catch (err) {
console.warn(err);
Toast.fail('打开相机失败,请重试');
}
finally {
Toast.remove(l);
}
}
const picImg = async (upload: (assets: ImagePickerAsset[] | DocumentPickerAsset[]) => void) => {
const permission = await requestMediaLibraryPermissionsAsync();
if (!permission.granted) {
Modal.alert("请允许相册权限", "如果点击“确认“按钮后没有跳转,请自己前往系统设置开启相关权限", [
{
text: "确认",
onPress: openSystemSettings,
}
]);
// 跳转到 ios/android 相关设置页面
return;
}
const l = Toast.loading('正在打开相册...');
try {
let result = await launchImageLibraryAsync({
mediaTypes: ['images'], // 只选图片
allowsEditing: false,
quality: .9, // 质量 0~1
});
if (!result.canceled) {
upload(result.assets);
}
} catch (err) {
console.warn(err);
Toast.fail('打开相册失败,请重试');
} finally {
Toast.remove(l);
}
}
const pickDoc = async (upload: (assets: ImagePickerAsset[] | DocumentPickerAsset[]) => void) => {
const l = Toast.loading('正在打开相册...');
try {
let result = await getDocumentAsync({
type: [
// PDF
'application/pdf',
// Word 文档
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
// Excel 表格
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
// WPS 文字 / WPS 表格
'application/wps-office.doc',
'application/wps-office.docx',
'application/wps-office.xls',
'application/wps-office.xlsx',
'application/wps-office.et',
'application/wps-office.wps',
// 纯文本
'text/plain',
// HTML
'text/html',
// 全部图片(jpg/png/gif/webp 等)
'image/*'
],
copyToCacheDirectory: true, // 复制到应用缓存目录
});
if (!result.canceled) {
upload(result.assets);
}
} catch (err) {
console.warn(err);
Toast.fail('打开文件失败,请重试');
}
finally {
Toast.remove(l);
}
};
export function UploadScreen({ visible, onClose }: { visible: boolean, onClose: () => void }) {
useEffect(() => {
if (!visible) {
setState(0);
}
}, [visible]);
const [state, setState] = useState(0);
const upload = useCallback(async (assets: ImagePickerAsset[] | DocumentPickerAsset[]) => {
setState(1);
let att: { url: string, fullurl: string, attid: any } = null!;
try {
const file = new File(assets[0].uri);
// file.type = item.mimeType || 'application/octet-stream';
const formData = new FormData();
formData.append('file', file);
att = await api.uploadFile<{ url: string, fullurl: string, attid: any }>('common/upload', { body: formData });
} catch (err) {
setState(0);
console.warn(err);
Toast.fail('上传失败,请重试');
return;
}
try {
await api.post('/credit/create', {
att: JSON.stringify(att),
});
setState(2);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (err) {
setState(0);
Toast.fail('添加分析到队列失败,请重试');
}
}, []);
return (
征信分析
{state === 0 && (
请选择征信上传方式
pickDoc(upload)} className="mt-8" />
{Platform.OS === 'ios' && picImg(upload)} className="mt-4" />}
takePhoto(upload)} className="mt-4" />
)}
{
state === 1 && (
)
}
{
state === 2 && (
<>
AI 正在分析
分析页
查看状态和结果
>
)
}
{state != 1 && { onClose(); }}>
}
);
}
export function UploadComponent({ customerId, onCompolete }: { customerId?: number, onCompolete: () => void }) {
const [state, setState] = useState(0);
const upload = useCallback(async (assets: ImagePickerAsset[] | DocumentPickerAsset[]) => {
setState(1);
let att: { url: string, fullurl: string, attid: any } = null!;
try {
const file = new File(assets[0].uri);
// file.type = item.mimeType || 'application/octet-stream';
const formData = new FormData();
formData.append('file', file);
att = await api.uploadFile<{ url: string, fullurl: string, attid: any }>('common/upload', { body: formData });
} catch (err) {
setState(0);
console.warn(err);
Toast.fail('上传失败,请重试');
return;
}
try {
await api.post('/credit/create', {
att: JSON.stringify(att),
});
setState(0);
onCompolete?.();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (err) {
setState(0);
Toast.fail('添加分析到队列失败,请重试');
}
}, [onCompolete]);
const onSelect = useCallback((index: number) => {
if (Platform.OS == 'android' && index == 2) {
return;
}
if (Platform.OS == 'ios' && index == 3) {
return;
}
if (index == 0) {
pickDoc(upload);
}
if (index == 1) {
if (Platform.OS == 'ios') {
picImg(upload);
} else {
takePhoto(upload);
}
}
if (index == 2) {
takePhoto(upload);
}
}, []);
const selectFile = useCallback(() => {
ActionSheet.showActionSheetWithOptions({
title: "请选择征信上传方式",
cancelButtonIndex: 3,
options: Platform.OS == 'ios' ? ['从本机文件', '从手机相册', '拍照上传', '取消'] : ['从本机文件', '拍照上传', '取消']
}, onSelect);
}, []);
return (
<>
上传征信文件
{state == 1 ? :
点击上传征信报告}
支持 PDF、图片格式,最大 20MB
>
);
}