feat(flow): 添加AGV站点列表功能支持

- 在基本节点参数组件中增加对AGV_MOVE_TO_STATION操作的支持
- 添加加载AGV站点列表的按钮和对话框功能
- 实现站点列表的异步加载和选项填充逻辑
- 为站点ID参数添加特殊验证规则确保设备匹配
- 在选择站点时添加设备ID验证防止数据错配
- 添加加载状态指示器和错误处理机制
- 实现站点选项的数据转换和显示格式化功能
This commit is contained in:
lixiaolong 2026-08-04 15:35:32 +08:00
parent 95ea34bbb8
commit bac6e1aa52

View File

@ -11,7 +11,7 @@
</el-button>
</template>
<div class="form__container">
<el-button type="primary" v-if="['AGV_MOVE_TO_POINT', 'ARM_MOVE_TO_POINT', 'ARM_MOVE_TO_J'].includes(props.data.properties.action)" size="small" @click="openRobotForm(props.data.properties.action)">获取位置</el-button>
<el-button type="primary" v-if="['AGV_MOVE_TO_POINT', 'AGV_MOVE_TO_STATION', 'ARM_MOVE_TO_POINT', 'ARM_MOVE_TO_J'].includes(props.data.properties.action)" size="small" @click="openRobotForm(props.data.properties.action)">{{ robotActionButtonText }}</el-button>
<el-form :inline="true" :model="formData" :rules="rules" ref="dynamicFormRef" label-position="top"
label-width="auto">
<div v-for="(property, index) in formData.nodeParams" :key="index">
@ -22,7 +22,7 @@
v-model="property.name" placeholder="请输入" clearable />
</el-form-item>
<el-form-item :label="index === 0 ? '参数值' : ''" :prop="`nodeParams.${index}.type`">
<el-select v-model="property.type" class="param-type" @change="handleTypeChange(index, formData, property.type)">
<el-select v-model="property.type" class="param-type" :disabled="property?.forceSelect || false" @change="handleTypeChange(index, formData, property.type)">
<el-option label="引用" value="quote" />
<el-option label="输入" value="input" />
</el-select>
@ -82,7 +82,7 @@
<el-dialog
v-model="dialogVisible"
title="获取位置信息"
:title="robotFormAction === 'AGV_MOVE_TO_STATION' ? '加载AGV站点列表' : '获取位置信息'"
width="360"
>
<el-form ref="robotFormRef" :model="robotForm" :rules="robotFormRules" label-width="auto">
@ -95,19 +95,19 @@
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitRobotForm">确认</el-button>
<el-button type="primary" :loading="stationListLoading" @click="submitRobotForm">确认</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, watch, nextTick } from 'vue'
import { computed, ref, reactive, watch, nextTick } from 'vue'
import { Plus, Minus } from '@element-plus/icons-vue'
import FormItemRecursive from '../FormItemRecursive.vue'
import { getInput } from '@/utils/flow'
import { useQuote } from './useQuote.js'
import { getArmStatus, getArmJointState, getAgvStatus } from '@/api/device/flow'
import { de } from 'element-plus/es/locale/index.mjs'
import { getArmStatus, getArmJointState, getAgvStatus, getAgvStations } from '@/api/device/flow'
import { ElMessage } from 'element-plus'
const props = defineProps({
data: Object
@ -210,6 +210,18 @@ const robotForm = reactive({
})
const testRule = (property) => {
if (property?.name === 'stationId' && props.data.properties.action === 'AGV_MOVE_TO_STATION') {
return [
{ required: true, message: '请从站点列表中选择站点', trigger: 'change' },
{ validator: () => {
const deviceId = formData.nodeParams.find(param => param.name === 'deviceId')?.input
const selectedFromList = property.selectOptions?.some(option => option.value === property.input)
if (selectedFromList && property.stationDeviceId === deviceId) return Promise.resolve()
return Promise.reject(new Error('设备已变化,请重新加载站点列表'))
}, trigger: 'change' }
]
}
if (property?.name === 'acceleration') {
return [
{ required: true, message: '请输入参数值', trigger: 'blur' },
@ -241,6 +253,10 @@ const testRule = (property) => {
}
const robotFormAction = ref()
const stationListLoading = ref(false)
const robotActionButtonText = computed(() =>
props.data.properties.action === 'AGV_MOVE_TO_STATION' ? '加载站点列表' : '获取位置'
)
const submitRobotForm = () => {
if (robotFormAction.value === 'AGV_MOVE_TO_POINT') {
@ -269,6 +285,39 @@ const submitRobotForm = () => {
}
}
})
} else if (robotFormAction.value === 'AGV_MOVE_TO_STATION') {
robotFormRef.value.validate(async (valid) => {
if (valid) {
stationListLoading.value = true
try {
const response = await getAgvStations({
deviceId: robotForm.deviceId,
terminalId: robotForm.terminalId
})
const stationOptions = toStationOptions(response?.data)
if (stationOptions.length === 0) {
throw new Error('AGV未返回可用站点')
}
const stationParam = formData.nodeParams.find(param => param.name === 'stationId')
const deviceParam = formData.nodeParams.find(param => param.name === 'deviceId')
if (stationParam) {
stationParam.selectOptions = stationOptions
stationParam.stationDeviceId = robotForm.deviceId
if (!stationOptions.some(item => item.value === stationParam.input)) {
stationParam.input = ''
}
}
if (deviceParam) deviceParam.input = robotForm.deviceId
dialogVisible.value = false
ElMessage.success(`已加载${stationOptions.length}个AGV站点`)
} catch (error) {
console.error('加载AGV站点列表失败:', error)
ElMessage.error(error?.message || '加载AGV站点列表失败')
} finally {
stationListLoading.value = false
}
}
})
} else if (robotFormAction.value === 'ARM_MOVE_TO_POINT') {
robotFormRef.value.validate(async (valid) => {
if (valid) {
@ -325,6 +374,17 @@ const submitRobotForm = () => {
}
}
const toStationOptions = (stations) => (Array.isArray(stations) ? stations : [])
.filter(station => station?.id !== undefined && station?.id !== null && String(station.id).trim())
.map(station => {
const id = String(station.id).trim()
const description = station.description ? String(station.description).trim() : ''
return {
value: id,
label: description ? `${id} - ${description}` : id
}
})
const openRobotForm = (action) => {
dialogVisible.value = true
robotFormAction.value = action