enhance: 类型问题
This commit is contained in:
parent
2505df0182
commit
f63497f3a1
@ -1,8 +1,7 @@
|
|||||||
import { addMaterial, confirmUpload, getUploadUrl } from '@/lib/background-uploader/api';
|
import { addMaterial, confirmUpload, getUploadUrl } from '@/lib/background-uploader/api';
|
||||||
import { ConfirmUpload, FileUploadItem, UploadResult, UploadTask } from '@/lib/background-uploader/types';
|
import { ConfirmUpload, FileUploadItem, UploadResult, UploadTask, ImagesuploaderProps, ExifData, defaultExifData } from '@/lib/background-uploader/types';
|
||||||
import { uploadFileWithProgress } from '@/lib/background-uploader/uploader';
|
import { uploadFileWithProgress } from '@/lib/background-uploader/uploader';
|
||||||
import { compressImage } from '@/lib/image-process/imageCompress';
|
import { compressImage } from '@/lib/image-process/imageCompress';
|
||||||
import { defaultExifData, ExifData, ImagesuploaderProps } from '@/types/upload';
|
|
||||||
import * as ImageManipulator from 'expo-image-manipulator';
|
import * as ImageManipulator from 'expo-image-manipulator';
|
||||||
import * as ImagePicker from 'expo-image-picker';
|
import * as ImagePicker from 'expo-image-picker';
|
||||||
import * as Location from 'expo-location';
|
import * as Location from 'expo-location';
|
||||||
@ -24,7 +23,7 @@ export const ImagesUploader: React.FC<ImagesuploaderProps> = ({
|
|||||||
fileType = ['images'],
|
fileType = ['images'],
|
||||||
}) => {
|
}) => {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [files, setFiles] = useState<FileUploadItem[]>([]);
|
||||||
const [uploadQueue, setUploadQueue] = useState<FileUploadItem[]>([]);
|
const [uploadQueue, setUploadQueue] = useState<FileUploadItem[]>([]);
|
||||||
|
|
||||||
// 请求权限
|
// 请求权限
|
||||||
@ -63,12 +62,14 @@ export const ImagesUploader: React.FC<ImagesuploaderProps> = ({
|
|||||||
// 创建上传项
|
// 创建上传项
|
||||||
const newFileItem: FileUploadItem = {
|
const newFileItem: FileUploadItem = {
|
||||||
id: fileId,
|
id: fileId,
|
||||||
|
uri: asset.uri,
|
||||||
|
previewUrl: asset.uri, // 使用 asset.uri 作为初始预览
|
||||||
name: asset.fileName || 'file',
|
name: asset.fileName || 'file',
|
||||||
progress: 0,
|
progress: 0,
|
||||||
status: 'uploading' as const,
|
status: 'uploading',
|
||||||
error: null,
|
error: undefined,
|
||||||
type: isVideo ? 'video' : 'image',
|
type: isVideo ? 'video' : 'image',
|
||||||
thumbnail: null,
|
thumbnail: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
setUploadQueue(prev => [...prev, newFileItem]);
|
setUploadQueue(prev => [...prev, newFileItem]);
|
||||||
@ -190,7 +191,7 @@ export const ImagesUploader: React.FC<ImagesuploaderProps> = ({
|
|||||||
item.id === fileId
|
item.id === fileId
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
status: 'done' as const,
|
status: 'success' as const,
|
||||||
progress: 100,
|
progress: 100,
|
||||||
thumbnail: uploadResults.thumbnail
|
thumbnail: uploadResults.thumbnail
|
||||||
}
|
}
|
||||||
|
|||||||
@ -159,7 +159,7 @@ export const processMediaUpload = async (asset: ExtendedAsset) => {
|
|||||||
const originalResult = await uploadOriginalFile();
|
const originalResult = await uploadOriginalFile();
|
||||||
|
|
||||||
// 如果是图片,再上传压缩文件
|
// 如果是图片,再上传压缩文件
|
||||||
let compressedResult = { success: true, file_id: null };
|
let compressedResult: { success: boolean; file_id?: string | null; error?: any } = { success: true, file_id: null };
|
||||||
if (!isVideo) {
|
if (!isVideo) {
|
||||||
compressedResult = await uploadCompressedFile();
|
compressedResult = await uploadCompressedFile();
|
||||||
// 添加素材
|
// 添加素材
|
||||||
|
|||||||
@ -15,16 +15,95 @@ export type UploadTask = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 上传队列项
|
// 文件元数据信息
|
||||||
export type FileUploadItem = {
|
interface FileSize {
|
||||||
|
value: number;
|
||||||
|
unit: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FileMetadata {
|
||||||
|
originalName: string;
|
||||||
|
type: string;
|
||||||
|
isCompressed: string;
|
||||||
|
fileType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后端返回的文件信息
|
||||||
|
interface FileInfo {
|
||||||
|
file_id: number;
|
||||||
|
name: string;
|
||||||
|
size: FileSize;
|
||||||
|
content_type: string; // 这里与 ConfirmUpload 的 content_type 定义不同,需要注意
|
||||||
|
upload_time: string;
|
||||||
|
storage_medium: string;
|
||||||
|
file_path: string; // 这里与 ConfirmUpload 的 file_path 定义不同
|
||||||
|
uploader_id: number;
|
||||||
|
upload_status: string;
|
||||||
|
deletion_status: string;
|
||||||
|
metadata: FileMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传队列项 - 作为唯一的类型定义
|
||||||
|
// 定义 EXIF 数据类型
|
||||||
|
export type ExifData = {
|
||||||
|
GPSLatitude?: number | undefined;
|
||||||
|
GPSLongitude?: number | undefined;
|
||||||
|
GPSAltitude?: number | undefined;
|
||||||
|
DateTimeOriginal?: string | undefined;
|
||||||
|
Make?: string | undefined;
|
||||||
|
Model?: string | undefined;
|
||||||
|
ExposureTime?: number | undefined;
|
||||||
|
FNumber?: number | undefined;
|
||||||
|
ISOSpeedRatings?: number | undefined;
|
||||||
|
FocalLength?: number | undefined;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 默认的 EXIF 数据结构
|
||||||
|
export const defaultExifData: ExifData = {
|
||||||
|
GPSLatitude: undefined,
|
||||||
|
GPSLongitude: undefined,
|
||||||
|
GPSAltitude: undefined,
|
||||||
|
DateTimeOriginal: undefined,
|
||||||
|
Make: undefined,
|
||||||
|
Model: undefined,
|
||||||
|
ExposureTime: undefined,
|
||||||
|
FNumber: undefined,
|
||||||
|
ISOSpeedRatings: undefined,
|
||||||
|
FocalLength: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 压缩图片可配置参数
|
||||||
|
export interface ImagesuploaderProps {
|
||||||
|
children?: React.ReactNode;
|
||||||
|
style?: import('react-native').StyleProp<import('react-native').ViewStyle>;
|
||||||
|
onPickImage?: (file: File, exifData: ExifData) => void;
|
||||||
|
compressQuality?: number;
|
||||||
|
maxWidth?: number;
|
||||||
|
maxHeight?: number;
|
||||||
|
preserveExif?: boolean;
|
||||||
|
uploadOriginal?: boolean;
|
||||||
|
onUploadComplete?: (result: FileUploadItem[]) => void;
|
||||||
|
onProgress?: (progress: any) => void; // TODO: Define a proper type for progress
|
||||||
|
multipleChoice?: boolean;
|
||||||
|
fileType?: any[]; // TODO: Use MediaType from expo-image-picker
|
||||||
|
showPreview?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileUploadItem {
|
||||||
id: string;
|
id: string;
|
||||||
|
uri: string; // 用于本地展示的资源URI
|
||||||
name: string;
|
name: string;
|
||||||
progress: number;
|
progress: number;
|
||||||
status: 'pending' | 'uploading' | 'done' | 'error';
|
status: 'pending' | 'uploading' | 'success' | 'error'; // 统一状态
|
||||||
error: string | null;
|
error?: string | null;
|
||||||
|
previewUrl: string; // 预览URL
|
||||||
|
file?: File;
|
||||||
type: 'image' | 'video';
|
type: 'image' | 'video';
|
||||||
thumbnail: string | null;
|
thumbnail?: string; // 缩略图URL
|
||||||
};
|
thumbnailFile?: File; // 缩略图文件对象
|
||||||
|
originalFile?: FileInfo // 上传后返回的文件信息
|
||||||
|
}
|
||||||
|
|
||||||
// 确认上传返回
|
// 确认上传返回
|
||||||
export type ConfirmUpload = {
|
export type ConfirmUpload = {
|
||||||
|
|||||||
210
types/upload.ts
210
types/upload.ts
@ -1,210 +0,0 @@
|
|||||||
import { MediaType } from "expo-image-picker";
|
|
||||||
import { ReactNode } from "react";
|
|
||||||
import { StyleProp, ViewStyle } from "react-native";
|
|
||||||
|
|
||||||
export interface FileStatus {
|
|
||||||
file: File;
|
|
||||||
status: 'pending' | 'uploading' | 'success' | 'error';
|
|
||||||
progress: number;
|
|
||||||
error?: string;
|
|
||||||
}
|
|
||||||
export interface MaterialFile {
|
|
||||||
id: string;
|
|
||||||
file_name: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OutputVideoFile {
|
|
||||||
id: string;
|
|
||||||
file_name: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ManualTask {
|
|
||||||
task_id: string;
|
|
||||||
user_id: string;
|
|
||||||
status: 'Created' | 'Processing' | 'Completed' | 'Failed';
|
|
||||||
created_at: string;
|
|
||||||
started_at: string;
|
|
||||||
completed_at: string;
|
|
||||||
failure_reason: string | null;
|
|
||||||
template_id: number;
|
|
||||||
source_files: MaterialFile[];
|
|
||||||
output_video_file?: OutputVideoFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Size {
|
|
||||||
value: number;
|
|
||||||
unit: 'B' | 'KB' | 'MB' | 'GB' | 'TB';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ContentType {
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FilePath {
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Metadata {
|
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type UploadStatus = 'Pending' | 'Uploading' | 'Completed' | 'Failed';
|
|
||||||
export type DeletionStatus = 'Active' | 'PendingDeletion' | 'Deleted';
|
|
||||||
|
|
||||||
export interface ConfirmUpload {
|
|
||||||
file_id: string;
|
|
||||||
upload_url: string
|
|
||||||
name: string;
|
|
||||||
size: Size;
|
|
||||||
content_type: ContentType;
|
|
||||||
upload_time: string; // ISO date string
|
|
||||||
storage_medium: string;
|
|
||||||
file_path: FilePath;
|
|
||||||
uploader_id: number;
|
|
||||||
upload_status: UploadStatus;
|
|
||||||
deletion_status: DeletionStatus;
|
|
||||||
metadata: Metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义 EXIF 数据类型
|
|
||||||
export type ExifData = {
|
|
||||||
GPSLatitude?: number | undefined;
|
|
||||||
GPSLongitude?: number | undefined;
|
|
||||||
GPSAltitude?: number | undefined;
|
|
||||||
DateTimeOriginal?: string | undefined;
|
|
||||||
Make?: string | undefined;
|
|
||||||
Model?: string | undefined;
|
|
||||||
ExposureTime?: number | undefined;
|
|
||||||
FNumber?: number | undefined;
|
|
||||||
ISOSpeedRatings?: number | undefined;
|
|
||||||
FocalLength?: number | undefined;
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 默认的 EXIF 数据结构
|
|
||||||
export const defaultExifData: ExifData = {
|
|
||||||
GPSLatitude: undefined,
|
|
||||||
GPSLongitude: undefined,
|
|
||||||
GPSAltitude: undefined,
|
|
||||||
DateTimeOriginal: undefined,
|
|
||||||
Make: undefined,
|
|
||||||
Model: undefined,
|
|
||||||
ExposureTime: undefined,
|
|
||||||
FNumber: undefined,
|
|
||||||
ISOSpeedRatings: undefined,
|
|
||||||
FocalLength: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 压缩图片可配置参数
|
|
||||||
export interface ImagesuploaderProps {
|
|
||||||
children?: ReactNode;
|
|
||||||
style?: StyleProp<ViewStyle>;
|
|
||||||
onPickImage?: (file: File, exifData: ExifData) => void;
|
|
||||||
/** 压缩质量,0-1 之间的数字,默认为 0.8 */
|
|
||||||
compressQuality?: number;
|
|
||||||
/** 最大宽度,图片会被等比例缩放 */
|
|
||||||
maxWidth?: number;
|
|
||||||
/** 最大高度,图片会被等比例缩放 */
|
|
||||||
maxHeight?: number;
|
|
||||||
/** 是否保留 EXIF 数据,默认为 true */
|
|
||||||
preserveExif?: boolean;
|
|
||||||
/** 是否上传原图,默认为 false */
|
|
||||||
uploadOriginal?: boolean;
|
|
||||||
/** 上传完成回调 */
|
|
||||||
onUploadComplete?: UploadCompleteCallback;
|
|
||||||
/** 进度 */
|
|
||||||
onProgress?: (progress: FileStatus) => void;
|
|
||||||
/** 多选单选 默认单选*/
|
|
||||||
multipleChoice?: boolean;
|
|
||||||
/** 文件类型 默认图片*/
|
|
||||||
fileType?: MediaType[];
|
|
||||||
/** 是否展示预览 默认展示*/
|
|
||||||
showPreview?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义上传结果类型
|
|
||||||
export interface UploadResult {
|
|
||||||
originalUrl?: string;
|
|
||||||
compressedUrl: string;
|
|
||||||
file: File;
|
|
||||||
exifData: ExifData;
|
|
||||||
originalFile: ConfirmUpload;
|
|
||||||
compressedFile: ConfirmUpload;
|
|
||||||
thumbnail: string;
|
|
||||||
thumbnailFile: File;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义上传完成回调类型
|
|
||||||
export type UploadCompleteCallback = (result: FileUploadItem[]) => void;
|
|
||||||
|
|
||||||
// 单张图片上传完成回调类型
|
|
||||||
export type UploadSingleCompleteCallback = (result: FileUploadItem) => void;
|
|
||||||
|
|
||||||
// 定义上传 URL 响应类型
|
|
||||||
export interface UploadUrlResponse {
|
|
||||||
expires_in: number;
|
|
||||||
file_id: string;
|
|
||||||
file_path: string;
|
|
||||||
upload_url: string;
|
|
||||||
}
|
|
||||||
interface FileSize {
|
|
||||||
value: number;
|
|
||||||
unit: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FileMetadata {
|
|
||||||
originalName: string;
|
|
||||||
type: string;
|
|
||||||
isCompressed: string;
|
|
||||||
fileType: string;
|
|
||||||
}
|
|
||||||
interface FileInfo {
|
|
||||||
file_id: number;
|
|
||||||
name: string;
|
|
||||||
size: FileSize;
|
|
||||||
content_type: ContentType;
|
|
||||||
upload_time: string;
|
|
||||||
storage_medium: string;
|
|
||||||
file_path: FilePath;
|
|
||||||
uploader_id: number;
|
|
||||||
upload_status: string;
|
|
||||||
deletion_status: string;
|
|
||||||
metadata: FileMetadata;
|
|
||||||
}
|
|
||||||
export interface FileUploadItem {
|
|
||||||
id: string;
|
|
||||||
uri: string;
|
|
||||||
name: string;
|
|
||||||
progress: number;
|
|
||||||
status: 'pending' | 'uploading' | 'success' | 'error';
|
|
||||||
error?: string;
|
|
||||||
previewUrl: string;
|
|
||||||
file?: File;
|
|
||||||
type: 'image' | 'video';
|
|
||||||
thumbnail?: string; // 缩略图URL
|
|
||||||
thumbnailFile?: File; // 缩略图文件对象
|
|
||||||
originalFile?: FileInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
// 压缩图片可配置参数
|
|
||||||
export interface ImagesPickerProps {
|
|
||||||
children?: ReactNode;
|
|
||||||
style?: StyleProp<ViewStyle>;
|
|
||||||
onPickImage?: (file: File, exifData: ExifData) => void;
|
|
||||||
/** 压缩质量,0-1 之间的数字,默认为 0.8 */
|
|
||||||
compressQuality?: number;
|
|
||||||
/** 最大宽度,图片会被等比例缩放 */
|
|
||||||
maxWidth?: number;
|
|
||||||
/** 最大高度,图片会被等比例缩放 */
|
|
||||||
maxHeight?: number;
|
|
||||||
/** 是否保留 EXIF 数据,默认为 true */
|
|
||||||
preserveExif?: boolean;
|
|
||||||
/** 是否上传原图,默认为 false */
|
|
||||||
uploadOriginal?: boolean;
|
|
||||||
/** 上传完成回调 */
|
|
||||||
onUploadComplete?: UploadSingleCompleteCallback;
|
|
||||||
/** 进度 */
|
|
||||||
onProgress?: (progress: FileStatus) => void;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user