#
Junjie
2026-01-29 62a399b547c3bd8c7081f7470ce66a6e17cf6d6f
#
3个文件已修改
106 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ApkBuildTaskController.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/OpenController.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/apkBuild/apkBuild.html 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ApkBuildTaskController.java
@@ -1,5 +1,6 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
@@ -13,6 +14,13 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -162,6 +170,40 @@
        }
    }
    @RequestMapping(value = "/apkBuildTask/downloadFile/{id}/auth", method = RequestMethod.GET)
    @ManagerAuth
    public void downloadApkFile(@PathVariable("id") Long id, HttpServletResponse response) {
        try {
            String localPath = apkBuildTaskService.downloadApk(id);
            File file = new File(localPath);
            if (!file.exists()) {
                throw new RuntimeException("APK文件不存在");
            }
            String fileName = URLEncoder.encode(file.getName(), "UTF-8");
            response.setContentType("application/vnd.android.package-archive");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setHeader("Content-Length", String.valueOf(file.length()));
            try (InputStream inputStream = new FileInputStream(file);
                 OutputStream outputStream = response.getOutputStream()) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, len);
                }
                outputStream.flush();
            }
        } catch (Exception e) {
            try {
                response.reset();
                response.setCharacterEncoding("utf-8");
                response.setContentType("application/json; charset=utf-8");
                response.getWriter().print(JSON.toJSONString(R.error("下载APK失败: " + e.getMessage())));
            } catch (IOException ignore) {
            }
        }
    }
    /**
     * 通过ADB安装APK到指定设备
     */
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -133,7 +133,10 @@
            list.add(tvDataDto);
        }
        return R.ok().add(list);
        HashMap<String, Object> map = new HashMap<>();
        map.put("data", list);
        map.put("deviceName", tvDevice.getName());
        return R.ok().add(map);
    }
    @GetMapping("/getError")
src/main/webapp/views/apkBuild/apkBuild.html
@@ -224,7 +224,7 @@
                    <el-table-column label="操作" width="180" align="center" fixed="right">
                        <template slot-scope="scope">
                            <el-button type="text" size="small" @click="showDetail(scope.row)">详情</el-button>
                            <el-button type="text" size="small" v-if="scope.row.status === 2 && !scope.row.apkPath"
                            <el-button type="text" size="small" v-if="scope.row.status === 2 && scope.row.apkPath"
                                @click="downloadApk(scope.row)" :loading="scope.row.downloading">下载</el-button>
                            <el-button type="text" size="small" style="color: #67c23a;"
                                v-if="scope.row.status === 2 && scope.row.apkPath"
@@ -658,21 +658,58 @@
                downloadApk(row) {
                    this.$set(row, 'downloading', true);
                    $.ajax({
                        url: baseUrl + '/apkBuildTask/download/' + row.id + '/auth',
                        url: baseUrl + '/apkBuildTask/downloadFile/' + row.id + '/auth',
                        headers: this.getHeaders(),
                        method: 'POST',
                        success: (res) => {
                        method: 'GET',
                        xhrFields: { responseType: 'blob' },
                        success: (data, status, xhr) => {
                            this.$set(row, 'downloading', false);
                            if (res.code === 200) {
                                this.$message.success('APK下载完成: ' + res.data.apkPath);
                                this.loadData();
                            } else {
                                this.$message.error(res.msg || '下载失败');
                            const contentType = xhr.getResponseHeader('Content-Type') || '';
                            if (contentType.indexOf('application/json') !== -1) {
                                const reader = new FileReader();
                                reader.onload = () => {
                                    try {
                                        const res = JSON.parse(reader.result);
                                        this.$message.error(res.msg || '下载失败');
                                    } catch (e) {
                                        this.$message.error('下载失败');
                                    }
                                };
                                reader.readAsText(data);
                                return;
                            }
                            const disposition = xhr.getResponseHeader('Content-Disposition') || '';
                            const fileNameMatch = disposition.match(/filename="?([^"]+)"?/);
                            let fileName = fileNameMatch ? decodeURIComponent(fileNameMatch[1]) : '';
                            if (!fileName) {
                                fileName = (row.projectName ? row.projectName : row.id) + '.apk';
                            }
                            const blob = new Blob([data], { type: contentType || 'application/octet-stream' });
                            const link = document.createElement('a');
                            link.href = URL.createObjectURL(blob);
                            link.download = fileName;
                            document.body.appendChild(link);
                            link.click();
                            document.body.removeChild(link);
                            URL.revokeObjectURL(link.href);
                            this.$message.success('APK已开始下载');
                        },
                        error: () => {
                        error: (xhr) => {
                            this.$set(row, 'downloading', false);
                            this.$message.error('请求失败');
                            if (xhr && xhr.response) {
                                const reader = new FileReader();
                                reader.onload = () => {
                                    try {
                                        const res = JSON.parse(reader.result);
                                        this.$message.error(res.msg || '下载失败');
                                    } catch (e) {
                                        this.$message.error('请求失败');
                                    }
                                };
                                reader.readAsText(xhr.response);
                            } else {
                                this.$message.error('请求失败');
                            }
                        }
                    });
                },