mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
@@ -26,55 +26,28 @@
    </div>
    <el-form :model="form" label-width="120px" :rules="rules" ref="formRef">
      <el-form-item label="玻璃ID列表" prop="glassIds" required>
      <el-form-item label="玻璃ID列表" prop="glassIds">
        <el-input
          v-model="glassIdsInput"
          type="textarea"
          :rows="4"
          placeholder="请输入玻璃条码,支持多行或逗号分隔,每行一个或逗号分隔"
          placeholder="可选:输入玻璃ID,将使用输入的ID进行测试"
          show-word-limit
          :maxlength="5000"
        />
        <div class="form-tip">
          已输入 {{ glassIds.length }} 个玻璃ID
          <span v-if="glassIds.length > 0">已输入 {{ glassIds.length }} 个玻璃ID(测试模式:使用输入的ID)</span>
          <span v-else>未输入玻璃ID(正常模式:将从数据库读取最近扫码的玻璃ID)</span>
        </div>
      </el-form-item>
      <el-divider content-position="left">执行配置</el-divider>
      <el-form-item label="执行间隔 (ms)">
        <el-input-number
          v-model="form.executionInterval"
          :min="100"
          :max="10000"
          :step="100"
          placeholder="设备操作间隔时间"
        />
        <div class="form-tip">每个设备操作之间的间隔时间(毫秒)</div>
      </el-form-item>
      <el-form-item label="超时时间 (分钟)">
        <el-input-number
          v-model="form.timeoutMinutes"
          :min="1"
          :max="60"
          :step="1"
          placeholder="任务超时时间"
        />
        <div class="form-tip">任务执行的最大超时时间</div>
      </el-form-item>
      <el-form-item label="重试次数">
        <el-input-number
          v-model="form.retryCount"
          :min="0"
          :max="10"
          :step="1"
          placeholder="失败重试次数"
        />
        <div class="form-tip">设备操作失败时的最大重试次数</div>
      </el-form-item>
    </el-form>
    <!-- 设备组拓扑图 -->
    <GroupTopology
      v-if="group"
      :group="group"
      class="topology-section"
    />
  </div>
</template>
@@ -84,6 +57,7 @@
import { Delete, Promotion } from '@element-plus/icons-vue'
import { multiDeviceTaskApi } from '@/api/device/multiDeviceTask'
import { deviceGroupApi, deviceInteractionApi } from '@/api/device/deviceManagement'
import GroupTopology from '../DeviceGroup/GroupTopology.vue'
const props = defineProps({
  group: {
@@ -93,12 +67,8 @@
})
const emit = defineEmits(['task-started'])
const form = reactive({
  executionInterval: 1000,
  timeoutMinutes: 30,
  retryCount: 3
})
//配置默认值
const form = reactive({})
const formRef = ref(null)
@@ -106,8 +76,10 @@
  glassIds: [
    {
      validator: (rule, value, callback) => {
        // 如果输入了玻璃ID,则进行验证;如果没有输入,则允许(将从数据库读取)
        if (glassIds.value.length === 0) {
          callback(new Error('请至少输入一个玻璃ID'))
          // 允许为空,将从数据库读取最近扫码的玻璃ID
          callback()
        } else if (glassIds.value.length > 100) {
          callback(new Error('玻璃ID数量不能超过100个'))
        } else {
@@ -151,6 +123,8 @@
    .filter((item) => item.length > 0)
})
const normalizeType = (type) => (type || '').trim().toUpperCase()
const fetchLoadDevice = async () => {
  loadDeviceId.value = null
  loadDeviceName.value = ''
@@ -172,9 +146,15 @@
      : Array.isArray(rawList?.data)
      ? rawList.data
      : []
    const targetDevice =
      deviceList.find((item) => (item.deviceType || '').toUpperCase() === 'LOAD_VEHICLE') ||
      deviceList[0]
    const scannerDevice = deviceList.find((item) => {
      const type = normalizeType(item.deviceType)
      return type.includes('SCANNER') || type.includes('扫码')
    })
    const loadVehicleDevice = deviceList.find((item) => {
      const type = normalizeType(item.deviceType)
      return type.includes('LOAD_VEHICLE') || type.includes('大车')
    })
    const targetDevice = scannerDevice || loadVehicleDevice || deviceList[0]
    if (targetDevice && targetDevice.id) {
      loadDeviceId.value = targetDevice.id
      loadDeviceName.value = targetDevice.deviceName || targetDevice.deviceCode || `ID: ${targetDevice.id}`
@@ -202,26 +182,13 @@
    return
  }
  
  if (glassIds.value.length === 0) {
    ElMessage.warning('请至少输入一个玻璃ID')
    return
  }
  try {
    loading.value = true
    
    // 构建任务参数
    // 如果输入了玻璃ID,使用输入的;如果没有输入,glassIds为空数组,后端会从数据库读取
    const parameters = {
      glassIds: glassIds.value,
      executionInterval: form.executionInterval || 1000
    }
    // 设备特定配置已移除,如有需要可在此扩展
    if (form.timeoutMinutes) {
      parameters.timeoutMinutes = form.timeoutMinutes
    }
    if (form.retryCount !== null) {
      parameters.retryCount = form.retryCount
      glassIds: glassIds.value.length > 0 ? glassIds.value : []
    }
    
    // 异步启动任务,立即返回,不阻塞
@@ -261,14 +228,14 @@
    return
  }
  if (!loadDeviceId.value) {
    ElMessage.warning('未找到上大车设备,无法清空PLC')
    ElMessage.warning('未找到对应设备,无法清空PLC')
    return
  }
  try {
    clearLoading.value = true
    const response = await deviceInteractionApi.executeOperation({
      deviceId: loadDeviceId.value,
      operation: 'clearGlass',
      operation: 'clearPlc',
      params: {}
    })
    if (response?.code !== 200) {
@@ -337,5 +304,9 @@
  margin-top: 4px;
  line-height: 1.4;
}
.topology-section {
  margin-top: 24px;
}
</style>