- 将inspection/robot API导入路径更改为resource/robot - 更新getRobotDevicesByRobotId等函数的导入路径 - 修改流程序列组件中的API引用路径 - 更新设备注册页面的相关API调用 - 移除AppMain.vue中的过渡动画 - 添加新的resource/device API模块 - 更新语音合成组件的API导入路径 - 修改Node-RED转换工具的API引用 - 调整手动接管方向控制的API导入 - 更新流执行工具的API调用 - 优化流资源角色处理逻辑 - 移除已废弃的设备控制台和配置页面 - 更新相机和灵巧手组件的数据获取方式 - 调整麦克风组件的API引用路径 - 更新VueFlow组件的API导入 - 修改开发环境配置的URL地址和端口设置
76 lines
6.8 KiB
Vue
76 lines
6.8 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-form :inline="true" :model="query">
|
||
<el-form-item label="终端"><el-input v-model="query.terminalName" clearable @keyup.enter="search" /></el-form-item>
|
||
<el-form-item label="连接状态"><el-select v-model="query.connectStatus" clearable style="width: 120px"><el-option label="在线" value="1" /><el-option label="离线" value="0" /></el-select></el-form-item>
|
||
<el-form-item><el-button type="primary" icon="Search" @click="search">查询</el-button><el-button icon="Refresh" @click="reset">重置</el-button></el-form-item>
|
||
</el-form>
|
||
<el-row class="mb8"><el-button type="primary" icon="Plus" @click="openAdd">登记终端</el-button></el-row>
|
||
<el-table v-loading="loading" :data="rows" row-key="id">
|
||
<el-table-column label="终端" min-width="210"><template #default="{ row }"><strong>{{ row.terminalName || row.terminalCode }}</strong><div class="secondary">{{ row.terminalCode }}</div></template></el-table-column>
|
||
<el-table-column label="当前地址" min-width="180"><template #default="{ row }">{{ endpoint(row) }}</template></el-table-column>
|
||
<el-table-column label="连接" width="95"><template #default="{ row }"><el-tag :type="row.connectStatus === '1' ? 'success' : 'info'">{{ row.connectStatus === '1' ? '在线' : '离线' }}</el-tag></template></el-table-column>
|
||
<el-table-column label="软件版本" prop="softwareVersion" min-width="130" />
|
||
<el-table-column label="绑定机器人" min-width="220"><template #default="{ row }"><span v-if="row.robotCount">{{ row.robotIdsCsv }}</span><span v-else class="secondary">未绑定</span></template></el-table-column>
|
||
<el-table-column label="最后心跳" prop="lastHeartbeatTime" width="180" />
|
||
<el-table-column label="操作" width="190" fixed="right"><template #default="{ row }"><el-button link type="primary" icon="Link" @click="openBindings(row)">绑定</el-button><el-button link type="primary" icon="Edit" @click="openEdit(row)">编辑</el-button><el-button link type="danger" icon="Delete" :disabled="row.connectStatus === '1'" @click="remove(row)">删除</el-button></template></el-table-column>
|
||
</el-table>
|
||
<pagination v-show="total > 0" :total="total" v-model:page="query.pageNum" v-model:limit="query.pageSize" @pagination="load" />
|
||
|
||
<el-dialog v-model="formOpen" :title="form.id ? '编辑边缘终端' : '登记边缘终端'" width="540px">
|
||
<el-alert v-if="!form.id" title="终端编码应与QUIC节点ID一致;连接地址和在线状态由终端自动上报。" type="info" :closable="false" show-icon />
|
||
<el-form :model="form" label-width="95px" class="terminal-form">
|
||
<el-form-item label="终端编码" required><el-input v-model="form.terminalCode" :disabled="Boolean(form.id)" /></el-form-item>
|
||
<el-form-item label="终端名称" required><el-input v-model="form.terminalName" /></el-form-item>
|
||
<el-form-item label="启用状态"><el-switch v-model="form.status" active-value="0" inactive-value="1" /></el-form-item>
|
||
<el-form-item label="备注"><el-input v-model="form.remark" type="textarea" /></el-form-item>
|
||
</el-form>
|
||
<template #footer><el-button @click="formOpen = false">取消</el-button><el-button type="primary" :loading="saving" @click="save">保存</el-button></template>
|
||
</el-dialog>
|
||
|
||
<el-dialog v-model="bindingOpen" title="绑定机器人" width="620px">
|
||
<el-alert title="一台机器人同一时间只归属一个在线边缘终端;重新绑定会自动解除旧终端关系。" type="info" :closable="false" show-icon />
|
||
<el-select v-model="selectedRobotIds" multiple filterable collapse-tags collapse-tags-tooltip placeholder="选择机器人" class="binding-select">
|
||
<el-option v-for="robot in robots" :key="robot.robotId" :label="`${robot.robotName || robot.robotId} (${robot.robotId})`" :value="robot.robotId" />
|
||
</el-select>
|
||
<template #footer><el-button @click="bindingOpen = false">取消</el-button><el-button type="primary" :loading="saving" @click="saveBindings">保存绑定</el-button></template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup name="ResourceTerminal">
|
||
import { onActivated, onMounted, reactive, ref } from 'vue'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import { listResourceTerminals, addResourceTerminal, updateResourceTerminal, deleteResourceTerminals, listTerminalRobots, updateTerminalRobots } from '@/api/resource/terminal'
|
||
import { listResourceRobots } from '@/api/resource/robot'
|
||
|
||
const loading = ref(false), saving = ref(false), rows = ref([]), total = ref(0), formOpen = ref(false), bindingOpen = ref(false), robots = ref([]), selectedRobotIds = ref([]), activeTerminal = ref(null)
|
||
const query = reactive({ pageNum: 1, pageSize: 20, terminalName: '', connectStatus: '' })
|
||
const empty = () => ({ id: '', terminalCode: '', terminalName: '', status: '0', remark: '' })
|
||
const form = reactive(empty())
|
||
const endpoint = row => row.ipAddress ? `${row.ipAddress}${row.port ? `:${row.port}` : ''}` : '-'
|
||
async function load() { loading.value = true; try { const res = await listResourceTerminals(query); rows.value = res.rows || []; total.value = res.total || 0 } finally { loading.value = false } }
|
||
function search() { query.pageNum = 1; load() }
|
||
function reset() { Object.assign(query, { pageNum: 1, terminalName: '', connectStatus: '' }); load() }
|
||
function openAdd() { Object.assign(form, empty()); formOpen.value = true }
|
||
function openEdit(row) { Object.assign(form, empty(), row); formOpen.value = true }
|
||
async function save() { if (!form.terminalCode.trim() || !form.terminalName.trim()) return ElMessage.warning('请输入终端编码和名称'); saving.value = true; try { if (form.id) await updateResourceTerminal(form); else await addResourceTerminal(form); ElMessage.success('终端已保存'); formOpen.value = false; load() } finally { saving.value = false } }
|
||
async function remove(row) { await ElMessageBox.confirm(`确定删除终端“${row.terminalName || row.terminalCode}”吗?`, '提示', { type: 'warning' }); await deleteResourceTerminals(row.id); ElMessage.success('已删除'); load() }
|
||
async function openBindings(row) {
|
||
activeTerminal.value = row
|
||
const [robotRes, bindingRes] = await Promise.all([listResourceRobots({ pageNum: 1, pageSize: 10000 }), listTerminalRobots(row.id)])
|
||
robots.value = robotRes.rows || []
|
||
selectedRobotIds.value = bindingRes.data || []
|
||
bindingOpen.value = true
|
||
}
|
||
async function saveBindings() { saving.value = true; try { await updateTerminalRobots(activeTerminal.value.id, selectedRobotIds.value); ElMessage.success('机器人绑定已保存'); bindingOpen.value = false; load() } finally { saving.value = false } }
|
||
onMounted(load)
|
||
onActivated(load)
|
||
</script>
|
||
|
||
<style scoped>
|
||
.secondary { color: var(--el-text-color-secondary); font-size: 12px; margin-top: 3px; }
|
||
.terminal-form { margin-top: 20px; }
|
||
.binding-select { width: 100%; margin-top: 20px; }
|
||
</style>
|