template_0205
This commit is contained in:
150
RN_TEMPLATE/app/services/api/uploadApi.ts
Normal file
150
RN_TEMPLATE/app/services/api/uploadApi.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Upload API for file uploads via proxy to MinIO
|
||||
* Supports both Web and Native platforms
|
||||
*/
|
||||
import { Platform } from "react-native"
|
||||
|
||||
const OSS_BASE_URL = "https://oss.upay01.com"
|
||||
|
||||
// Upload response type
|
||||
export interface UploadResponse {
|
||||
code: number
|
||||
message: string
|
||||
data?: {
|
||||
filename: string
|
||||
originalName: string
|
||||
size: number
|
||||
mimetype: string
|
||||
url: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a URI to Blob (for Web platform)
|
||||
*/
|
||||
async function uriToBlob(uri: string): Promise<Blob> {
|
||||
const response = await fetch(uri)
|
||||
const blob = await response.blob()
|
||||
return blob
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file on Web platform
|
||||
*/
|
||||
async function uploadFileWeb(
|
||||
uri: string,
|
||||
fileName: string,
|
||||
mimeType: string,
|
||||
): Promise<{ kind: "ok"; url: string } | { kind: "error"; message: string }> {
|
||||
try {
|
||||
// Convert URI to Blob for Web
|
||||
const blob = await uriToBlob(uri)
|
||||
const file = new File([blob], fileName, { type: mimeType })
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append("file", file)
|
||||
|
||||
const response = await fetch(`${OSS_BASE_URL}/api/proxy/upload`, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
})
|
||||
|
||||
const data: UploadResponse = await response.json()
|
||||
|
||||
if (response.ok && data.code === 200 && data.data?.url) {
|
||||
return { kind: "ok", url: data.data.url }
|
||||
} else {
|
||||
return { kind: "error", message: data.message || "Upload failed" }
|
||||
}
|
||||
} catch (e) {
|
||||
if (__DEV__ && e instanceof Error) {
|
||||
console.error(`Upload error: ${e.message}`)
|
||||
}
|
||||
return { kind: "error", message: "Upload failed" }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file on Native platform (iOS/Android)
|
||||
*/
|
||||
function uploadFileNative(
|
||||
uri: string,
|
||||
fileName: string,
|
||||
mimeType: string,
|
||||
): Promise<{ kind: "ok"; url: string } | { kind: "error"; message: string }> {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
const xhr = new XMLHttpRequest()
|
||||
|
||||
xhr.onload = () => {
|
||||
if (__DEV__) {
|
||||
console.log("Upload response status:", xhr.status)
|
||||
console.log("Upload response body:", xhr.responseText)
|
||||
}
|
||||
if (xhr.status === 200) {
|
||||
try {
|
||||
const response: UploadResponse = JSON.parse(xhr.responseText)
|
||||
if (response.code === 200 && response.data?.url) {
|
||||
resolve({ kind: "ok", url: response.data.url })
|
||||
} else {
|
||||
resolve({ kind: "error", message: response.message || "Upload failed" })
|
||||
}
|
||||
} catch {
|
||||
resolve({ kind: "error", message: "Invalid response" })
|
||||
}
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
console.log("Upload failed - Status:", xhr.status, "Response:", xhr.responseText)
|
||||
}
|
||||
resolve({ kind: "error", message: `Upload failed with status ${xhr.status}` })
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onerror = () => {
|
||||
resolve({ kind: "error", message: "Network error" })
|
||||
}
|
||||
|
||||
xhr.ontimeout = () => {
|
||||
resolve({ kind: "error", message: "Upload timeout" })
|
||||
}
|
||||
|
||||
xhr.open("POST", `${OSS_BASE_URL}/api/proxy/upload`)
|
||||
xhr.timeout = 60000
|
||||
|
||||
// React Native specific FormData format
|
||||
const formData = new FormData()
|
||||
formData.append("file", {
|
||||
uri: uri,
|
||||
type: mimeType,
|
||||
name: fileName,
|
||||
} as any)
|
||||
|
||||
xhr.send(formData)
|
||||
} catch (e) {
|
||||
if (__DEV__ && e instanceof Error) {
|
||||
console.error(`Upload error: ${e.message}`)
|
||||
}
|
||||
resolve({ kind: "error", message: "Upload failed" })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a file to OSS storage
|
||||
* Automatically handles Web vs Native platform differences
|
||||
* @param uri - Local file URI
|
||||
* @param fileName - File name
|
||||
* @param mimeType - MIME type of the file
|
||||
* @returns Upload result with URL or error
|
||||
*/
|
||||
export async function uploadFile(
|
||||
uri: string,
|
||||
fileName: string,
|
||||
mimeType: string,
|
||||
): Promise<{ kind: "ok"; url: string } | { kind: "error"; message: string }> {
|
||||
if (Platform.OS === "web") {
|
||||
return uploadFileWeb(uri, fileName, mimeType)
|
||||
} else {
|
||||
return uploadFileNative(uri, fileName, mimeType)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user