版本发布
This commit is contained in:
248
cool/upload/index.ts
Normal file
248
cool/upload/index.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
import { config } from "../../config";
|
||||
import { service } from "../service";
|
||||
import { basename, extname, filename, parse, parseObject, pathJoin, uuid } from "../utils";
|
||||
import { useStore } from "../store";
|
||||
|
||||
// 上传进度回调结果类型
|
||||
export type OnProgressUpdateResult = {
|
||||
progress: number;
|
||||
totalBytesSent: number;
|
||||
totalBytesExpectedToSend: number;
|
||||
};
|
||||
|
||||
// 上传任务类型定义
|
||||
export type UploadTask = {
|
||||
abort(): void;
|
||||
};
|
||||
|
||||
// 上传选项类型定义
|
||||
export type UploadOptions = {
|
||||
onProgressUpdate?: (result: OnProgressUpdateResult) => void; // 上传进度回调
|
||||
onTask?: (task: UploadTask) => void; // 上传任务回调
|
||||
};
|
||||
|
||||
// 上传模式类型
|
||||
export type UploadMode = {
|
||||
mode: "local" | "cloud"; // 上传模式:本地或云端
|
||||
type: string; // 云服务类型
|
||||
};
|
||||
|
||||
// 上传请求的参数类型
|
||||
export type UploadRequestOptions = {
|
||||
url: string;
|
||||
preview?: string;
|
||||
data: any;
|
||||
};
|
||||
|
||||
// 云上传返回数据类型
|
||||
export type CloudUploadResponse = {
|
||||
uploadUrl?: string;
|
||||
url?: string;
|
||||
host?: string;
|
||||
credentials?: any;
|
||||
OSSAccessKeyId?: string;
|
||||
policy?: string;
|
||||
signature?: string;
|
||||
publicDomain?: string;
|
||||
token?: string;
|
||||
fields?: any;
|
||||
};
|
||||
|
||||
// 本地上传返回数据类型
|
||||
export type LocalUploadResponse = {
|
||||
code: number;
|
||||
message?: string;
|
||||
data: string;
|
||||
};
|
||||
|
||||
// 获取上传模式(本地/云端及云类型)
|
||||
async function getUploadMode(): Promise<UploadMode> {
|
||||
const res = await service.base.comm.uploadMode({});
|
||||
return parse<UploadMode>(res)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* 路径上传
|
||||
* @param path 文件路径
|
||||
*/
|
||||
export async function upload(path: string) {
|
||||
return uploadFile({
|
||||
path,
|
||||
size: 0,
|
||||
name: "",
|
||||
type: "image/png"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param file 文件信息 ChooseImageTempFile
|
||||
* @param options 上传选项
|
||||
*/
|
||||
export async function uploadFile(
|
||||
file: ChooseImageTempFile,
|
||||
options: UploadOptions | null = null
|
||||
): Promise<string> {
|
||||
const { user } = useStore();
|
||||
|
||||
// 获取上传模式和类型
|
||||
const { mode, type } = await getUploadMode();
|
||||
|
||||
// 判断是否本地上传
|
||||
const isLocal = mode == "local";
|
||||
|
||||
// 判断是否是云上传
|
||||
const isCloud = mode == "cloud";
|
||||
|
||||
// 获取文件路径
|
||||
const filePath = file.path;
|
||||
|
||||
// 获取文件名
|
||||
let fileName = file.name;
|
||||
|
||||
// 如果文件名不存在,则使用文件路径的文件名
|
||||
if (fileName == "" || fileName == null) {
|
||||
fileName = basename(filePath);
|
||||
}
|
||||
|
||||
// 获取文件扩展名
|
||||
let ext = extname(fileName);
|
||||
if (ext == "") {
|
||||
ext = "png";
|
||||
}
|
||||
|
||||
// 生成唯一key: 原文件名_uuid.扩展名
|
||||
let key = `${filename(fileName)}_${uuid()}.${ext}`;
|
||||
|
||||
// 云上传需要加上时间戳路径
|
||||
if (isCloud) {
|
||||
key = `app/${Date.now()}/${key}`;
|
||||
}
|
||||
|
||||
// 支持多种上传方式
|
||||
return new Promise((resolve, reject) => {
|
||||
/**
|
||||
* 实际上传文件的函数
|
||||
* @param param0 上传参数
|
||||
*/
|
||||
function next({ url, preview, data }: UploadRequestOptions) {
|
||||
// 发起上传请求
|
||||
const task = uni.uploadFile({
|
||||
url,
|
||||
filePath,
|
||||
name: "file",
|
||||
header: {
|
||||
// 本地上传带token
|
||||
Authorization: isLocal ? user.token : null
|
||||
},
|
||||
formData: {
|
||||
...(data as UTSJSONObject),
|
||||
key
|
||||
},
|
||||
success(res) {
|
||||
if (isLocal) {
|
||||
// 本地上传返回处理
|
||||
const { code, data, message } = parseObject<LocalUploadResponse>(res.data)!;
|
||||
|
||||
if (code == 1000) {
|
||||
resolve(data);
|
||||
} else {
|
||||
reject(message);
|
||||
}
|
||||
} else {
|
||||
// 云上传直接拼接url
|
||||
resolve(pathJoin(preview ?? url, key!));
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
console.error(err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
|
||||
// 上传任务回调
|
||||
if (options?.onTask != null) {
|
||||
options.onTask!({
|
||||
abort: () => {
|
||||
task.abort();
|
||||
}
|
||||
} as UploadTask);
|
||||
}
|
||||
|
||||
// 上传进度回调
|
||||
if (options?.onProgressUpdate != null) {
|
||||
task.onProgressUpdate((result) => {
|
||||
const { progress, totalBytesSent, totalBytesExpectedToSend } = result;
|
||||
|
||||
options.onProgressUpdate!({
|
||||
progress,
|
||||
totalBytesSent,
|
||||
totalBytesExpectedToSend
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 本地上传
|
||||
if (isLocal) {
|
||||
next({
|
||||
url: config.baseUrl + "/app/base/comm/upload",
|
||||
data: {}
|
||||
});
|
||||
} else {
|
||||
// 云上传
|
||||
const data = {} as UTSJSONObject;
|
||||
|
||||
// AWS需要提前传key
|
||||
if (type == "aws") {
|
||||
data.key = key;
|
||||
}
|
||||
|
||||
// 获取云上传参数
|
||||
service.base.comm
|
||||
.upload(data)
|
||||
.then((res) => {
|
||||
const d = parse<CloudUploadResponse>(res)!;
|
||||
|
||||
switch (type) {
|
||||
// 腾讯云COS
|
||||
case "cos":
|
||||
next({
|
||||
url: d.url!,
|
||||
data: d.credentials!
|
||||
});
|
||||
break;
|
||||
// 阿里云OSS
|
||||
case "oss":
|
||||
next({
|
||||
url: d.host!,
|
||||
data: {
|
||||
OSSAccessKeyId: d.OSSAccessKeyId,
|
||||
policy: d.policy,
|
||||
signature: d.signature
|
||||
}
|
||||
});
|
||||
break;
|
||||
// 七牛云
|
||||
case "qiniu":
|
||||
next({
|
||||
url: d.uploadUrl!,
|
||||
preview: d.publicDomain,
|
||||
data: {
|
||||
token: d.token
|
||||
}
|
||||
});
|
||||
break;
|
||||
// 亚马逊AWS
|
||||
case "aws":
|
||||
next({
|
||||
url: d.url!,
|
||||
data: d.fields!
|
||||
});
|
||||
break;
|
||||
}
|
||||
})
|
||||
.catch(reject);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user