1 changed files with 964 additions and 0 deletions
@ -0,0 +1,964 @@ |
|||
<template> |
|||
<div> |
|||
<div class="pda-container"> |
|||
<!-- 头部栏 --> |
|||
<div class="header-bar"> |
|||
<div class="header-left" @click="handleBack"> |
|||
<i class="el-icon-arrow-left"></i> |
|||
<span>打托</span> |
|||
</div> |
|||
<div class="header-right" @click="$router.push({ path: '/' })"> |
|||
首页 |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="main-content form-section"> |
|||
<!-- 第一行:栈板扫描 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">栈板编码</label> |
|||
<div style="display: flex; gap: 8px;"> |
|||
<el-input |
|||
v-model="palletCode" |
|||
placeholder="请扫描栈板编码" |
|||
class="form-input" |
|||
style="flex: 0.75;" |
|||
clearable |
|||
@keyup.enter.native="handlePalletScan" |
|||
ref="palletInput" |
|||
/> |
|||
<button |
|||
class="action-btn secondary" |
|||
style="flex: 0.25; margin: 0;" |
|||
@click="handleCallPallet" |
|||
> |
|||
Call栈板 |
|||
</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 第二行:筛选条件 (扫描栈板后显示) --> |
|||
<div v-if="palletScanned" class="input-group"> |
|||
<div style="display: flex; gap: 8px; align-items: end;"> |
|||
<div style="flex: 1;"> |
|||
<label class="input-label">位置</label> |
|||
<el-select |
|||
v-model="selectedPosition" |
|||
placeholder="请选择位置" |
|||
style="width: 100%;" |
|||
@change="handlePositionChange" |
|||
> |
|||
<el-option label="ALL" value=""></el-option> |
|||
<el-option |
|||
v-for="position in positionOptions" |
|||
:key="position" |
|||
:label="position" |
|||
:value="position" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
<div style="flex: 1;"> |
|||
<label class="input-label">层数</label> |
|||
<el-select |
|||
v-model="selectedLayer" |
|||
placeholder="请选择层数" |
|||
style="width: 100%;" |
|||
> |
|||
<el-option label="ALL" value=""></el-option> |
|||
<el-option |
|||
v-for="layer in layerOptions" |
|||
:key="layer" |
|||
:label="`第${layer}层`" |
|||
:value="layer" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
<button |
|||
class="action-btn secondary" |
|||
style="margin: 0; white-space: nowrap;" |
|||
@click="refreshTable" |
|||
> |
|||
刷新 |
|||
</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 第三行:扫进/扫出选择 (扫描栈板后显示) --> |
|||
<div v-if="palletScanned" class="input-group"> |
|||
<div style="display: flex; gap: 8px; align-items: center; flex-wrap: nowrap;"> |
|||
<div style="flex: 1; min-width: 0;"> |
|||
<el-radio-group v-model="operationType" style="display: flex; flex-wrap: nowrap;"> |
|||
<el-radio label="in" style="margin-right: 0px; white-space: nowrap;">扫进</el-radio> |
|||
<el-radio label="out" style="white-space: nowrap;">扫出</el-radio> |
|||
</el-radio-group> |
|||
</div> |
|||
<button |
|||
class="action-btn secondary" |
|||
style="margin: 0; white-space: nowrap; flex-shrink: 0;" |
|||
@click="showScanModal" |
|||
> |
|||
扫描二维码 |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 栈板明细表格 (扫描栈板后显示) --> |
|||
<div v-if="palletScanned" class="rma-list"> |
|||
<div class="list-title-row"> |
|||
<div class="list-title">栈板明细</div> |
|||
<button class="action-btn secondary" style="margin-left: 10px;" @click="handleTransportOrder">运输指令</button> |
|||
</div> |
|||
<div class="detail-table"> |
|||
<div class="table-header"> |
|||
<div class="col-position">位置</div> |
|||
<div class="col-layer">层数</div> |
|||
<div class="col-serial">标签号</div> |
|||
<div class="col-part">物料编码</div> |
|||
</div> |
|||
<div |
|||
v-for="(detail, index) in detailList" |
|||
:key="index" |
|||
class="table-row" |
|||
@click="handleRowDblClick(detail, index)" |
|||
> |
|||
<div class="col-position">{{ detail.position }}</div> |
|||
<div class="col-layer">{{ detail.layer }}</div> |
|||
<div class="col-serial">{{ detail.serialNo }}</div> |
|||
<div class="col-part">{{ detail.partNo }}</div> |
|||
</div> |
|||
<!-- 暂无数据提示 --> |
|||
<div v-if="detailList.length === 0" class="table-row empty-row"> |
|||
<div class="empty-hint">暂无栈板明细数据</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 扫码模态框 --> |
|||
<el-dialog |
|||
title="扫描标签" |
|||
:visible.sync="scanModalVisible" |
|||
width="90%" |
|||
:close-on-click-modal="false" |
|||
:show-close="false" |
|||
:modal="true" |
|||
:modal-append-to-body="true" |
|||
:append-to-body="true" |
|||
> |
|||
<div class="scan-modal-content"> |
|||
<!-- 扫进时显示位置和层数选择 --> |
|||
<div v-if="operationType === 'in'" class="modal-form"> |
|||
<div class="input-group"> |
|||
<label class="input-label">位置</label> |
|||
<el-select |
|||
v-model="scanPosition" |
|||
placeholder="请选择位置" |
|||
style="width: 100%;" |
|||
@change="handleScanPositionChange" |
|||
> |
|||
<el-option |
|||
v-for="position in positionOptions" |
|||
:key="position" |
|||
:label="position" |
|||
:value="position" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
<div class="input-group"> |
|||
<label class="input-label">层数</label> |
|||
<el-select |
|||
v-model="scanLayer" |
|||
placeholder="请选择层数" |
|||
style="width: 100%;" |
|||
> |
|||
<el-option |
|||
v-for="layer in scanLayerOptions" |
|||
:key="layer" |
|||
:label="`第${layer}层`" |
|||
:value="layer" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 标签扫描 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">标签二维码</label> |
|||
<el-input |
|||
v-model="scanCode" |
|||
placeholder="请扫描标签二维码" |
|||
class="form-input" |
|||
clearable |
|||
@keyup.enter.native="handleLabelScan" |
|||
ref="scanInput" |
|||
/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div slot="footer" class="dialog-footer"> |
|||
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeScanModal">取消</button> |
|||
</div> |
|||
</el-dialog> |
|||
|
|||
<!-- 修改位置模态框 --> |
|||
<el-dialog |
|||
title="修改标签位置" |
|||
:visible.sync="editPositionModalVisible" |
|||
width="90%" |
|||
:close-on-click-modal="false" |
|||
:show-close="false" |
|||
:modal="true" |
|||
:modal-append-to-body="true" |
|||
:append-to-body="true" |
|||
> |
|||
<div class="edit-modal-content"> |
|||
<!-- 标签号(只读) --> |
|||
<div class="input-group"> |
|||
<label class="input-label">标签号</label> |
|||
<el-input |
|||
v-model="editSerialNo" |
|||
placeholder="标签号" |
|||
class="form-input" |
|||
readonly |
|||
/> |
|||
</div> |
|||
|
|||
<!-- 位置选择 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">位置</label> |
|||
<el-select |
|||
v-model="editPosition" |
|||
placeholder="请选择位置" |
|||
style="width: 100%;" |
|||
@change="handleEditPositionChange" |
|||
> |
|||
<el-option |
|||
v-for="position in positionOptions" |
|||
:key="position" |
|||
:label="position" |
|||
:value="position" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
|
|||
<!-- 层数选择 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">层数</label> |
|||
<el-select |
|||
v-model="editLayer" |
|||
placeholder="请选择层数" |
|||
style="width: 100%;" |
|||
> |
|||
<el-option |
|||
v-for="layer in editLayerOptions" |
|||
:key="layer" |
|||
:label="`第${layer}层`" |
|||
:value="layer" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
</div> |
|||
|
|||
<div slot="footer" class="dialog-footer"> |
|||
<button class="action-btn primary" @click="confirmEditPosition">确定</button> |
|||
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeEditPositionModal">取消</button> |
|||
</div> |
|||
</el-dialog> |
|||
|
|||
<!-- 运输任务模态框 --> |
|||
<el-dialog |
|||
title="创建运输任务" |
|||
:visible.sync="transportModalVisible" |
|||
width="90%" |
|||
:close-on-click-modal="false" |
|||
:show-close="false" |
|||
:modal="true" |
|||
:modal-append-to-body="true" |
|||
:append-to-body="true" |
|||
> |
|||
<div class="transport-modal-content"> |
|||
<!-- 栈板号(只读) --> |
|||
<div class="input-group"> |
|||
<label class="input-label">栈板号</label> |
|||
<el-input |
|||
v-model="palletCode" |
|||
placeholder="栈板号" |
|||
class="form-input" |
|||
readonly |
|||
/> |
|||
</div> |
|||
|
|||
<!-- 起点站点选择 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">起点站点</label> |
|||
<el-select |
|||
v-model="selectedStartStation" |
|||
placeholder="请选择起点站点" |
|||
style="width: 100%;" |
|||
@change="handleStartStationChange" |
|||
> |
|||
<el-option |
|||
v-for="station in startStationOptions" |
|||
:key="station.stationCode" |
|||
:label="`${station.stationCode} - ${station.stationName}`" |
|||
:value="station.stationCode" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
|
|||
<!-- 目标站点选择 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">目标站点</label> |
|||
<el-select |
|||
v-model="selectedTargetStation" |
|||
placeholder="请先选择起点站点" |
|||
style="width: 100%;" |
|||
:disabled="!selectedStartStation" |
|||
> |
|||
<el-option |
|||
v-for="target in targetStationOptions" |
|||
:key="target.stationCode" |
|||
:label="`${target.stationCode} - ${target.stationName}`" |
|||
:value="target.stationCode" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
</div> |
|||
|
|||
<div slot="footer" class="dialog-footer"> |
|||
<button class="action-btn primary" @click="confirmTransportTask">确定</button> |
|||
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeTransportModal">取消</button> |
|||
</div> |
|||
</el-dialog> |
|||
|
|||
<!-- Call栈板模态框 --> |
|||
<el-dialog |
|||
title="调用空托盘" |
|||
:visible.sync="callPalletModalVisible" |
|||
width="90%" |
|||
:close-on-click-modal="false" |
|||
:show-close="false" |
|||
:modal="true" |
|||
:modal-append-to-body="true" |
|||
:append-to-body="true" |
|||
> |
|||
<div class="call-modal-content"> |
|||
<!-- 目标站点选择 --> |
|||
<div class="input-group"> |
|||
<label class="input-label">目标站点</label> |
|||
<el-select |
|||
v-model="selectedCallStation" |
|||
placeholder="请选择目标站点" |
|||
style="width: 100%;" |
|||
> |
|||
<el-option |
|||
v-for="station in callStationOptions" |
|||
:key="station.stationCode" |
|||
:label="`${station.stationCode} - ${station.stationName}`" |
|||
:value="station.stationCode" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
</div> |
|||
|
|||
<div slot="footer" class="dialog-footer"> |
|||
<button class="action-btn primary" @click="confirmCallPallet">确定</button> |
|||
<button class="action-btn secondary" style="margin-left: 10px;" @click="closeCallPalletModal">取消</button> |
|||
</div> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
checkPalletExists, |
|||
getPalletPositions, |
|||
getPalletDetails, |
|||
getLayersByPosition, |
|||
validateLabel, |
|||
savePalletDetail, |
|||
deletePalletDetail, |
|||
getLayersForEdit, |
|||
updatePalletDetailPosition, |
|||
getAgvStations, |
|||
getTargetStations, |
|||
createPalletTransportTask, |
|||
callPalletToStation |
|||
} from '../../../api/automatedWarehouse/palletPacking' |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
site: localStorage.getItem('site'), |
|||
palletCode: '', |
|||
palletScanned: false, |
|||
operationType: 'in', // 'in' 或 'out' |
|||
|
|||
// 筛选条件 |
|||
selectedPosition: '', |
|||
selectedLayer: '', |
|||
positionOptions: [], |
|||
layerOptions: [], |
|||
|
|||
// 扫码模态框 |
|||
scanModalVisible: false, |
|||
scanCode: '', |
|||
scanPosition: '', |
|||
scanLayer: '', |
|||
scanLayerOptions: [], |
|||
needRefreshOnClose: false, // 标记是否需要在关闭模态框时刷新 |
|||
|
|||
// 栈板明细 |
|||
detailList: [], |
|||
|
|||
// 运输任务模态框 |
|||
transportModalVisible: false, |
|||
startStationOptions: [], |
|||
targetStationOptions: [], |
|||
selectedStartStation: '', |
|||
selectedTargetStation: '', |
|||
|
|||
// Call栈板模态框 |
|||
callPalletModalVisible: false, |
|||
callStationOptions: [], |
|||
selectedCallStation: '', |
|||
|
|||
// 修改位置模态框 |
|||
editPositionModalVisible: false, |
|||
editSerialNo: '', |
|||
editPosition: '', |
|||
editLayer: '', |
|||
editLayerOptions: [], |
|||
editOriginalPosition: '', |
|||
editOriginalLayer: '', |
|||
}; |
|||
}, |
|||
methods: { |
|||
handleBack() { |
|||
this.$router.back(); |
|||
}, |
|||
|
|||
// 扫描栈板 |
|||
handlePalletScan() { |
|||
if (!this.palletCode.trim()) { |
|||
this.$message.error('请输入栈板编码'); |
|||
return; |
|||
} |
|||
|
|||
checkPalletExists({ |
|||
site: this.site, |
|||
palletId: this.palletCode |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.palletScanned = true; |
|||
this.positionOptions = data.positions || []; |
|||
this.$message.success('栈板验证成功'); |
|||
this.refreshTable(); |
|||
} else { |
|||
this.$message.error(data.msg || '栈板不存在'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('验证栈板失败:', error); |
|||
this.$message.error('验证栈板失败'); |
|||
}); |
|||
}, |
|||
|
|||
// Call栈板 - 调用空托盘 |
|||
handleCallPallet() { |
|||
this.callPalletModalVisible = true; |
|||
this.selectedCallStation = ''; |
|||
|
|||
// 获取AGV站点列表 |
|||
getAgvStations({}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.callStationOptions = data.stations || []; |
|||
} else { |
|||
this.$message.error(data.msg || '获取站点列表失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取站点列表失败:', error); |
|||
this.$message.error('获取站点列表失败'); |
|||
}); |
|||
}, |
|||
|
|||
// 位置选择变化 |
|||
handlePositionChange() { |
|||
if (this.selectedPosition) { |
|||
getLayersByPosition({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
position: this.selectedPosition |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.layerOptions = data.layers || []; |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取层数失败:', error); |
|||
}); |
|||
} else { |
|||
this.layerOptions = []; |
|||
} |
|||
this.selectedLayer = ''; |
|||
}, |
|||
|
|||
// 刷新表格 |
|||
refreshTable() { |
|||
getPalletDetails({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
position: this.selectedPosition, |
|||
layer: this.selectedLayer |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.detailList = data.details || []; |
|||
} else { |
|||
this.detailList = []; |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取栈板明细失败:', error); |
|||
this.detailList = []; |
|||
}); |
|||
}, |
|||
|
|||
// 显示扫码模态框 |
|||
showScanModal() { |
|||
this.scanModalVisible = true; |
|||
this.scanCode = ''; |
|||
this.scanPosition = ''; |
|||
this.scanLayer = ''; |
|||
this.scanLayerOptions = []; |
|||
this.needRefreshOnClose = false; // 重置刷新标记 |
|||
|
|||
this.$nextTick(() => { |
|||
if (this.$refs.scanInput) { |
|||
this.$refs.scanInput.focus(); |
|||
} |
|||
}); |
|||
}, |
|||
// 关闭扫码模态框 |
|||
closeScanModal() { |
|||
this.scanModalVisible = false; |
|||
// 如果有操作成功,则在关闭时刷新外面的列表 |
|||
if (this.needRefreshOnClose) { |
|||
this.refreshTable(); |
|||
this.needRefreshOnClose = false; |
|||
} |
|||
}, |
|||
|
|||
// 扫码模态框中位置变化 |
|||
handleScanPositionChange() { |
|||
if (this.scanPosition) { |
|||
getLayersByPosition({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
position: this.scanPosition |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
const maxLayer = data.layers && data.layers.length > 0 |
|||
? Math.max(...data.layers) |
|||
: 0; |
|||
|
|||
this.scanLayerOptions = Array.from({ length: maxLayer+1 }, (_, i) => i + 1) |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取层数失败:', error); |
|||
this.scanLayerOptions = [1]; |
|||
}); |
|||
} else { |
|||
this.scanLayerOptions = []; |
|||
} |
|||
this.scanLayer = ''; |
|||
}, |
|||
|
|||
// 处理标签扫描 |
|||
handleLabelScan() { |
|||
if (!this.scanCode.trim()) { |
|||
this.$message.error('请输入标签编码'); |
|||
return; |
|||
} |
|||
|
|||
if (this.operationType === 'in') { |
|||
// 扫进操作 |
|||
if (!this.scanPosition) { |
|||
this.$message.error('请选择位置'); |
|||
return; |
|||
} |
|||
if (!this.scanLayer) { |
|||
this.$message.error('请选择层数'); |
|||
return; |
|||
} |
|||
|
|||
savePalletDetail({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
position: this.scanPosition, |
|||
layer: this.scanLayer, |
|||
serialNo: this.scanCode |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.$message.success('扫进成功'); |
|||
this.needRefreshOnClose = true; // 标记需要在关闭时刷新 |
|||
this.scanCode = ''; // 清空扫描码,准备下次扫描 |
|||
this.$refs.scanInput.focus(); |
|||
} else { |
|||
this.$message.error(data.msg || '扫进失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('扫进失败:', error); |
|||
this.$message.error('扫进失败'); |
|||
}); |
|||
} else { |
|||
// 扫出操作 |
|||
deletePalletDetail({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
serialNo: this.scanCode |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.$message.success('扫出成功'); |
|||
this.needRefreshOnClose = true; // 标记需要在关闭时刷新 |
|||
this.scanCode = ''; // 清空扫描码,准备下次扫描 |
|||
this.$refs.scanInput.focus(); |
|||
} else { |
|||
this.$message.error(data.msg || '扫出失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('扫出失败:', error); |
|||
this.$message.error('扫出失败'); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 双击行事件 - 修改位置 |
|||
handleRowDblClick(detail, index) { |
|||
|
|||
this.editSerialNo = detail.serialNo; |
|||
this.editPosition = detail.position; |
|||
this.editLayer = detail.layer; |
|||
this.editOriginalPosition = detail.position; |
|||
this.editOriginalLayer = detail.layer; |
|||
|
|||
// 获取当前位置的层数选项(排除自己) |
|||
this.handleEditPositionChange(); |
|||
|
|||
this.editPositionModalVisible = true; |
|||
}, |
|||
|
|||
// 编辑位置选择变化 |
|||
handleEditPositionChange() { |
|||
if (this.editPosition) { |
|||
getLayersForEdit({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
position: this.editPosition, |
|||
excludeSerialNo: this.editSerialNo |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.editLayerOptions = data.layers || []; |
|||
// 如果当前选择的层数不在新的选项中,清空选择 |
|||
// if (!this.editLayerOptions.includes(this.editLayer)) { |
|||
// this.editLayer = ''; |
|||
// } |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取层数失败:', error); |
|||
this.editLayerOptions = []; |
|||
}); |
|||
} else { |
|||
this.editLayerOptions = []; |
|||
this.editLayer = ''; |
|||
} |
|||
}, |
|||
|
|||
// 确定修改位置 |
|||
confirmEditPosition() { |
|||
if (!this.editPosition) { |
|||
this.$message.error('请选择位置'); |
|||
return; |
|||
} |
|||
if (!this.editLayer) { |
|||
this.$message.error('请选择层数'); |
|||
return; |
|||
} |
|||
|
|||
// 检查是否有变化 |
|||
if (this.editPosition === this.editOriginalPosition && this.editLayer === this.editOriginalLayer) { |
|||
this.$message.warning('位置没有变化'); |
|||
return; |
|||
} |
|||
|
|||
updatePalletDetailPosition({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
serialNo: this.editSerialNo, |
|||
newPosition: this.editPosition, |
|||
newLayer: this.editLayer |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.$message.success('位置修改成功'); |
|||
this.closeEditPositionModal(); |
|||
this.refreshTable(); |
|||
} else { |
|||
this.$message.error(data.msg || '位置修改失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('位置修改失败:', error); |
|||
this.$message.error('位置修改失败'); |
|||
}); |
|||
}, |
|||
|
|||
// 关闭修改位置模态框 |
|||
closeEditPositionModal() { |
|||
this.editPositionModalVisible = false; |
|||
this.editSerialNo = ''; |
|||
this.editPosition = ''; |
|||
this.editLayer = ''; |
|||
this.editLayerOptions = []; |
|||
this.editOriginalPosition = ''; |
|||
this.editOriginalLayer = ''; |
|||
}, |
|||
|
|||
// 运输指令按钮点击事件 |
|||
handleTransportOrder() { |
|||
if (!this.palletCode) { |
|||
this.$message.error('请先扫描栈板'); |
|||
return; |
|||
} |
|||
|
|||
this.transportModalVisible = true; |
|||
this.selectedStartStation = ''; |
|||
this.selectedTargetStation = ''; |
|||
this.targetStationOptions = []; |
|||
|
|||
// 获取AGV站点列表 |
|||
getAgvStations({}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.startStationOptions = data.stations || []; |
|||
} else { |
|||
this.$message.error(data.msg || '获取站点列表失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取站点列表失败:', error); |
|||
this.$message.error('获取站点列表失败'); |
|||
}); |
|||
}, |
|||
|
|||
// 起点站点选择变化 |
|||
handleStartStationChange() { |
|||
this.selectedTargetStation = ''; |
|||
this.targetStationOptions = []; |
|||
|
|||
if (this.selectedStartStation) { |
|||
getTargetStations({ |
|||
startStation: this.selectedStartStation |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.targetStationOptions = data.targets || []; |
|||
} else { |
|||
this.$message.error(data.msg || '获取目标站点失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('获取目标站点失败:', error); |
|||
this.$message.error('获取目标站点失败'); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 确认创建运输任务 |
|||
confirmTransportTask() { |
|||
if (!this.selectedStartStation) { |
|||
this.$message.error('请选择起点站点'); |
|||
return; |
|||
} |
|||
if (!this.selectedTargetStation) { |
|||
this.$message.error('请选择目标站点'); |
|||
return; |
|||
} |
|||
|
|||
createPalletTransportTask({ |
|||
site: this.site, |
|||
palletId: this.palletCode, |
|||
startStation: this.selectedStartStation, |
|||
endStation: this.selectedTargetStation |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.$message.success('运输任务创建成功'); |
|||
this.closeTransportModal(); |
|||
} else { |
|||
this.$message.error(data.msg || '创建运输任务失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('创建运输任务失败:', error); |
|||
this.$message.error('创建运输任务失败'); |
|||
}); |
|||
}, |
|||
|
|||
// 关闭运输任务模态框 |
|||
closeTransportModal() { |
|||
this.transportModalVisible = false; |
|||
this.selectedStartStation = ''; |
|||
this.selectedTargetStation = ''; |
|||
this.startStationOptions = []; |
|||
this.targetStationOptions = []; |
|||
}, |
|||
|
|||
// 确认Call栈板 |
|||
confirmCallPallet() { |
|||
if (!this.selectedCallStation) { |
|||
this.$message.error('请选择站点'); |
|||
return; |
|||
} |
|||
|
|||
callPalletToStation({ |
|||
site: this.site, |
|||
station: this.selectedCallStation |
|||
}).then(({ data }) => { |
|||
if (data.code === 0) { |
|||
this.$message.success('空托盘调用任务创建成功'); |
|||
this.closeCallPalletModal(); |
|||
} else { |
|||
this.$message.error(data.msg || '调用空托盘失败'); |
|||
} |
|||
}).catch(error => { |
|||
console.error('调用空托盘失败:', error); |
|||
this.$message.error('调用空托盘失败'); |
|||
}); |
|||
}, |
|||
|
|||
// 关闭Call栈板模态框 |
|||
closeCallPalletModal() { |
|||
this.callPalletModalVisible = false; |
|||
this.selectedCallStation = ''; |
|||
this.callStationOptions = []; |
|||
}, |
|||
|
|||
}, |
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
if (this.$refs.palletInput) { |
|||
this.$refs.palletInput.focus(); |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 表格样式 */ |
|||
.detail-table { |
|||
background: white; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
border: 1px solid #e0e0e0; |
|||
} |
|||
|
|||
.table-header, |
|||
.table-row { |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 8px; |
|||
border-bottom: 1px solid #e0e0e0; |
|||
} |
|||
|
|||
.table-header { |
|||
background: #f5f5f5; |
|||
font-weight: bold; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.table-row { |
|||
font-size: 13px; |
|||
} |
|||
|
|||
.table-row:last-child { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.col-position { |
|||
flex: 1; |
|||
text-align: center; |
|||
} |
|||
|
|||
.col-layer { |
|||
flex: 1; |
|||
text-align: center; |
|||
} |
|||
|
|||
.col-serial { |
|||
flex: 2; |
|||
text-align: center; |
|||
} |
|||
|
|||
.col-part { |
|||
flex: 2; |
|||
text-align: center; |
|||
} |
|||
|
|||
/* 空数据提示 */ |
|||
.empty-hint { |
|||
text-align: center; |
|||
color: #999; |
|||
padding: 20px; |
|||
background: white; |
|||
border-radius: 6px; |
|||
margin-top: 16px; |
|||
} |
|||
|
|||
/* 模态框样式 */ |
|||
.scan-modal-content { |
|||
padding: 10px 0; |
|||
} |
|||
|
|||
.modal-form { |
|||
margin-bottom: 16px; |
|||
} |
|||
|
|||
.dialog-footer { |
|||
text-align: center; |
|||
} |
|||
|
|||
/* 修复模态框层级问题 */ |
|||
::v-deep .el-dialog__wrapper { |
|||
z-index: 2000 !important; |
|||
} |
|||
|
|||
::v-deep .el-overlay { |
|||
z-index: 2000 !important; |
|||
} |
|||
|
|||
/* 修复单选框样式 */ |
|||
::v-deep .el-radio { |
|||
margin-right: 8px !important; |
|||
} |
|||
|
|||
::v-deep .el-radio__label { |
|||
font-size: 14px; |
|||
} |
|||
|
|||
/* 标题行样式 */ |
|||
.list-title-row { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
margin-bottom: 8px; |
|||
} |
|||
|
|||
.list-title-row .list-title { |
|||
margin: 0; |
|||
flex: 1; |
|||
} |
|||
|
|||
/* 空数据行样式 */ |
|||
.empty-row { |
|||
justify-content: center; |
|||
align-items: center; |
|||
padding: 20px; |
|||
border-bottom: none; |
|||
} |
|||
|
|||
.empty-row .empty-hint { |
|||
text-align: center; |
|||
color: #999; |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue