08.用户下载app
分类: springboot vue 专栏: 【带小白做项目】springboot和vue前台开发 标签: 下载功能
2026-01-31 21:15:17 87浏览
开发下载功能
注意点
- 下载功能必须是登录状态下才允许下载。游客不允许下载
- 并且下载完后要更新 appinfo 的下载量的数据
服务端
@GetMapping("/{versionId}")
@ApiOperation(value = "app下载")
public ResponseEntity<Resource> download(@PathVariable Long versionId){
/*1. 下载功能必须是登录状态下才允许下载。游客不允许下载
2. 并且下载完后要更新 appinfo 的下载量的数据*/
AppVersion appVersion = versionMapper.selectByPrimaryKey(versionId);
if (appVersion == null) {
// return ResponseEntity.notFound().build();
throw new RuntimeException("版本信息不存在");
}
AppInfo appInfo = appInfoService.getById(appVersion.getAppid());
if (appInfo == null) {
// return ResponseEntity.notFound().build();
throw new RuntimeException("app应用信息不存在");
}
// 更新下载量
if (appInfo.getDownloads() == null) {
appInfo.setDownloads(0L);
} else {
appInfo.setDownloads(appInfo.getDownloads() + 1);
}
appInfoService.saveOrUpdate2(appInfo);
try {
// 获取文件路径
String filePath = appVersion.getDownloadlink();
// 如果是相对路径,需要拼接上基础路径
if (!filePath.startsWith("/") && !filePath.contains(":")) {
filePath = uploadPath + "/" + filePath;
}
Path path = Paths.get(filePath);
Resource resource = new UrlResource(path.toUri());
if (resource.exists() || resource.isReadable()) {
// 获取文件名
String fileName = path.getFileName().toString();
// 设置响应头
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+ fileName )
.body(resource);
} else {
// return ResponseEntity.notFound().build();
throw new RuntimeException("apk文件不存在或不可读");
}
} catch (IOException e) {
e.printStackTrace();
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
throw new RuntimeException("下载失败");
}
}前端页面
// 下载指定版本
downloadVersion(versionId) {
downloadApp(versionId).then(res => {
console.log(res)
// 检查响应是否是文件流还是JSON数据
try {
// 尝试将响应转换为JSON,如果成功说明是错误消息
const jsonData = JSON.parse(new TextDecoder().decode(res));
console.log(jsonData)
if (jsonData.code && jsonData.code == 3001) {
// this.$message.error(jsonData.mess || jsonData.message || '下载失败');
MessageBox.confirm(jsonData.mess ,"系统提示",{
confirmButtonText:'重新登录',
type:'warning',
showCancelButton: false
}
).then(()=>{
router.push("/front/loginOrReg");
}).catch(() => {
// 用户点击关闭按钮或取消操作时的处理
console.log("用户关闭了登录提示框");
})
return;
}
} catch (e) {
// 转换失败说明是文件流,继续处理下载
}
// 处理文件下载
const blob = new Blob([res], { type: 'application/vnd.android.package-archive' });
const downloadElement = document.createElement('a');
const href = window.URL.createObjectURL(blob); // 创建下载的链接
downloadElement.href = href;
downloadElement.download = this.appDetail.softwarename+ '.apk'; // 下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); // 点击下载
document.body.removeChild(downloadElement); // 下载完成移除元素
window.URL.revokeObjectURL(href); // 释放掉blob对象
}).catch(error => {
console.error('下载错误:', error);
this.$message.error('下载失败,请稍后重试');
})
},export function downloadApp(versonid) {
return request({
url: '/front/download/'+versonid,
method: 'get',
responseType: 'arraybuffer' // 使用 arraybuffer 可以同时处理文件和JSON数据
})
}
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
暂无评论,快来写一下吧
展开评论
他的专栏
他感兴趣的技术


新业务
springboot学习
ssm框架课
vue学习
【带小白】java基础速成