huang
4 天以前 9dcde5b27b70a4b0c0885347af5405eb2d1ef089
mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
@@ -35,12 +35,51 @@
    </div>
    <el-form :model="form" label-width="120px" :rules="rules" ref="formRef">
      <div style="width: 350px; margin-bottom: 12px; margin-left: 120px;">
          <el-select
            v-model="selectedEngineeringId"
            placeholder="选择工程号(选择后自动填充玻璃ID)"
            clearable
            filterable
            :disabled="!group"
            :loading="engineeringListLoading"
            @change="handleEngineeringChange"
            style="width: 100%"
          >
            <el-option
              v-for="item in engineeringList"
              :key="item.engineeringId"
              :label="item.engineeringId"
              :value="item.engineeringId"
            >
              <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
                <div style="flex: 1;">
                  <span>{{ item.engineeringId }}</span>
                  <span style="margin-left: 8px; color: #8492a6; font-size: 12px">
                    {{ item.date ? new Date(item.date).toLocaleDateString() : '' }}
                  </span>
                </div>
                <el-button
                  type="danger"
                  link
                  size="small"
                  :loading="deletingEngineeringId === item.engineeringId"
                  @click.stop="handleDeleteEngineering(item.engineeringId)"
                  style="margin-left: 8px; padding: 0 4px;"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </el-option>
          </el-select>
        </div>
      <el-form-item label="玻璃ID列表" prop="glassIds">
        <el-input
          v-model="glassIdsInput"
          type="textarea"
          :rows="4"
          placeholder="可选:输入玻璃ID,将使用输入的ID进行测试"
          placeholder="可选:输入玻璃ID,将使用输入的ID进行测试(或通过上方选择工程号自动填充)"
          show-word-limit
          :maxlength="5000"
        />
@@ -57,8 +96,8 @@
</template>
<script setup>
import { computed, reactive, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { computed, reactive, ref, watch, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, Promotion, Upload } from '@element-plus/icons-vue'
import * as XLSX from 'xlsx'
import { multiDeviceTaskApi } from '@/api/device/multiDeviceTask'
@@ -116,13 +155,27 @@
const loadDeviceLoading = ref(false)
const fileInputRef = ref(null)
// 工程号相关
const selectedEngineeringId = ref('')
const engineeringList = ref([])
const engineeringListLoading = ref(false)
const glassIdsLoading = ref(false)
const deletingEngineeringId = ref('')
watch(
  () => props.group,
  () => {
    glassIdsInput.value = ''
    selectedEngineeringId.value = ''
    fetchLoadDevice()
    fetchEngineeringList()
  }
)
// 组件挂载时加载工程号列表
onMounted(() => {
  fetchEngineeringList()
})
const glassIds = computed(() => {
  if (!glassIdsInput.value) return []
@@ -131,6 +184,108 @@
    .map((item) => item.trim())
    .filter((item) => item.length > 0)
})
// 获取工程号列表
const fetchEngineeringList = async () => {
  try {
    engineeringListLoading.value = true
    const response = await engineeringApi.getEngineeringList()
    if (Array.isArray(response)) {
      engineeringList.value = response
    } else if (Array.isArray(response?.data)) {
      engineeringList.value = response.data
    } else {
      engineeringList.value = []
    }
    // 按日期倒序排列
    engineeringList.value.sort((a, b) => {
      const dateA = a.date ? new Date(a.date).getTime() : 0
      const dateB = b.date ? new Date(b.date).getTime() : 0
      return dateB - dateA
    })
  } catch (error) {
    console.error('获取工程号列表失败:', error)
    ElMessage.error(error?.message || '获取工程号列表失败')
    engineeringList.value = []
  } finally {
    engineeringListLoading.value = false
  }
}
// 处理工程号选择变化
const handleEngineeringChange = async (engineeringId) => {
  if (!engineeringId) {
    // 清空选择时,不清空已输入的玻璃ID,让用户保留
    return
  }
  try {
    glassIdsLoading.value = true
    const response = await engineeringApi.getGlassIdsByEngineeringId(engineeringId)
    const glassIds = response?.glassIds || response?.data?.glassIds || []
    if (glassIds.length > 0) {
      glassIdsInput.value = glassIds.join('\n')
      ElMessage.success(`已加载工程号 ${engineeringId} 的 ${glassIds.length} 个玻璃ID`)
    } else {
      ElMessage.warning(`工程号 ${engineeringId} 下没有找到玻璃ID`)
    }
  } catch (error) {
    console.error('获取玻璃ID列表失败:', error)
    ElMessage.error(error?.message || '获取玻璃ID列表失败')
  } finally {
    glassIdsLoading.value = false
  }
}
// 处理删除工程号
const handleDeleteEngineering = async (engineeringId) => {
  if (!engineeringId) {
    return
  }
  try {
    await ElMessageBox.confirm(
      `确定要删除工程号 "${engineeringId}" 及其关联的所有玻璃信息吗?此操作不可恢复!`,
      '确认删除',
      {
        confirmButtonText: '确定删除',
        cancelButtonText: '取消',
        type: 'warning',
        dangerouslyUseHTMLString: false
      }
    )
    deletingEngineeringId.value = engineeringId
    const response = await engineeringApi.deleteEngineering(engineeringId)
    const result = response?.data || response
    if (result?.success !== false) {
      const deletedCount = result?.deletedGlassCount || 0
      ElMessage.success(`已删除工程号 ${engineeringId},共删除 ${deletedCount} 条玻璃信息`)
      // 如果删除的是当前选中的工程号,清空选择
      if (selectedEngineeringId.value === engineeringId) {
        selectedEngineeringId.value = ''
        glassIdsInput.value = ''
      }
      // 刷新工程号列表
      await fetchEngineeringList()
    } else {
      throw new Error(result?.message || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除工程号失败:', error)
      ElMessage.error(error?.message || '删除工程号失败')
    }
  } finally {
    deletingEngineeringId.value = ''
  }
}
const normalizeType = (type) => (type || '').trim().toUpperCase()
@@ -461,7 +616,7 @@
    const qty = parseInt(quantity) || 1
    for (let j = 0; j < qty; j++) {
      // 如果数量大于1,为每条记录生成唯一的玻璃ID(追加序号)
      const finalGlassId = qty > 1 ? `${glassId}_${j + 1}` : glassId
      const finalGlassId = qty > 1 ? `${glassId}${j + 1}` : glassId
      result.push({
        glassId: finalGlassId,
@@ -508,10 +663,16 @@
        : `成功导入 ${glassDataList.length} 条玻璃数据`
      ElMessage.success(successMsg)
      // 将导入的玻璃ID填充到输入框,方便用户查看和编辑
      const glassIds = glassDataList.map(item => item.glassId).filter(id => id)
      if (glassIds.length > 0) {
        glassIdsInput.value = glassIds.join('\n')
      // 成功后刷新工程号下拉列表,并选中最新工程号
      try {
        await fetchEngineeringList()
        if (engineerId) {
          selectedEngineeringId.value = engineerId
          // 刷新并回填后端保存的 glassId(带工程号前缀),避免使用前端原始值
          await handleEngineeringChange(engineerId)
        }
      } catch (refreshErr) {
        console.error('刷新工程号列表失败:', refreshErr)
      }
    } else {
      // MES 接口返回失败