huang
2025-12-02 628aa6a42e587e9f337e213f87f922fc2ab2af02
mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
@@ -26,61 +26,34 @@
    </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进行测试(代替卧转立扫码);如果不输入,将从数据库读取最近扫码的玻璃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="位置编码">
        <el-input
          v-model="form.positionCode"
          placeholder="例如:POS1"
          clearable
        />
        <div class="form-tip">上大车设备的位置编码</div>
      </el-form-item>
      <el-form-item label="位置值">
        <el-input-number
          v-model="form.positionValue"
          :min="0"
          :max="9999"
          placeholder="位置数值"
        />
        <div class="form-tip">上大车设备的位置数值</div>
      </el-form-item>
      <el-form-item label="存储位置">
        <el-input-number
          v-model="form.storagePosition"
          :min="1"
          :max="200"
          placeholder="存储位置编号"
        />
        <div class="form-tip">玻璃存储设备的存储位置</div>
      </el-form-item>
      <el-form-item label="处理类型">
        <el-select v-model="form.processType" placeholder="选择处理类型" clearable>
          <el-option label="标准处理" :value="1" />
          <el-option label="快速处理" :value="2" />
          <el-option label="慢速处理" :value="3" />
        </el-select>
        <div class="form-tip">大理片设备的处理类型</div>
      </el-form-item>
      <el-divider content-position="left">执行配置</el-divider>
      <el-form-item label="单片间隔 (秒)">
        <el-input-number
          v-model="form.glassIntervalSeconds"
          :min="0"
          :max="60"
          :step="0.1"
          :precision="1"
          placeholder="每个玻璃ID之间的间隔时间"
        />
        <div class="form-tip">多个玻璃ID时,每个玻璃ID传递之间的间隔时间(秒),用于模拟玻璃每片运动的时间。0表示一次性全部传递</div>
      </el-form-item>
      
      <el-form-item label="执行间隔 (ms)">
        <el-input-number
@@ -133,14 +106,11 @@
})
const emit = defineEmits(['task-started'])
//配置默认值
const form = reactive({
  positionCode: '',
  positionValue: null,
  storagePosition: null,
  processType: null,
  glassIntervalSeconds: 10, // 单片间隔,默认10秒
  executionInterval: 1000,
  timeoutMinutes: 30,
  timeoutMinutes: 1,
  retryCount: 3
})
@@ -150,8 +120,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 {
@@ -195,6 +167,8 @@
    .filter((item) => item.length > 0)
})
const normalizeType = (type) => (type || '').trim().toUpperCase()
const fetchLoadDevice = async () => {
  loadDeviceId.value = null
  loadDeviceName.value = ''
@@ -216,9 +190,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}`
@@ -246,33 +226,22 @@
    return
  }
  
  if (glassIds.value.length === 0) {
    ElMessage.warning('请至少输入一个玻璃ID')
    return
  }
  try {
    loading.value = true
    
    // 构建任务参数
    // 如果输入了玻璃ID,使用输入的;如果没有输入,glassIds为空数组,后端会从数据库读取
    // 将秒转换为毫秒传给后端
    const glassIntervalMs = form.glassIntervalSeconds != null && form.glassIntervalSeconds !== undefined
      ? Math.round(form.glassIntervalSeconds * 1000)
      : 1000
    const parameters = {
      glassIds: glassIds.value,
      glassIds: glassIds.value.length > 0 ? glassIds.value : [],
      glassIntervalMs: glassIntervalMs,
      executionInterval: form.executionInterval || 1000
    }
    
    // 添加可选参数
    if (form.positionCode) {
      parameters.positionCode = form.positionCode
    }
    if (form.positionValue !== null) {
      parameters.positionValue = form.positionValue
    }
    if (form.storagePosition !== null) {
      parameters.storagePosition = form.storagePosition
    }
    if (form.processType !== null) {
      parameters.processType = form.processType
    }
    // 设备特定配置已移除,如有需要可在此扩展
    if (form.timeoutMinutes) {
      parameters.timeoutMinutes = form.timeoutMinutes
    }
@@ -296,12 +265,8 @@
        emit('task-started')
      }, 500)
      
      // 重置表单(保留部分配置),方便继续启动其他设备组
      // 重置表单(保留执行配置),方便继续启动其他设备组
      glassIdsInput.value = ''
      form.positionCode = ''
      form.positionValue = null
      form.storagePosition = null
      form.processType = null
      
      // 提示用户可以继续启动其他设备组
      ElMessage.info('可以继续选择其他设备组启动测试,多个设备组将并行执行')
@@ -321,17 +286,15 @@
    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',
      params: {
        positionCode: form.positionCode || null
      }
      operation: 'clearPlc',
      params: {}
    })
    if (response?.code !== 200) {
      throw new Error(response?.message || 'PLC清空失败')