commit
2ca7f48131
3
.env
3
.env
|
@ -8,6 +8,9 @@ SHOPRO_BASE_URL = http://api-dashboard.yudao.iocoder.cn
|
|||
SHOPRO_DEV_BASE_URL=http://127.0.0.1:48080
|
||||
### SHOPRO_DEV_BASE_URL = http://yunai.natapp1.cc
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||
SHOPRO_UPLOAD_TYPE=client
|
||||
|
||||
# 后端接口前缀(一般不建议调整)
|
||||
SHOPRO_API_PATH=/app-api
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { baseUrl, apiPath, tenantId } from '@/sheep/config';
|
||||
import request from '@/sheep/request';
|
||||
|
||||
const FileApi = {
|
||||
// 上传文件
|
||||
|
@ -40,6 +41,26 @@ const FileApi = {
|
|||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 获取文件预签名地址
|
||||
getFilePresignedUrl: (path) => {
|
||||
return request({
|
||||
url: '/infra/file/presigned-url',
|
||||
method: 'GET',
|
||||
params: {
|
||||
path,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 创建文件
|
||||
createFile: (data) => {
|
||||
return request({
|
||||
url: '/infra/file/create', // 请求的 URL
|
||||
method: 'POST', // 请求方法
|
||||
data: data, // 要发送的数据
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default FileApi;
|
||||
|
|
|
@ -116,6 +116,28 @@ function normalizeChooseAndUploadFileRes(res, fileType) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function convertToArrayBuffer(uniFile) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fs = uni.getFileSystemManager();
|
||||
|
||||
fs.readFile({
|
||||
filePath: uniFile.path, // 确保路径正确
|
||||
success: (fileRes) => {
|
||||
try {
|
||||
// 将读取的内容转换为 ArrayBuffer
|
||||
const arrayBuffer = new Uint8Array(fileRes.data).buffer;
|
||||
resolve(arrayBuffer);
|
||||
} catch (error) {
|
||||
reject(new Error(`转换为 ArrayBuffer 失败: ${error.message}`));
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
reject(new Error(`读取文件失败: ${error.errMsg}`));
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function uploadCloudFiles(files, max = 5, onUploadProgress) {
|
||||
files = JSON.parse(JSON.stringify(files));
|
||||
const len = files.length;
|
||||
|
@ -165,36 +187,58 @@ function uploadCloudFiles(files, max = 5, onUploadProgress) {
|
|||
});
|
||||
}
|
||||
|
||||
function uploadFiles(choosePromise, { onChooseFile, onUploadProgress }) {
|
||||
return choosePromise
|
||||
.then((res) => {
|
||||
async function uploadFiles(choosePromise, { onChooseFile, onUploadProgress }) {
|
||||
// 获取选择的文件
|
||||
const res = await choosePromise;
|
||||
// 处理文件选择回调
|
||||
let files = res.tempFiles || [];
|
||||
if (onChooseFile) {
|
||||
const customChooseRes = onChooseFile(res);
|
||||
if (typeof customChooseRes !== 'undefined') {
|
||||
return Promise.resolve(customChooseRes).then((chooseRes) =>
|
||||
typeof chooseRes === 'undefined' ? res : chooseRes,
|
||||
);
|
||||
files = await Promise.resolve(customChooseRes);
|
||||
if (typeof files === 'undefined') {
|
||||
files = res.tempFiles || []; // Fallback
|
||||
}
|
||||
}
|
||||
return res;
|
||||
})
|
||||
.then((res) => {
|
||||
if (res === false) {
|
||||
return {
|
||||
errMsg: ERR_MSG_OK,
|
||||
tempFilePaths: [],
|
||||
tempFiles: [],
|
||||
};
|
||||
}
|
||||
return res;
|
||||
})
|
||||
.then(async (files) => {
|
||||
for (let file of files.tempFiles) {
|
||||
|
||||
// 如果是前端直连上传
|
||||
if (UPLOAD_TYPE.CLIENT === import.meta.env.SHOPRO_UPLOAD_TYPE) {
|
||||
for (const file of files) {
|
||||
// 1.1 获取文件预签名地址
|
||||
const { data: presignedInfo } = await FileApi.getFilePresignedUrl(file.name);
|
||||
// 1.2 获取二进制文件对象
|
||||
const fileBuffer = await convertToArrayBuffer(file);
|
||||
// 1.3 上传文件
|
||||
await uni.request({
|
||||
url: presignedInfo.uploadUrl, // 预签名的上传 URL
|
||||
method: 'PUT', // 使用 PUT 方法
|
||||
header: {
|
||||
'Content-Type': file.fileType + '/' + file.name.substring(file.name.lastIndexOf('.') + 1), // 设置内容类型
|
||||
},
|
||||
data: fileBuffer, // 文件的路径,适用于小程序
|
||||
success: (res) => {
|
||||
// 1.4. 记录文件信息到后端(异步)
|
||||
createFile(presignedInfo, file);
|
||||
// 1.5. 重新赋值
|
||||
file.url = presignedInfo.url;
|
||||
console.log('上传成功:', res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('上传失败:', err);
|
||||
},
|
||||
});
|
||||
}
|
||||
return files;
|
||||
} else {
|
||||
// 后端上传
|
||||
for (let file of files) {
|
||||
const { data } = await FileApi.uploadFile(file.path);
|
||||
file.url = data;
|
||||
}
|
||||
|
||||
return files;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chooseAndUploadFile(
|
||||
|
@ -210,4 +254,32 @@ function chooseAndUploadFile(
|
|||
return uploadFiles(chooseAll(opts), opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件信息
|
||||
* @param vo 文件预签名信息
|
||||
* @param file 文件
|
||||
*/
|
||||
function createFile(vo, file) {
|
||||
const fileVo = {
|
||||
configId: vo.configId,
|
||||
url: vo.url,
|
||||
path: file.name,
|
||||
name: file.name,
|
||||
type: file.fileType,
|
||||
size: file.size,
|
||||
};
|
||||
FileApi.createFile(fileVo);
|
||||
return fileVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传类型
|
||||
*/
|
||||
const UPLOAD_TYPE = {
|
||||
// 客户端直接上传(只支持S3服务)
|
||||
CLIENT: 'client',
|
||||
// 客户端发送到后端上传
|
||||
SERVER: 'server',
|
||||
};
|
||||
|
||||
export { chooseAndUploadFile, uploadCloudFiles };
|
||||
|
|
|
@ -369,7 +369,7 @@
|
|||
},
|
||||
})
|
||||
.then((result) => {
|
||||
this.setSuccessAndError(result.tempFiles);
|
||||
this.setSuccessAndError(result);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('选择失败', err);
|
||||
|
@ -453,7 +453,7 @@
|
|||
|
||||
if (index === -1 || !this.files) break;
|
||||
if (item.errMsg === 'request:fail') {
|
||||
this.files[index].url = item.path;
|
||||
this.files[index].url = item.url;
|
||||
this.files[index].status = 'error';
|
||||
this.files[index].errMsg = item.errMsg;
|
||||
// this.files[index].progress = -1
|
||||
|
@ -587,7 +587,7 @@
|
|||
path: v.path,
|
||||
size: v.size,
|
||||
fileID: v.fileID,
|
||||
url: v.url,
|
||||
url: v.path,
|
||||
});
|
||||
});
|
||||
return newFilesData;
|
||||
|
|
Loading…
Reference in New Issue