#
Junjie
2026-01-19 ecf6d2ccc69c1e8bd2068c16f232b98bf4a8c234
#
4个文件已修改
212 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/TvDeviceController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/TvDeviceService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/TvDeviceServiceImpl.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/tvDevice/tvDevice.html 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/TvDeviceController.java
@@ -330,4 +330,43 @@
            return R.error("截图失败: " + e.getMessage());
        }
    }
    /**
     * 重启设备上的应用
     */
    @RequestMapping(value = "/tvDevice/restartApp/{id}/auth", method = RequestMethod.POST)
    @ManagerAuth
    public R restartApp(@PathVariable("id") Long id, @RequestBody(required = false) JSONObject param) {
        try {
            String packageName = param != null ? param.getString("packageName") : null;
            String result = tvDeviceService.restartApp(id, packageName);
            Map<String, Object> data = new HashMap<>();
            data.put("result", result);
            data.put("device", tvDeviceService.selectById(id));
            return R.ok(data);
        } catch (Exception e) {
            return R.error("重启失败: " + e.getMessage());
        }
    }
    /**
     * 批量重启设备上的应用
     */
    @RequestMapping(value = "/tvDevice/batchRestartApp/auth", method = RequestMethod.POST)
    @ManagerAuth
    public R batchRestartApp(@RequestBody JSONObject param) {
        try {
            List<Long> deviceIds = param.getJSONArray("deviceIds").toJavaList(Long.class);
            String packageName = param.getString("packageName");
            if (deviceIds == null || deviceIds.isEmpty()) {
                return R.error("请选择设备");
            }
            List<String> results = tvDeviceService.batchRestartApp(deviceIds, packageName);
            return R.ok(results);
        } catch (Exception e) {
            return R.error("重启失败: " + e.getMessage());
        }
    }
}
src/main/java/com/zy/asrs/service/TvDeviceService.java
@@ -75,4 +75,31 @@
     * @return Base64编码的PNG图片
     */
    String captureScreen(Long deviceId) throws Exception;
    /**
     * 关闭设备上的应用
     *
     * @param deviceId    设备ID
     * @param packageName 应用包名(可为null使用默认包名)
     * @return 关闭结果
     */
    String stopApp(Long deviceId, String packageName) throws Exception;
    /**
     * 重启设备上的应用(先关闭再启动)
     *
     * @param deviceId    设备ID
     * @param packageName 应用包名(可为null使用默认包名)
     * @return 重启结果
     */
    String restartApp(Long deviceId, String packageName) throws Exception;
    /**
     * 批量重启设备上的应用
     *
     * @param deviceIds   设备ID列表
     * @param packageName 应用包名(可为null使用默认包名)
     * @return 重启结果列表
     */
    List<String> batchRestartApp(List<Long> deviceIds, String packageName);
}
src/main/java/com/zy/asrs/service/impl/TvDeviceServiceImpl.java
@@ -334,6 +334,78 @@
        return base64Image;
    }
    @Override
    public String stopApp(Long deviceId, String packageName) throws Exception {
        TvDevice device = this.selectById(deviceId);
        if (device == null) {
            throw new RuntimeException("设备不存在");
        }
        String pkg = (packageName != null && !packageName.trim().isEmpty()) ? packageName.trim() : defaultPackage;
        StringBuilder result = new StringBuilder();
        String adbAddress = device.getAdbAddress();
        // 先连接设备
        String connectResult = executeAdbCommand("connect", adbAddress);
        result.append("连接: ").append(connectResult).append("\n");
        if (connectResult.contains("failed")) {
            device.setStatus((short) 0);
            device.setUpdateTime(new Date());
            this.updateById(device);
            throw new RuntimeException("连接设备失败: " + connectResult);
        }
        Thread.sleep(500);
        // 使用am force-stop关闭应用
        String stopResult = executeAdbCommand("-s", adbAddress, "shell", "am", "force-stop", pkg);
        result.append("关闭: ").append(stopResult.isEmpty() ? "成功" : stopResult);
        // 更新设备状态
        device.setStatus((short) 1);
        device.setLastConnectTime(new Date());
        device.setUpdateTime(new Date());
        this.updateById(device);
        log.info("设备 {} 关闭应用 {} 成功", device.getName(), pkg);
        return result.toString();
    }
    @Override
    public String restartApp(Long deviceId, String packageName) throws Exception {
        StringBuilder result = new StringBuilder();
        // 先关闭应用
        String stopResult = stopApp(deviceId, packageName);
        result.append("【关闭应用】\n").append(stopResult).append("\n\n");
        // 等待1秒确保应用完全关闭
        Thread.sleep(1000);
        // 再启动应用
        String launchResult = launchApp(deviceId, packageName);
        result.append("【启动应用】\n").append(launchResult);
        return result.toString();
    }
    @Override
    public List<String> batchRestartApp(List<Long> deviceIds, String packageName) {
        List<String> results = new ArrayList<>();
        for (Long deviceId : deviceIds) {
            TvDevice device = this.selectById(deviceId);
            String deviceName = device != null ? device.getName() : "ID:" + deviceId;
            try {
                String result = restartApp(deviceId, packageName);
                results.add(deviceName + ": 重启成功\n" + result);
            } catch (Exception e) {
                results.add(deviceName + ": 重启失败 - " + e.getMessage());
            }
        }
        return results;
    }
    /**
     * 执行ADB命令
     */
src/main/webapp/views/tvDevice/tvDevice.html
@@ -181,13 +181,15 @@
                        </template>
                    </el-table-column>
                    <el-table-column prop="remark" label="备注" min-width="100" show-overflow-tooltip></el-table-column>
                    <el-table-column label="操作" width="300" align="center" fixed="right">
                    <el-table-column label="操作" width="350" align="center" fixed="right">
                        <template slot-scope="scope">
                            <el-button type="text" size="small" @click="showEditDialog(scope.row)">编辑</el-button>
                            <el-button type="text" size="small" @click="testConnection(scope.row)"
                                :loading="scope.row.testing">测试连接</el-button>
                                :loading="scope.row.testing">测试</el-button>
                            <el-button type="text" size="small" style="color: #67c23a;" @click="launchApp(scope.row)"
                                :loading="scope.row.launching">启动</el-button>
                            <el-button type="text" size="small" style="color: #e6a23c;" @click="restartApp(scope.row)"
                                :loading="scope.row.restarting">重启</el-button>
                            <el-button type="text" size="small" style="color: #409eff;"
                                @click="captureScreen(scope.row)" :loading="scope.row.capturing">截图</el-button>
                            <el-button type="text" size="small" style="color: #f56c6c;"
@@ -302,7 +304,11 @@
                    <el-form-item>
                        <el-button type="success" @click="batchLaunchApp" :loading="launching"
                            :disabled="launchForm.deviceIds.length === 0">
                            <i class="el-icon-video-play"></i> 批量启动应用
                            <i class="el-icon-video-play"></i> 批量启动
                        </el-button>
                        <el-button type="warning" @click="batchRestartApp" :loading="launching"
                            :disabled="launchForm.deviceIds.length === 0">
                            <i class="el-icon-refresh"></i> 批量重启
                        </el-button>
                    </el-form-item>
                </el-form>
@@ -679,6 +685,68 @@
                    });
                },
                // 单个设备重启应用
                restartApp(row) {
                    this.$set(row, 'restarting', true);
                    $.ajax({
                        url: baseUrl + '/tvDevice/restartApp/' + row.id + '/auth',
                        headers: this.getHeaders(),
                        method: 'POST',
                        contentType: 'application/json;charset=UTF-8',
                        data: JSON.stringify({ packageName: this.launchForm.packageName }),
                        success: (res) => {
                            this.$set(row, 'restarting', false);
                            if (res.code === 200) {
                                Object.assign(row, res.data.device);
                                this.$message.success('重启成功');
                                this.installResult = res.data.result;
                            } else {
                                this.$message.error(res.msg || '重启失败');
                            }
                        },
                        error: () => {
                            this.$set(row, 'restarting', false);
                            this.$message.error('请求失败');
                        }
                    });
                },
                // 批量重启应用
                batchRestartApp() {
                    if (this.launchForm.deviceIds.length === 0) {
                        this.$message.warning('请选择设备');
                        return;
                    }
                    this.launching = true;
                    this.installResult = '';
                    $.ajax({
                        url: baseUrl + '/tvDevice/batchRestartApp/auth',
                        headers: this.getHeaders(),
                        method: 'POST',
                        contentType: 'application/json;charset=UTF-8',
                        data: JSON.stringify({
                            deviceIds: this.launchForm.deviceIds,
                            packageName: this.launchForm.packageName
                        }),
                        success: (res) => {
                            this.launching = false;
                            if (res.code === 200) {
                                this.installResult = res.data.join('\n');
                                this.$message.success('重启完成');
                                this.loadData();
                            } else {
                                this.$message.error(res.msg || '重启失败');
                            }
                        },
                        error: () => {
                            this.launching = false;
                            this.$message.error('请求失败');
                        }
                    });
                },
                // 搜索
                handleSearch() {
                    this.currentPage = 1;