-
+
+
+
-
+
@@ -388,7 +409,11 @@ import {
updatePalletDetailPosition,
getAgvStations,
callPalletToStation,
- callPalletToStationWithUpdateZuPan
+ callPalletToStationWithUpdateZuPan,
+ getPalletInfo,
+ getPalletTypeList,
+ getPalletTypeAreas,
+ updatePalletTypeAndAutoSort
} from '../../../api/automatedWarehouse/palletPacking'
export default {
@@ -399,6 +424,16 @@ export default {
palletScanned: false,
operationType: 'in', // 'in' 或 'out'
+ // 栈板类型和自动分拣
+ currentPalletFamily: '', // 当前栈板大分类(固定不可改)
+ currentPalletType: '', // 当前栈板类型
+ currentAutoSort: '', // 当前是否自动分拣 Y/N
+ palletTypeOptions: [], // 托盘类型选项列表
+ palletTypeDisabled: false, // 栈板类型下拉框是否禁用(有明细数据时禁用)
+ autoSortDisabled: false, // 自动分拣下拉框是否禁用
+ currentWcsAutoSort: '', // 当前托盘类型的wcsAutoSort值
+ currentMaxLayer: 0, // 当前托盘类型的最大层数,0=无限
+
// 筛选条件
selectedPosition: '',
selectedLayer: '',
@@ -418,9 +453,9 @@ export default {
// 运输任务模态框
transportModalVisible: false,
- transportStationOptions: [],
+ transportAreaOptions: [], // 目标区域选项(从空闲站点中提取并去重)
currentPalletStation: '',
- selectedTargetStation: '',
+ selectedTargetArea: '', // 选择的目标区域
// Call栈板模态框
callPalletModalVisible: false,
@@ -437,6 +472,11 @@ export default {
editLayerOptions: [],
editOriginalPosition: '',
editOriginalLayer: '',
+
+ // 按钮loading状态(防止重复点击)
+ editPositionLoading: false, // 修改位置按钮
+ transportTaskLoading: false, // 创建运输任务按钮
+ callPalletLoading: false, // Call栈板按钮
};
},
methods: {
@@ -458,6 +498,10 @@ export default {
if (data.code === 0) {
this.palletScanned = true;
this.positionOptions = data.positions || [];
+
+ // 获取栈板详细信息(包括palletType和autoSort)
+ this.loadPalletInfo();
+
this.refreshTable();
} else {
this.$message.error(data.msg || '栈板不存在');
@@ -468,6 +512,137 @@ export default {
});
},
+ // 加载栈板信息
+ loadPalletInfo() {
+ getPalletInfo({
+ site: this.site,
+ palletId: this.palletCode
+ }).then(({ data }) => {
+ if (data.code === 0) {
+ const palletInfo = data.row || {};
+ this.currentPalletFamily = palletInfo.palletFamily || '';
+ this.currentPalletType = palletInfo.palletType || '';
+ this.currentAutoSort = palletInfo.autoSort || 'N';
+
+ // 加载托盘类型列表(根据palletFamily过滤)
+ this.loadPalletTypeList();
+ } else {
+ this.$message.error(data.msg || '获取栈板信息失败');
+ }
+ }).catch(error => {
+ console.error('获取栈板信息失败:', error);
+ this.$message.error('获取栈板信息失败');
+ });
+ },
+
+ // 加载托盘类型列表
+ loadPalletTypeList() {
+ getPalletTypeList({
+ site: this.site,
+ palletFamily: this.currentPalletFamily,
+ active: 'Y'
+ }).then(({ data }) => {
+ if (data.code === 0) {
+ this.palletTypeOptions = data.rows || [];
+
+ // 设置当前托盘类型的wcsAutoSort值和maxLayer
+ const currentType = this.palletTypeOptions.find(t => t.palletType === this.currentPalletType);
+ if (currentType) {
+ this.currentWcsAutoSort = currentType.wcsAutoSort || 'N';
+ this.currentMaxLayer = currentType.maxLayer || 0;
+ this.updateAutoSortControl();
+
+ // 加载当前托盘类型的区域列表
+ this.loadPalletTypeAreas();
+ }
+ } else {
+ this.palletTypeOptions = [];
+ }
+ }).catch(error => {
+ console.error('获取托盘类型列表失败:', error);
+ this.palletTypeOptions = [];
+ });
+ },
+
+ // 加载托盘类型的区域列表
+ loadPalletTypeAreas() {
+ getPalletTypeAreas({
+ site: this.site,
+ palletType: this.currentPalletType
+ }).then(({ data }) => {
+ if (data.code === 0) {
+ // 从pallet_type_area获取position列表
+ const areas = data.rows || [];
+ this.positionOptions = areas.map(area => area.position);
+ } else {
+ this.positionOptions = [];
+ }
+ }).catch(error => {
+ console.error('获取托盘区域列表失败:', error);
+ this.positionOptions = [];
+ });
+ },
+
+ // 托盘类型变更事件
+ handlePalletTypeChange() {
+ // 查找选中的托盘类型
+ const selectedType = this.palletTypeOptions.find(t => t.palletType === this.currentPalletType);
+
+ if (selectedType) {
+ this.currentWcsAutoSort = selectedType.wcsAutoSort || 'N';
+ this.currentMaxLayer = selectedType.maxLayer || 0;
+
+ // 默认值:从托盘类型表取
+ this.currentAutoSort = this.currentWcsAutoSort;
+
+ // 更新自动分拣控制
+ this.updateAutoSortControl();
+
+ // 重新查询pallet_type_area,更新位置下拉框
+ this.loadPalletTypeAreas();
+
+ // 保存到数据库
+ this.savePalletTypeAndAutoSort();
+ }
+ },
+
+ // 更新自动分拣控制逻辑
+ updateAutoSortControl() {
+ if (this.currentWcsAutoSort === 'N') {
+ // 不支持自动分拣,锁定为N,禁用选择
+ this.currentAutoSort = 'N';
+ this.autoSortDisabled = true;
+ } else {
+ // 支持自动分拣,可以选择Y或N
+ this.autoSortDisabled = false;
+ }
+ },
+
+ // 是否自动分拣变更事件
+ handleAutoSortChange() {
+ // 保存到数据库
+ this.savePalletTypeAndAutoSort();
+ },
+
+ // 保存栈板类型和自动分拣标志
+ savePalletTypeAndAutoSort() {
+ updatePalletTypeAndAutoSort({
+ site: this.site,
+ palletId: this.palletCode,
+ palletType: this.currentPalletType,
+ autoSort: this.currentAutoSort
+ }).then(({ data }) => {
+ if (data.code === 0) {
+ this.$message.success('更新成功');
+ } else {
+ this.$message.error(data.msg || '更新失败');
+ }
+ }).catch(error => {
+ console.error('更新失败:', error);
+ this.$message.error('更新失败');
+ });
+ },
+
// Call栈板 - 调用空托盘
handleCallPallet() {
this.callPalletModalVisible = true;
@@ -530,12 +705,27 @@ export default {
}).then(({ data }) => {
if (data.code === 0) {
this.detailList = data.details || [];
+
+ // 如果栈板有明细数据,禁用栈板类型和自动分拣的修改
+ const hasDetails = this.detailList.length > 0;
+ this.palletTypeDisabled = hasDetails;
+
+ // 如果有明细数据,自动分拣也要禁用;否则根据wcsAutoSort判断
+ if (hasDetails) {
+ this.autoSortDisabled = true;
+ } else {
+ this.updateAutoSortControl();
+ }
} else {
this.detailList = [];
+ this.palletTypeDisabled = false;
+ this.updateAutoSortControl();
}
}).catch(error => {
console.error('获取栈板明细失败:', error);
this.detailList = [];
+ this.palletTypeDisabled = false;
+ this.updateAutoSortControl();
});
},
@@ -574,17 +764,29 @@ export default {
// 扫码模态框中位置变化
handleScanPositionChange() {
if (this.scanPosition) {
+ // maxLayer=0表示混装托盘,只能选第1层
+ if (this.currentMaxLayer === 0) {
+ this.scanLayerOptions = [1];
+ this.scanLayer = 1; // 自动选中第1层
+ this.moveFocusToScanInput();
+ return;
+ }
+
+ // maxLayer>0,根据已有层数和maxLayer计算可选层数
getLayersByPosition({
site: this.site,
palletId: this.palletCode,
position: this.scanPosition
}).then(({ data }) => {
if (data.code === 0) {
- const maxLayer = data.layers && data.layers.length > 0
+ const existingMaxLayer = data.layers && data.layers.length > 0
? Math.max(...data.layers)
: 0;
- this.scanLayerOptions = Array.from({ length: maxLayer+1 }, (_, i) => i + 1)
+ // 有maxLayer限制,取已有最大层+1和maxLayer的较小值
+ const layerCount = Math.min(existingMaxLayer + 1, this.currentMaxLayer);
+
+ this.scanLayerOptions = Array.from({ length: layerCount }, (_, i) => i + 1);
}
}).catch(error => {
console.error('获取层数失败:', error);
@@ -673,6 +875,14 @@ export default {
// 编辑位置选择变化
handleEditPositionChange() {
if (this.editPosition) {
+ // maxLayer=0表示混装托盘,只能选第1层
+ if (this.currentMaxLayer === 0) {
+ this.editLayerOptions = [1];
+ this.editLayer = 1; // 自动选中第1层
+ return;
+ }
+
+ // maxLayer>0,根据已有层数和maxLayer计算可选层数
getLayersForEdit({
site: this.site,
palletId: this.palletCode,
@@ -680,7 +890,15 @@ export default {
excludeSerialNo: this.editSerialNo
}).then(({ data }) => {
if (data.code === 0) {
- this.editLayerOptions = data.layers || [];
+ let layerOptions = data.layers || [];
+
+ // 根据maxLayer限制层数选项
+ if (this.currentMaxLayer > 0) {
+ // 过滤掉超过maxLayer的层数
+ layerOptions = layerOptions.filter(layer => layer <= this.currentMaxLayer);
+ }
+
+ this.editLayerOptions = layerOptions;
// 如果当前选择的层数不在新的选项中,清空选择
// if (!this.editLayerOptions.includes(this.editLayer)) {
// this.editLayer = '';
@@ -713,6 +931,9 @@ export default {
return;
}
+ // 设置loading状态,防止重复点击
+ this.editPositionLoading = true;
+
updatePalletDetailPosition({
site: this.site,
palletId: this.palletCode,
@@ -730,6 +951,9 @@ export default {
}).catch(error => {
console.error('位置修改失败:', error);
this.$message.error('位置修改失败');
+ }).finally(() => {
+ // 无论成功或失败,都要恢复按钮状态
+ this.editPositionLoading = false;
});
},
@@ -765,14 +989,38 @@ export default {
}
this.transportModalVisible = true;
- this.selectedTargetStation = '';
- this.transportStationOptions = [];
+ this.selectedTargetArea = '';
+ this.transportAreaOptions = [];
- // 获取所有AGV站点列表,只显示空闲站点(statusDb = 0)
+ // 获取所有AGV站点列表,只显示空闲站点(statusDb = 0)的区域
getAgvStations({}).then(({ data }) => {
if (data.code === 0) {
// 过滤出statusDb为0(空闲)的站点
- this.transportStationOptions = (data.stations || []).filter(station => station.statusDb === '0');
+ const freeStations = (data.stations || []).filter(station => station.statusDb === 0);
+
+ console.log('空闲站点数量:', freeStations.length);
+
+ // 提取station_area并去重(只提取有stationArea的站点)
+ const areaMap = new Map();
+ freeStations.forEach(station => {
+ if (station.stationArea && station.stationArea.trim() !== '') {
+ if (!areaMap.has(station.stationArea)) {
+ areaMap.set(station.stationArea, {
+ stationArea: station.stationArea,
+ areaType: station.areaType
+ });
+ }
+ }
+ });
+
+ this.transportAreaOptions = Array.from(areaMap.values());
+
+ console.log('可用目标区域数量:', this.transportAreaOptions.length);
+
+ // 如果没有可用区域,给出友好提示
+ if (this.transportAreaOptions.length === 0) {
+ this.$message.warning('当前没有可用的目标区域,所有站点可能都已被占用');
+ }
} else {
this.$message.error(data.msg || '获取站点列表失败');
}
@@ -795,22 +1043,19 @@ export default {
this.$message.error('无法获取当前栈板位置');
return;
}
- if (!this.selectedTargetStation) {
- this.$message.error('请选择目标站点');
+ if (!this.selectedTargetArea) {
+ this.$message.error('请选择目标区域');
return;
}
- // 前端验证:起始站点和目标站点不能一样
- if (this.currentPalletStation === this.selectedTargetStation) {
- this.$message.error('起始站点和目标站点不能相同');
- return;
- }
+ // 设置loading状态,防止重复点击
+ this.transportTaskLoading = true;
- // 调用包含组盘处理的接口
+ // 调用包含组盘处理的接口(后端会根据区域自动查找空闲站点)
callPalletToStationWithUpdateZuPan({
site: this.site,
startStation: this.currentPalletStation,
- targetStation: this.selectedTargetStation
+ targetArea: this.selectedTargetArea
}).then(({ data }) => {
if (data.code === 0) {
this.$message.success('栈板运输任务创建成功');
@@ -823,6 +1068,9 @@ export default {
}).catch(error => {
console.error('创建运输任务失败:', error);
this.$message.error('创建运输任务失败');
+ }).finally(() => {
+ // 无论成功或失败,都要恢复按钮状态
+ this.transportTaskLoading = false;
});
},
@@ -830,8 +1078,8 @@ export default {
closeTransportModal() {
this.transportModalVisible = false;
this.currentPalletStation = '';
- this.selectedTargetStation = '';
- this.transportStationOptions = [];
+ this.selectedTargetArea = '';
+ this.transportAreaOptions = [];
},
// 确认Call栈板
@@ -851,6 +1099,9 @@ export default {
return;
}
+ // 设置loading状态,防止重复点击
+ this.callPalletLoading = true;
+
callPalletToStation({
site: this.site,
startStation: this.selectedCallStartStation,
@@ -865,6 +1116,9 @@ export default {
}).catch(error => {
console.error('调用空托盘失败:', error);
this.$message.error('异常:'+error);
+ }).finally(() => {
+ // 无论成功或失败,都要恢复按钮状态
+ this.callPalletLoading = false;
});
},
@@ -930,13 +1184,9 @@ export default {
}
.col-serial {
- flex: 2;
- text-align: center;
-}
-
-.col-part {
- flex: 2;
+ flex: 4;
text-align: center;
+ word-break: break-all;
}
/* 空数据提示 */
@@ -1006,4 +1256,12 @@ export default {
color: #999;
width: 100%;
}
+
+/* 按钮禁用状态样式 */
+.action-btn:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ background-color: #ccc !important;
+ border-color: #ccc !important;
+}