chore: 初始化平芝126KV总装线 PDA
This commit is contained in:
797
src/views/CallMaterials/index.vue
Normal file
797
src/views/CallMaterials/index.vue
Normal file
@@ -0,0 +1,797 @@
|
||||
<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.ProjectNo }}</span>
|
||||
<span><b>间隔编号:</b>{{ item.IntervalNo }}</span>
|
||||
<span><b>部件位置:</b>{{ item.ComponentLocation }}</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="showInputDialog" title="物料验证" width="320px" :close-on-click-modal="false"
|
||||
@close="onInputCancel">
|
||||
<el-form @submit.prevent>
|
||||
<el-form-item label="产品图号">
|
||||
<el-input v-model="MaterialData.SortNo" disabled clearable autofocus @keyup.enter="onInputConfirm" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品编号">
|
||||
<el-input v-model="inputValue" placeholder="请扫描物料编号" clearable autofocus @input="onInputChange"
|
||||
@keyup.enter="onInputConfirm" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="onInputCancel">取消</el-button>
|
||||
<el-button type="primary" @click="onInputConfirm">校验</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<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>
|
||||
</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.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.StockStatus === true && 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.callMaterial)
|
||||
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 === '物料验证') {
|
||||
inputValue.value = ''
|
||||
showInputDialog.value = true
|
||||
// 将当前物料信息赋值到验证数据
|
||||
Object.assign(MaterialData, currentItem.value)
|
||||
return
|
||||
}
|
||||
|
||||
if (action.name === '退料') {
|
||||
// 获取退料目标库区
|
||||
const routes = await getRoutePartitions(currentItem.value.StockCode)
|
||||
if (!routes || !routes.returnMaterial) {
|
||||
ElMessage.warning('未配置退料路线,请联系管理员')
|
||||
return
|
||||
}
|
||||
|
||||
// 记录目标库区
|
||||
targetPartition.returnMaterial = routes.returnMaterial
|
||||
|
||||
// 根据目标库区获取库位列表
|
||||
const stockRes = await ExecAgvApi('getStockList', { PartitionCode: targetPartition.returnMaterial })
|
||||
if (!stockRes.Result) {
|
||||
ElMessage.error(stockRes.ErrMsg || '获取库位失败')
|
||||
return
|
||||
}
|
||||
|
||||
// 退料流程:只显示空库位(无托盘且状态为空)
|
||||
stockList.value = stockRes.Data
|
||||
.filter(i => !i.PalletCode && i.StockStatus === false)
|
||||
.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.returnMaterial)
|
||||
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 partitionName = await getPartitionName(targetPartition.callMaterial)
|
||||
|
||||
// 叫料流程确认
|
||||
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.ProjectNo || ''],
|
||||
['取料间隔编号', stock.IntervalNo || ''],
|
||||
['取料部件位置', stock.ComponentLocation || ''],
|
||||
['取料托盘编号', stock.TrayNo || ''],
|
||||
['送料库位', currentItem.value.StockCode],
|
||||
['送料库位名称', currentItem.value.StockName],
|
||||
['操作人', user.value.name],
|
||||
['type', 1],
|
||||
])
|
||||
ElMessage.success('叫料任务创建成功')
|
||||
getOpStoreCode()
|
||||
} else {
|
||||
ElMessage.error(res.ErrMsg || '叫料任务创建失败')
|
||||
}
|
||||
isCallMaterialFlow.value = false
|
||||
})
|
||||
} else if (isReturnMaterialFlow.value) {
|
||||
// 获取目标库区名称
|
||||
const partitionName = await getPartitionName(targetPartition.returnMaterial)
|
||||
|
||||
// 退料流程确认
|
||||
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', 2],
|
||||
])
|
||||
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 === '退料') {
|
||||
// 获取退空托盘目标库区
|
||||
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.PalletCode || i.PalletCode === '')
|
||||
.map(i => ({ name: i.StockName, code: i.StockCode, ...i }))
|
||||
|
||||
if (stockList.value.length === 0) {
|
||||
ElMessage.warning('目标库区没有可用库位')
|
||||
return
|
||||
}
|
||||
|
||||
// 设置退空托盘流程标识和数据
|
||||
isReturnPalletFlow.value = true
|
||||
returnPalletStock.value = currentItem.value
|
||||
stockDialogTitle.value = await getPartitionName(targetPartition.returnPallet)
|
||||
showStockDialog.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 === '') && i.StockName !== '无库位')
|
||||
.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)
|
||||
</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>
|
||||
Reference in New Issue
Block a user