08.用户下载app

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: springboot vue 专栏: 【带小白做项目】springboot和vue前台开发 标签: 下载功能

2026-01-31 21:15:17 87浏览

开发下载功能

注意点

  1. 下载功能必须是登录状态下才允许下载。游客不允许下载
  2. 并且下载完后要更新 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展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695