<template>
  <div class="card modern-card">
    <div style="display: flex; justify-content: flex-end; margin-bottom: 12px;position: relative;">
      <div v-if="currentPartitionName"
        style="position: absolute; left: 10px; top: 10px; font-size: .8rem; color: #409EFF; font-weight: bold; letter-spacing: 1px;">
        {{ currentPartitionName }}
      </div>
      <!-- <el-button type="primary" @click="onReturnPalletClick">退空托盘</el-button> -->
    </div>
    <div class="storList">
      <div class="storList-item modern-item" v-for="item in opStoreData" :key="item.StockCode"
        @click="handleClick(item)">
        <div class="storList-header">
          <span class="storList-title">{{ item.StockName }}</span>
          <div class="storList-tags">
            <van-tag type="danger" v-if="item.TaskId != null">任务中</van-tag>
            <van-tag type="primary" v-if="item.StockStatus == false && !item.TrayNo">空库位</van-tag>
            <van-tag type="warning" v-if="item.StockStatus == false && item.TrayNo">空托盘</van-tag>
            <van-tag type="success" v-if="item.StockStatus == true">满料</van-tag>
          </div>
        </div>
        <div class="storList-info">
          <span><i class="iconfont icon-project"></i> 项目名称：<b>{{ item.ProjectNo }}</b></span>
          <span><i class="iconfont icon-product"></i> 间隔编号：<b>{{ item.IntervalNo }}</b></span>
          <span><i class="iconfont icon-model"></i> 部件位置：<b>{{ item.ComponentLocation }}</b></span>
          <span><i class="iconfont icon-tuopan"></i> 托盘编号：<b>{{ item.TrayNo }}</b></span>
        </div>
      </div>
    </div>
    <el-dialog v-model="showStockDialog" :title="stockDialogTitle" width="400px" :close-on-click-modal="false"
      @close="onStockDialogClose">
      <div v-if="stockList.length > 0">
        <div v-for="item in stockList" :key="item.code" @click="onStockSelect(item)"
          style="cursor:pointer; border-bottom:1px solid #eee; padding:12px 0;">
          <div style="display:flex;flex-direction:column;">
            <span><b>库位名称：</b>{{ item.name }}</span>
            <span><b>组件位置：</b>{{ item.ComponentLocation }}</span>
            <span><b>间隔号：</b>{{ item.IntervalNo }}</span>
          </div>
        </div>
      </div>
      <div v-else style="text-align:center;color:#888;">暂无可用库位</div>
    </el-dialog>
    <van-action-sheet v-model:show="showActionSheet" :actions="actionList" @select="onActionSelect" title="请选择操作" />
    <van-action-sheet v-model:show="showCallMaterialSheet" :actions="callMaterialActions" @select="onCallMaterialSelect"
      title="请选择操作" />
    <van-action-sheet v-model:show="showReturnMaterialSheet" :actions="returnMaterialActions"
      @select="onReturnMaterialSelect" title="请选择操作" />
    <el-dialog v-model="showReturnPalletDialog" title="退空托盘" width="320px" :close-on-click-modal="false"
      @close="onReturnPalletCancel">
      <el-form @submit.prevent>
        <el-form-item label="托盘码">
          <el-input v-model="returnPalletCode" placeholder="请扫描托盘码" clearable autofocus
            @keyup.enter="onReturnPalletConfirm" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="onReturnPalletCancel">取消</el-button>
        <el-button type="primary" @click="onReturnPalletConfirm">校验</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="showEditStockDialog" title="修改库位信息" width="340px" :close-on-click-modal="false"
      @close="onEditStockCancel">
      <el-form @submit.prevent>
        <el-form-item label="项目名称">
          <el-input v-model="editStockForm.ProjectName" placeholder="请扫描或输入 项目名称 或 三段码" clearable @input="onEngineNoInput" />
        </el-form-item>
        <el-form-item label="间隔编号">
          <el-input v-model="editStockForm.IntervalNo" placeholder="请输入 间隔编号" clearable />
        </el-form-item>
        <el-form-item label="部件位置">
          <el-input v-model="editStockForm.ComponentLocation" placeholder="请输入 部件位置" clearable />
        </el-form-item>
        <el-form-item label="托盘编号">
          <el-input v-model="editStockForm.TrayNo" placeholder="请输入 托盘编号（仅托盘码时只填此项）" clearable />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="onEditStockCancel">取消</el-button>
        <el-button type="primary" @click="onEditStockConfirm">确认</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { v4 as uuidv4 } from 'uuid'
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useAppStore } from '@/store/app.js'
import { Dialog, ActionSheet, Toast } from 'vant'
import { ElMessage, ElMessageBox } from 'element-plus'
const store = useAppStore()
const { user } = storeToRefs(store)

const ExecDatabaseByParam = inject('ExecDatabaseByParam')
const ExecAgvApi = inject('ExecAgvApi')

const opStoreCode = ref(-1)

// 补充定义 stockList
const stockList = ref([])

// 添加 selectedStock 定义
const selectedStock = ref(null)

// StockCode 库位编号
// StockName 库位名称
// StockStatus 满料状态 bool
// TrayNo 托盘号
// IntervalNo 间隔号
// ComponentLocation 组件位置
// TaskId 任务号
const opStoreData = reactive([])
// 库区列表
const partitionList = reactive([])

// 物料验证相关数据
const MaterialData = reactive({})

// 目标库区数据
const targetPartition = reactive({
  callMaterial: null, // 叫料库区
  returnMaterial: null, // 退料库区
  returnPallet: null // 退空托库区
})

// 库位选择数据
const showStockDialog = ref(false)
const stockDialogTitle = ref('')

const showActionSheet = ref(false)
const actionList = [
  { name: '库位绑定' }
]
const currentItem = ref(null)

const showInputDialog = ref(false)
const inputValue = ref('')

const showReturnPalletDialog = ref(false)
const returnPalletCode = ref('')
const returnPalletStock = ref(null)

// 叫托盘相关数据
const showCallMaterialSheet = ref(false)
const callMaterialActions = [
  { name: '叫托盘' }
]

// 空库位 -> 叫托盘
const onCallMaterialSelect = async (action) => {
  showCallMaterialSheet.value = false
  if (action.name === '叫托盘') {
    // 获取空托盘来源库区（退空托库区）
    const routes = await getRoutePartitions(currentItem.value.StockCode)
    if (!routes || !routes.returnPallet) {
      ElMessage.warning('未配置退空托库区，请联系管理员')
      return
    }

    // 记录目标库区
    targetPartition.returnPallet = routes.returnPallet

    // 根据目标库区获取库位列表
    const stockRes = await ExecAgvApi('getStockList', { PartitionCode: targetPartition.returnPallet })
    if (!stockRes.Result) {
      ElMessage.error(stockRes.ErrMsg || '获取库位失败')
      return
    }

    // 只显示空托盘库位（有托盘、无产品、状态为空），排除"无库位"
    stockList.value = (stockRes.Data || [])
      .filter(i => i.TrayNo && (!i.ProjectNo || i.ProjectNo === '') && (!i.IntervalNo || i.IntervalNo === '') && (!i.ComponentLocation || i.ComponentLocation === '') && i.StockStatus === false && i.StockName !== '无库位')
      .map(i => ({ name: i.StockName, code: i.StockCode, ...i }))

    if (stockList.value.length === 0) {
      ElMessage.warning('目标库区没有可用空托盘库位')
      return
    }

    // 设置叫托盘流程标识
    isCallMaterialFlow.value = true
    stockDialogTitle.value = await getPartitionName(targetPartition.returnPallet)
    showStockDialog.value = true
  }
}

const isCallMaterialFlow = ref(false)
const currentPartitionName = ref('')

// 有产品库位 -> 送料/修改
const showReturnMaterialSheet = ref(false)
const returnMaterialActions = [
  { name: '送料' },
  { name: '修改库位信息' }
]

// 有产品库位：选择送料或修改库位信息
const onReturnMaterialSelect = async (action) => {
  showReturnMaterialSheet.value = false
  if (action.name === '修改库位信息') {
    // 预填当前库位信息
    editStockForm.ProjectName = currentItem.value.ProjectNo || ''
    editStockForm.IntervalNo = currentItem.value.IntervalNo || ''
    editStockForm.ComponentLocation = currentItem.value.ComponentLocation || ''
    editStockForm.TrayNo = currentItem.value.TrayNo || ''
    editStockForm.StockCode = currentItem.value.StockCode
    editStockForm.TaskId = currentItem.value.TaskId
    showEditStockDialog.value = true
    return
  }

  if (action.name === '送料') {
    // 获取送料目标库区（叫料库区）
    const routes = await getRoutePartitions(currentItem.value.StockCode)
    if (!routes || !routes.callMaterial) {
      ElMessage.warning('未配置叫料路线，请联系管理员')
      return
    }

    // 记录目标库区
    targetPartition.callMaterial = routes.callMaterial

    // 根据目标库区获取库位列表
    const stockRes = await ExecAgvApi('getStockList', { PartitionCode: targetPartition.callMaterial })
    if (!stockRes.Result) {
      ElMessage.error(stockRes.ErrMsg || '获取库位失败')
      return
    }

    // 只显示空库位(无托盘且状态为空)，排除"无库位"
    stockList.value = (stockRes.Data || [])
      .filter(i => !i.TrayNo && i.StockStatus === false && i.StockName !== '无库位')
      .map(i => ({ name: i.StockName, code: i.StockCode, ...i }))

    if (stockList.value.length === 0) {
      ElMessage.warning('目标库区没有可用空库位')
      return
    }

    // 设置送料流程标识
    isReturnMaterialFlow.value = true
    stockDialogTitle.value = await getPartitionName(targetPartition.callMaterial)
    showStockDialog.value = true
  }
}

const isReturnMaterialFlow = ref(false)

// 获取预设路线库区信息
const getRoutePartitions = async (stockCode) => {
  try {
    const res = await ExecDatabaseByParam('11', 'PTCHV_AGV_送料路线_PDA查询_初始化', [['库位号', stockCode]])
    if (res.data && res.data.length > 0) {
      return {
        callMaterial: res.data[0].叫料库区,
        returnMaterial: res.data[0].退料库区,
        returnPallet: res.data[0].退空托库区
      }
    } else {
      ElMessage.warning('未找到预设的路线信息')
      return null
    }
  } catch (error) {
    console.error('获取路线信息失败:', error)
    ElMessage.error('获取路线信息失败')
    return null
  }
}

onMounted(async () => {
  await getPartitionList()
  await getOpStoreCode()
})
const getPartitionList = async () => {
  let res = await ExecDatabaseByParam('11', 'MES_计划BOM_工位与名称_库位编号_查询', [['工位号', user.value.opName]])
  if (res.data.length > 0) {
    // 处理库区编号，可能会返回多个库区，如 "7,14"
    const partitionCodes = res.data[0].库位编号.toString().split(',').map(code => code.trim())
    opStoreCode.value = partitionCodes[0] // 保存第一个库区编号作为主库区

    // 查找库区名称
    partitionList.length = 0
    const partitionRes = await ExecAgvApi('getPartitionList', {})
    if (partitionRes.Result) {
      partitionList.push(...partitionRes.Data)
      currentPartitionName.value = await getPartitionName(opStoreCode.value)
    }
  } else {
    ElMessage.warning('此工位无对应库位!')
  }
}

// 获取对应库位编号名称
const getPartitionName = async (partitionCode) => {
  const found = partitionList.find(i => i.PartitionCode == partitionCode)
  return found ? found.PartitionName : ''
}

const getOpStoreCode = async () => {
  // 获取MES_计划BOM_工位与名称_库位编号_查询返回的所有库区编号
  const res = await ExecDatabaseByParam('11', 'MES_计划BOM_工位与名称_库位编号_查询', [['工位号', user.value.opName]])
  if (res.data.length === 0) {
    ElMessage.warning('此工位无对应库位!')
    return
  }

  // 清空现有数据
  opStoreData.length = 0

  // 处理可能有多个库区编号的情况（如 "7,14"）
  const partitionCodes = res.data[0].库位编号.toString().split(',').map(code => code.trim())

  // 依次查询每个库区的库位信息并合并
  for (const partitionCode of partitionCodes) {
    const agvPar = {
      "PartitionCode": partitionCode
    }
    const agvRes = await ExecAgvApi('getStockList', agvPar)

    if (agvRes.Result) {
      // 将查询到的库位信息添加到列表中，过滤"无库位"
      const filteredData = (agvRes.Data || []).filter(item => item.StockName !== '无库位')
      opStoreData.push(...filteredData)
    } else {
      ElMessage.error(`获取库区${partitionCode}信息失败: ${agvRes.ErrMsg}`)
    }
  }

  // 如果没有任何库位信息
  if (opStoreData.length === 0) {
    ElMessage.error('未获取到任何库位信息')
  }
}

const handleClick = async (item) => {
  if (item.TaskId != null) {
    Dialog.alert({
      title: '提示',
      message: '该库位存在任务，不可操作',
    })
    return
  }
  // 满料库位：退料流程
  if (item.StockStatus === true) {
    currentItem.value = item
    showReturnMaterialSheet.value = true
    return
  }
  // 空托盘：退空托盘流程
  if (item.StockStatus === false && item.TrayNo) {
    currentItem.value = item
    showActionSheet.value = true
    return
  }
  // 空库位：叫料流程
  if (item.StockStatus === false && !item.TrayNo) {
    currentItem.value = item
    showCallMaterialSheet.value = true
    return
  }
}

// 选择库位后的处理
const onStockItemClick = (item) => {
  // 二次确认

}

const onStockDialogClose = () => {
  showStockDialog.value = false
}

const onStockSelect = async (stock) => {
  selectedStock.value = stock
  showStockDialog.value = false

  if (isCallMaterialFlow.value) {
    // 校验所选是否空托盘库位
    const isPureEmptyPallet = stock.TrayNo && (!stock.IntervalNo || stock.IntervalNo === '') && (!stock.ComponentLocation || stock.ComponentLocation === '') && stock.StockStatus === false
    if (!isPureEmptyPallet) {
      ElMessage.warning('库位不符合空托盘库位')
      isCallMaterialFlow.value = false
      return
    }

    // 叫托盘流程确认
    ElMessageBox.confirm(`是否将空托盘 从库位【${stock.name}】送至库位【${currentItem.value.StockName}】？`, '确认叫托盘', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      const taskId = uuidv4()
      const res = await ExecAgvApi('createTask', {
        taskId,
        pickPosition: stock.code,
        dropPosition: currentItem.value.StockCode,
      })
      if (res.Result) {
        await ExecDatabaseByParam('12', 'PTCHV_AGV_送料记录_增加', [
          ['任务号', taskId],
          ['取料库位', stock.code],
          ['取料库位名称', stock.name],
          ['取料项目名称', ''],
          ['取料间隔编号', ''],
          ['取料部件位置', ''],
          ['取料托盘编号', stock.TrayNo || ''],
          ['送料库位', currentItem.value.StockCode],
          ['送料库位名称', currentItem.value.StockName],
          ['操作人', user.value.name],
          ['type', 3],
        ])
        ElMessage.success('叫托盘任务创建成功')
        getOpStoreCode()
      } else {
        ElMessage.error(res.ErrMsg || '叫托盘任务创建失败')
      }
      isCallMaterialFlow.value = false
    })
  } else if (isReturnMaterialFlow.value) {
    // 送料流程确认
    Dialog.confirm({
      title: '确认送料',
      message: `是否将物料送至库位【${stock.name}】？`,
      confirmButtonText: '确认',
      cancelButtonText: '取消',
    }).then(async () => {
      const taskId = uuidv4()
      const res = await ExecAgvApi('createTask', {
        taskId,
        pickPosition: currentItem.value.StockCode,
        dropPosition: stock.code,
      })
      if (res.Result) {
        await ExecDatabaseByParam('12', 'PTCHV_AGV_送料记录_增加', [
          ['任务号', taskId],
          ['取料库位', currentItem.value.StockCode],
          ['取料库位名称', currentItem.value.StockName],
          ['取料项目名称', currentItem.value.ProjectNo || ''],
          ['取料间隔编号', currentItem.value.IntervalNo || ''],
          ['取料部件位置', currentItem.value.ComponentLocation || ''],
          ['取料托盘编号', currentItem.value.TrayNo || ''],
          ['送料库位', stock.code],
          ['送料库位名称', stock.name],
          ['操作人', user.value.name],
          ['type', 1],
        ])
        ElMessage.success('送料任务创建成功')
        getOpStoreCode()
      } else {
        ElMessage.error(res.ErrMsg || '送料任务创建失败')
      }
      isReturnMaterialFlow.value = false
    }).catch(() => {
      isReturnMaterialFlow.value = false
    })
  } else if (isReturnPalletFlow.value) {
    // 获取目标库区名称
    const partitionName = await getPartitionName(targetPartition.returnPallet)

    // 退空托盘流程确认
    Dialog.confirm({
      title: '确认退空托盘',
      message: `是否将空托盘退至 库位【${stock.name}】？`,
      confirmButtonText: '确认',
      cancelButtonText: '取消',
    }).then(async () => {
      // 先更新库位信息
      const oldTrayNo = returnPalletStock.value.TrayNo || ''
      const oldIntervalNo = returnPalletStock.value.IntervalNo || ''
      const oldComponentLocation = returnPalletStock.value.ComponentLocation || ''
      const stockName = returnPalletStock.value.StockName || ''

      const updateRes = await ExecAgvApi('updateStockInfo', {
        StockCode: returnPalletStock.value.StockCode,
        StockStatus: false,
        TrayNo: oldTrayNo,
        ProjectNo: null,
        IntervalNo: null,
        ComponentLocation: null,
        TaskId: returnPalletStock.value.TaskId
      })

      if (!updateRes.Result) {
        ElMessage.error(updateRes.ErrMsg || '库位信息更新失败')
        return
      }

      await ExecDatabaseByParam('12', 'PTCHV_AGV_库位更新记录_增加', [
        ['库位号', returnPalletStock.value.StockCode],
        ['库位名称', stockName],
        ['项目名称', ''],
        ['间隔编号', ''],
        ['部件位置', ''],
        ['托盘编号', oldTrayNo],
        ['项目名称_old', ''],
        ['间隔编号_old', oldIntervalNo],
        ['部件位置_old', oldComponentLocation],
        ['托盘编号_old', oldTrayNo],
        ['操作人', user.value.name],
        ['type', 2],
      ])

      // 创建退空托盘任务
      const taskId = uuidv4()
      const res = await ExecAgvApi('createTask', {
        taskId,
        pickPosition: returnPalletStock.value.StockCode,
        dropPosition: stock.code,
      })

      if (res.Result) {
        await ExecDatabaseByParam('12', 'PTCHV_AGV_送料记录_增加', [
          ['任务号', taskId],
          ['取料库位', returnPalletStock.value.StockCode],
          ['取料库位名称', stockName],
          ['取料项目名称', ''],
          ['取料间隔编号', ''],
          ['取料部件位置', ''],
          ['取料托盘编号', oldTrayNo],
          ['送料库位', stock.code],
          ['送料库位名称', stock.name],
          ['操作人', user.value.name],
          ['type', 3],
        ])
        ElMessage.success('退空托盘任务创建成功')
        getOpStoreCode()
      } else {
        ElMessage.error(res.ErrMsg || '退空托盘任务创建失败')
      }
      isReturnPalletFlow.value = false
    }).catch(() => {
      isReturnPalletFlow.value = false
    })
  }
}

const onInputChange = (val) => {
  if (val.length > 10) {
    // 如果 出现 &符号说明是扫描了二维码 解析出来是 <物料编号&物料图号> 只把物料编号赋值给inputValue
    if (val.split('&').length === 2) {
      const [EngineNo, SortNo] = val.split('&')
      inputValue.value = EngineNo
    }
  }
}


const onActionSelect = async (action) => {
  showActionSheet.value = false
  if (action.name === '库位绑定') {
    // 仅允许空托盘无产品信息库位执行绑定
    if (!(currentItem.value.StockStatus === false && currentItem.value.TrayNo && (!currentItem.value.ProjectNo && !currentItem.value.IntervalNo && !currentItem.value.ComponentLocation))) {
      ElMessage.warning('当前库位不符合空托盘库位条件')
      return
    }
    editStockForm.TrayNo = currentItem.value.TrayNo || ''
    editStockForm.ProjectName = ''
    editStockForm.IntervalNo = ''
    editStockForm.ComponentLocation = ''
    editStockForm.StockCode = currentItem.value.StockCode
    editStockForm.TaskId = currentItem.value.TaskId
    showEditStockDialog.value = true
  }
}

const onInputConfirm = async () => {
  if (!inputValue.value) {
    ElMessage.warning('请输入物料码')
    return
  }

  // 如果 出现 &符号说明是扫描了二维码 解析出来是 <物料编号&物料图号> 只把物料编号赋值给inputValue  
  if (inputValue.value.split('&').length === 2) {
    const [EngineNo, SortNo] = inputValue.value.split('&')
    inputValue.value = EngineNo
  }

  if (MaterialData.EngineNo != inputValue.value) {
    ElMessage.warning(`库位物料编号【${MaterialData.EngineNo}】与扫描物料编号【${inputValue.value}】不匹配`)
    return
  }
  const res = await ExecDatabaseByParam('11', 'PTCHV_物料验证记录_增加', [["工位号", user.value.opName], ["物料编号", inputValue.value], ["物料图号", MaterialData.SortNo]])
  if (res.data[0].result === 1) {
    ElMessage.success('物料校验成功')
    showInputDialog.value = false

    if (user.value.opName == 'OP010') {
      // 1. 调用 PTCHV_AGV_上线绑定 存储过程
      const resBind = await ExecDatabaseByParam('11', 'PTCHV_AGV_上线绑定', [['工位号', user.value.opName]])
      if (resBind.data && resBind.data[0].result === 1) {
        try {
          const item = resBind.data[0]
          const agvReq = {
            taskId: uuidv4(),
            EngineNo: item.工件编号,
            SortNo: item.产品型号,
            RouteCode: item.工艺路线编号
          }
          // 2. 调用 AGV API 生产上线绑定
          const agvRes = await ExecAgvApi('productionLaunchBind', agvReq)
          if (agvRes.Result) {
            // 3. 调用 PTCHV_AGV_工位放行次数_记录 存储过程
            const resPass = await ExecDatabaseByParam('12', 'PTCHV_AGV_工位放行次数_记录', [
              ['工件编号', item.工件编号],
              ['OP10', agvRes.Data.OP010PassCount],
              ['OP20', agvRes.Data.OP020PassCount],
              ['OP30', agvRes.Data.OP030PassCount]
            ])
            if (resPass.data && resPass.data[0].result === '1') {
              // 4. 调用 PTCHV_AGV_进离站 存储过程
              const param = [
                ['工位号', user.value.opName],
                ['工件编号', item.工件编号],
                ['type', 1],
                ['任务编号', agvReq.taskId]
              ]
              const resInOut = await ExecDatabaseByParam('12', 'PTCHV_AGV_进离站', param)
              if (resInOut.data && resInOut.data[0].result === '1') {
                ElMessage.success('产品上线绑定AGV成功！')
              } else {
                ElMessage.error('产品上线绑定AGV失败')
              }
            } else {
              ElMessage.error('放行次数记录失败')
            }
          } else {
            ElMessage.error(agvRes.ErrMsg)
          }
        } catch (e) {
          ElMessage.error('调度任务出错' + e.message)
          console.log(e)
        }
      } else {
        ElMessage.error('调度任务出错' + (resBind.data && resBind.data[0] && resBind.data[0].msg ? resBind.data[0].msg : ''))
      }
    }
  } else {
    ElMessage.error(res.data[0].msg)
  }
}

const onInputCancel = () => {
  showInputDialog.value = false
}

const onReturnPalletClick = () => {
  returnPalletCode.value = ''
  returnPalletStock.value = null
  showReturnPalletDialog.value = true
}

const onReturnPalletCancel = () => {
  showReturnPalletDialog.value = false
}

const onReturnPalletConfirm = async () => {
  if (!returnPalletCode.value) {
    ElMessage.warning('请输入托盘码')
    return
  }

  // 校验托盘码是否属于本库区
  const stock = opStoreData.find(i => i.TrayNo === returnPalletCode.value)
  if (!stock) {
    ElMessage.error('该托盘码不属于本库区')
    return
  }

  returnPalletStock.value = stock
  showReturnPalletDialog.value = false

  // 获取退空托盘目标库区
  const routes = await getRoutePartitions(stock.StockCode)
  if (!routes || !routes.returnPallet) {
    ElMessage.warning('未配置退空托盘路线，请联系管理员')
    return
  }

  // 记录目标库区
  targetPartition.returnPallet = routes.returnPallet

  // 根据目标库区获取库位列表
  const stockRes = await ExecAgvApi('getStockList', { PartitionCode: targetPartition.returnPallet })
  if (!stockRes.Result) {
    ElMessage.error(stockRes.ErrMsg || '获取库位失败')
    return
  }

  // 退空托盘流程：只显示无托盘库位
  stockList.value = stockRes.Data
    .filter(i => !i.TrayNo || i.TrayNo === '')
    .map(i => ({ name: i.StockName, code: i.StockCode, ...i }))

  if (stockList.value.length === 0) {
    ElMessage.warning('目标库区没有可用库位')
    return
  }

  // 设置退空托盘流程标识并显示库位选择
  isReturnPalletFlow.value = true
  showStockDialog.value = true
}

// 标记当前流程类型
const isReturnPalletFlow = ref(false)

// 库位绑定对话框
const showEditStockDialog = ref(false)
const editStockForm = reactive({
  ProjectName: '',
  IntervalNo: '',
  ComponentLocation: '',
  TrayNo: '',
  StockCode: '',
  TaskId: ''
})

const onEngineNoInput = () => {
  const raw = editStockForm.ProjectName || ''
  const parts = raw.split('&')
  if (parts.length === 3) {
    editStockForm.ProjectName = parts[0].trim()
    editStockForm.IntervalNo = parts[1].trim()
    editStockForm.ComponentLocation = parts[2].trim()
  }
}

const onEditStockConfirm = async () => {
  const TrayNo = editStockForm.TrayNo ? editStockForm.TrayNo : null
  const ProjectNo = editStockForm.ProjectName ? editStockForm.ProjectName : null
  const IntervalNo = editStockForm.IntervalNo ? editStockForm.IntervalNo : null
  const ComponentLocation = editStockForm.ComponentLocation ? editStockForm.ComponentLocation : null
  const StockStatus = (IntervalNo && ComponentLocation) ? true : false
  const params = {
    StockCode: editStockForm.StockCode,
    TrayNo,
    ProjectNo,
    IntervalNo,
    ComponentLocation,
    StockStatus,
    TaskId: editStockForm.TaskId
  }
  // 记录旧值
  const current = opStoreData.find(i => i.StockCode === editStockForm.StockCode) || {}
  const oldTrayNo = current.TrayNo || null
  const oldProjectNo = current.ProjectNo || null
  const oldIntervalNo = current.IntervalNo || null
  const oldComponentLocation = current.ComponentLocation || null
  const stockName = current.StockName || ''

  const res = await ExecAgvApi('updateStockInfo', params)
  if (res.Result) {
    await ExecDatabaseByParam('12', 'PTCHV_AGV_库位更新记录_增加', [
      ['库位号', editStockForm.StockCode],
      ['库位名称', stockName],
      ['项目名称', ProjectNo || ''],
      ['间隔编号', IntervalNo || ''],
      ['部件位置', ComponentLocation || ''],
      ['托盘编号', TrayNo || ''],
      ['项目名称_old', oldProjectNo || ''],
      ['间隔编号_old', oldIntervalNo || ''],
      ['部件位置_old', oldComponentLocation || ''],
      ['托盘编号_old', oldTrayNo || ''],
      ['操作人', user.value.name],
      ['type', 1],
    ])
    ElMessage.success('库位信息修改成功')
    showEditStockDialog.value = false
    await getOpStoreCode()
  } else {
    ElMessage.error(res.ErrMsg || '库位信息修改失败')
  }
}

const onEditStockCancel = () => {
  showEditStockDialog.value = false
}
</script>

<style lang="scss" scoped>
.card.modern-card {
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 4px 24px 0 rgba(0, 0, 0, 0.08);
  padding: 10px 14px;
  overflow-y: auto;
}

.storList {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.storList-item.modern-item {
  background: linear-gradient(135deg, #f8fafc 60%, #e0e7ef 100%);
  border-radius: 14px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
  padding: 20px 18px 16px 18px;
  min-width: 260px;
  max-width: 320px;
  flex: 1 1 260px;
  transition: box-shadow 0.2s, transform 0.2s;
  display: flex;
  flex-direction: column;
  gap: 12px;
  cursor: pointer;

  &:hover {
    box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.12);
    transform: translateY(-2px) scale(1.02);
  }
}

.storList-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.storList-title {
  font-size: 1.18rem;
  font-weight: 600;
  color: #222;
}

.storList-tags {
  display: flex;
  gap: 8px;
}

.storList-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.98rem;
  color: #555;

  span {
    display: flex;
    align-items: center;
    gap: 4px;

    i {
      font-size: 1.1em;
      color: #8bb4f8;
    }

    b {
      color: #222;
      font-weight: 500;
      margin-left: 2px;
    }
  }
}
</style>