环境
vue3+typescript+arcodesign vue+openapi生成接口
需求
前端使用arco design 的文件上传组件a-upload上传到七牛云进行对象存储,前端api由openapi生成
template
<a-upload
action="/"
name="file"
:fileList="file ? [file] : []"
:show-file-list="false"
@change="onChange"
@progress="onProgress"
>
<template #upload-button>
<div
:class="`arco-upload-list-item${
file && file.status === 'error'
? ' arco-upload-list-item-error'
: ''
}`"
>
<div
class="arco-upload-list-picture custom-upload-avatar"
v-if="file && file.url"
>
<img :src="file.url" />
<div class="arco-upload-list-picture-mask">
<IconEdit />
</div>
<a-progress
v-if="
file.status === 'uploading' && file.percent < 100
"
:percent="file.percent"
type="circle"
size="mini"
:style="{
position: 'absolute',
left: '50%',
top: '50%',
transform: 'translateX(-50%) translateY(-50%)',
}"
/>
</div>
<div class="arco-upload-picture-card" v-else>
<div class="arco-upload-picture-card-text">
<IconPlus />
<div style="margin-top: 10px; font-weight: 600">
Upload
</div>
</div>
</div>
</div>
</template>
</a-upload>
script
const file = ref();
const onChange = (_: any, currentFile: FileItem) => {
file.value = currentFile;
// file.value = new File([currentFile], "pic.jpg");
// console.log(file);
var response = FileControllerService.uploadPicUsingPost(currentFile.file);
if (response.code === 0) {
message.success("上传成功" + response.data);
} else {
message.error("上传失败:" + response.data);
}
};
const onProgress = (currentFile: Blob) => {
file.value = currentFile;
message.info("上传中");
};
主要是currentFile的类型要写对,我前端学的少真的废了很多时间
api
/**
* uploadPic
* @param file file
* @returns BaseResponse_string_ OK
* @returns any Created
* @throws ApiError
*/
public static uploadPicUsingPost(
file: Blob
): CancelablePromise<BaseResponse_string_ | any> {
return __request(OpenAPI, {
method: "POST",
url: "/api/file/uploadPic",
formData: {
file: file,
},
errors: {
401: `Unauthorized`,
403: `Forbidden`,
404: `Not Found`,
},
});
}
java controller
@PostMapping("/uploadPic")
public BaseResponse<String> uploadPic(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {
if (multipartFile == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传文件为空" + multipartFile.toString());
}
String filename = multipartFile.getOriginalFilename();
String contentType = multipartFile.getContentType();
long size = multipartFile.getSize();
log.info("文件:" + filename + " 上传");
if (!contentType.equals("image/jpeg") && !contentType.equals("image/png") && !contentType.equals("image/jpg")) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "不支持的文件类型:" + contentType.toString());
}
log.info("文件格式:" + contentType);
if (size > 5 * 1024 * 1024) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小应不超过5MB");
}
log.info("文件大小:" + size);
//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
// 指定分片上传版本
cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
//
String imgURL = "";
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
InputStream inputStream = null;
try {
inputStream = multipartFile.getInputStream();
Auth auth = Auth.create(accessKey, secretKey);//创建凭证
String upToken = auth.uploadToken(bucket); //上传凭证
//修改6 put方法 第一个参数 要放上面 自己定义的 inputStream对象
Response response = uploadManager.put(inputStream, key, upToken, null, null);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
// System.out.println(putRet.key);
// System.out.println(putRet.hash); // hash值就是上传后的图片名字
//todo 把图片URL写入数据库
imgURL = baseURL + putRet.hash;
log.info("上传成功,图片地址" + imgURL);
} catch (IOException e) {
e.printStackTrace();
throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件读取失败");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 对上传的图片进行处理,例如保存到数据库等操作
return ResultUtils.success(imgURL);
}
参考🔗
https://blog.csdn.net/m0_54409739/article/details/134889798