tiefen_space_app/utils/upload.js

292 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import mime from "mime";
import baseRequest from "./baseRequest";
import Toast from "react-native-toast-message";
import * as VideoThumbnails from "expo-video-thumbnails";
import { generateSignature } from "./crypto";
//获取环境变量
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
//获取上传失败时返回的id
async function getFailId() {
const base = await baseRequest();
const signature = await generateSignature({
...base,
});
try {
const response = await fetch(
`${apiUrl}/api/upload_media_fail_config/list?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...base,
}),
}
);
const data = await response.json();
if (data.ret === -1) {
Toast.show({
type: "error",
text1: data.msg,
topOffset: 60,
});
return;
}
return data.data;
} catch (e) {
console.warn(e);
}
}
//获取auth
async function getAuth(mtype) {
const base = await baseRequest();
const signature = await generateSignature({
mtype: mtype,
...base,
});
try {
const response = await fetch(
`${apiUrl}/api/media/auth?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mtype: mtype,
...base,
}),
}
);
const data = await response.json();
if (data.ret === -1) {
Toast.show({
type: "error",
text1: data.msg,
topOffset: 60,
});
return;
}
return data.data.policy_token;
} catch (error) {
console.error(error);
}
}
//上传单张图片
export async function uploadImage(asset) {
const auth = await getAuth(1);
const fileType = mime.getType(asset?.uri);
//禁止上传gif安卓展示gif时会闪退
if (fileType === "image/gif") {
Toast.show({
type: "error",
text1: "无法上传gif图片",
topOffset: 60,
});
const failId = await getFailId();
return failId?.image_id_for_upload_fail;
}
try {
const formData = new FormData();
formData.append("name", auth.filename);
formData.append("policy", auth.policy);
formData.append("OSSAccessKeyId", auth.access_key_id);
formData.append("success_action_status", "200");
formData.append("signature", auth.signature);
formData.append("key", auth.directory + "/" + auth.filename);
formData.append("file", {
uri: asset?.uri,
name: asset?.filename,
type: fileType,
});
const uploadResponse = await fetch(auth.host, {
method: "POST",
body: formData,
});
if (uploadResponse.status === 200) {
const md5 = uploadResponse.headers.map.etag.substring(
1,
uploadResponse.headers.map.etag.length - 1
);
const item = {
src_id: auth.directory + "/" + auth.filename,
md5: md5,
h: asset.height,
w: asset.width,
fmt: fileType,
};
const base = await baseRequest();
const signature = await generateSignature({
mtype: 1,
item: item,
...base,
});
const response = await fetch(
`${apiUrl}/api/media/c_upload?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mtype: 1,
item: item,
...base,
}),
}
);
const data = await response.json();
if (data.ret === -1) {
Toast.show({
type: "error",
text1: data.msg,
topOffset: 60,
});
return;
}
return data.data.ret_item.id;
} else {
Toast.show({
type: "error",
text1: "上传图片失败",
topOffset: 60,
});
const failId = await getFailId();
return failId?.image_id_for_upload_fail;
}
} catch (error) {
console.log("Error occurred while getting or uploading data:", error);
Toast.show({
type: "error",
text1: "上传图片失败",
topOffset: 60,
});
const failId = await getFailId();
return failId?.image_id_for_upload_fail;
}
}
//上传单个视频
export async function uploadVideo(asset) {
const auth = await getAuth(2);
const fileType = mime.getType(asset?.uri);
const generateThumbnail = async () => {
try {
const videoCover = await VideoThumbnails.getThumbnailAsync(asset?.uri);
return videoCover;
} catch (e) {
console.warn(e);
}
};
try {
const formData = new FormData();
formData.append("name", auth.filename);
formData.append("policy", auth.policy);
formData.append("OSSAccessKeyId", auth.access_key_id);
formData.append("success_action_status", "200");
formData.append("signature", auth.signature);
formData.append("key", auth.directory + "/" + auth.filename);
formData.append("file", {
uri: asset?.uri,
name: asset?.filename,
type: fileType,
});
const uploadResponse = await fetch(auth.host, {
method: "POST",
body: formData,
});
if (uploadResponse.status === 200) {
const md5 = uploadResponse.headers.map.etag.substring(
1,
uploadResponse.headers.map.etag.length - 1
);
const videoCover = await generateThumbnail();
const videoCoverId = await uploadImage(videoCover);
const item = {
src_id: auth.directory + "/" + auth.filename,
cover_id: videoCoverId,
md5: md5,
dur: asset?.duration,
fmt: fileType,
};
const base = await baseRequest();
const signature = await generateSignature({
mtype: 2,
item: item,
...base,
});
const response = await fetch(
`${apiUrl}/api/media/c_upload?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
mtype: 2,
item: item,
...base,
}),
}
);
const data = await response.json();
if (data.ret === -1) {
Toast.show({
type: "error",
text1: data.msg,
topOffset: 60,
});
return;
}
return data.data.ret_item.id;
} else {
Toast.show({
type: "error",
text1: "上传视频失败",
topOffset: 60,
});
const failId = await getFailId();
return failId?.video_id_for_upload_fail;
}
} catch (error) {
console.log("Error occurred while getting or uploading data:", error);
Toast.show({
type: "error",
text1: "上传视频失败",
topOffset: 60,
});
const failId = await getFailId();
return failId?.video_id_for_upload_fail;
}
}
//上传多个图片或者视频
export async function multiUpload(assets) {
let ids = { image_ids: [], video_ids: [] };
const tasks = assets.map(async (asset, index) => {
if (asset.duration === 0) {
const id = await uploadImage(asset);
ids.image_ids[index] = id;
} else {
const id = await uploadVideo(asset);
ids.video_ids[index] = id;
}
});
await Promise.all(tasks);
return {
image_ids: ids.image_ids.filter(Boolean),
video_ids: ids.video_ids.filter(Boolean),
};
}