Junjie
2026-04-07 cd448f774cfd4837a969d01ebea03530608c6839
src/main/webapp/views/tvDevice/tvDevice.html
@@ -157,6 +157,24 @@
                </div>
            </div>
            <div style="margin-bottom: 15px;">
                <el-card shadow="hover">
                    <div slot="header">
                        <span>手动异常信息</span>
                    </div>
                    <el-form label-position="top" size="small">
                        <el-form-item label="异常信息">
                            <el-input type="textarea" v-model="manualError" :rows="3"
                                placeholder="输入需要下发到设备的异常信息"></el-input>
                        </el-form-item>
                        <el-button type="primary" size="small" @click="saveManualError"
                            :loading="manualErrorSaving">保存</el-button>
                        <el-button size="small" @click="clearManualError"
                            :disabled="manualErrorSaving">清空</el-button>
                    </el-form>
                </el-card>
            </div>
            <!-- 表格区域 -->
            <div class="table-section">
                <el-table :data="tableData" border stripe @selection-change="handleSelectionChange" style="width: 100%;"
@@ -181,13 +199,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;"
@@ -220,12 +240,9 @@
                                    <el-select v-model="installForm.taskId" placeholder="请选择已完成的打包任务"
                                        style="width: 100%;" filterable>
                                        <el-option v-for="task in completedTasks" :key="task.id"
                                            :label="task.projectName || task.taskId" :value="task.id"
                                            :label="buildTaskLabel(task)" :value="task.id"
                                            :disabled="!task.apkPath">
                                            <span>{{ task.projectName || task.repoAlias }}</span>
                                            <span style="float: right; color: #909399; font-size: 12px;">
                                                {{ task.apkPath ? '已下载' : '未下载' }}
                                            </span>
                                            <span>{{ buildTaskLabel(task) }}</span>
                                        </el-option>
                                    </el-select>
                                </el-form-item>
@@ -302,7 +319,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>
@@ -424,7 +445,10 @@
                screenshotImage: '',
                screenshotLoading: false,
                autoRefreshScreenshot: false,
                screenshotTimer: null
                screenshotTimer: null,
                manualError: '',
                manualErrorSaving: false
            },
            computed: {
@@ -443,12 +467,60 @@
                this.loadData();
                this.loadAllDevices();
                this.loadCompletedTasks();
                this.loadManualError();
            },
            methods: {
                // 获取请求头
                getHeaders() {
                    return { 'token': localStorage.getItem('token') };
                },
                loadManualError() {
                    $.ajax({
                        url: baseUrl + '/openapi/manualError/auth',
                        headers: this.getHeaders(),
                        method: 'GET',
                        success: (res) => {
                            if (res.code === 200) {
                                this.manualError = (res.data && res.data.manualError) ? res.data.manualError : '';
                            } else if (res.code === 403) {
                                top.location.href = baseUrl + '/';
                            } else {
                                this.$message.error(res.msg || '加载失败');
                            }
                        },
                        error: () => {
                            this.$message.error('请求失败');
                        }
                    });
                },
                saveManualError() {
                    this.manualErrorSaving = true;
                    $.ajax({
                        url: baseUrl + '/openapi/manualError/auth',
                        headers: this.getHeaders(),
                        method: 'POST',
                        contentType: 'application/json;charset=UTF-8',
                        data: JSON.stringify({ manualError: this.manualError }),
                        success: (res) => {
                            this.manualErrorSaving = false;
                            if (res.code === 200) {
                                this.$message.success('保存成功');
                            } else if (res.code === 403) {
                                top.location.href = baseUrl + '/';
                            } else {
                                this.$message.error(res.msg || '保存失败');
                            }
                        },
                        error: () => {
                            this.manualErrorSaving = false;
                            this.$message.error('请求失败');
                        }
                    });
                },
                clearManualError() {
                    this.manualError = '';
                    this.saveManualError();
                },
                // 加载数据
@@ -679,6 +751,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;
@@ -883,6 +1017,14 @@
                    this.$message.error('上传失败');
                },
                buildTaskLabel(task) {
                    const name = task.projectName || task.repoAlias || task.taskId || '';
                    const time = this.formatDate(task.createdAt) || '-';
                    const id = task.id != null ? task.id : '';
                    const status = task.apkPath ? '已下载' : '未下载';
                    return `${name} | ID: ${id} | ${time} | ${status}`;
                },
                // 格式化日期
                formatDate(timestamp) {
                    if (!timestamp) return '';
@@ -900,4 +1042,4 @@
    </script>
</body>
</html>
</html>