|
|
|
@ -130,16 +130,36 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="list-body"> |
|
|
|
<!-- 左滑删除容器 --> |
|
|
|
<div |
|
|
|
v-for="(item, index) in materialList" |
|
|
|
:key="item.id" |
|
|
|
class="list-item" |
|
|
|
class="swipe-item-wrapper" |
|
|
|
> |
|
|
|
<div class="col-no">{{ materialList.length - index }}</div> |
|
|
|
<div class="col-label">{{ item.labelCode }}</div> |
|
|
|
<div class="col-part">{{ item.materialCode }}</div> |
|
|
|
<div class="col-batch">{{ item.batchNo || '-' }}</div> |
|
|
|
<div class="col-qty">{{ item.actualQty }}</div> |
|
|
|
<!-- 可滑动的内容区域 --> |
|
|
|
<div |
|
|
|
class="swipe-content" |
|
|
|
:style="{ |
|
|
|
transform: item.swipeOffset ? `translateX(${item.swipeOffset}px)` : 'translateX(0)', |
|
|
|
transition: item.isAnimating ? 'transform 0.3s ease' : 'none' |
|
|
|
}" |
|
|
|
@touchstart="handleTouchStart($event, item, index)" |
|
|
|
@touchmove="handleTouchMove($event, item)" |
|
|
|
@touchend="handleTouchEnd($event, item)" |
|
|
|
> |
|
|
|
<div class="list-item"> |
|
|
|
<div class="col-no">{{ materialList.length - index }}</div> |
|
|
|
<div class="col-label">{{ item.labelCode }}</div> |
|
|
|
<div class="col-part">{{ item.materialCode }}</div> |
|
|
|
<div class="col-batch">{{ item.batchNo || '-' }}</div> |
|
|
|
<div class="col-qty">{{ item.actualQty }}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 删除按钮(隐藏在右侧) --> |
|
|
|
<div class="delete-action" @click="handleDeleteItem(item, index)"> |
|
|
|
<i class="el-icon-delete"></i> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 空状态 --> |
|
|
|
@ -263,7 +283,11 @@ export default { |
|
|
|
showMaterialDialog: false, |
|
|
|
materialListLoading: false, |
|
|
|
showLocationDialog: false, |
|
|
|
locationCode: '' |
|
|
|
locationCode: '', |
|
|
|
// 左滑删除相关 |
|
|
|
touchStartX: 0, |
|
|
|
touchStartY: 0, |
|
|
|
deleteButtonWidth: 80 // 删除按钮宽度 |
|
|
|
}; |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
@ -271,6 +295,109 @@ export default { |
|
|
|
return date ? moment(date).format('YYYY-MM-DD') : ''; |
|
|
|
}, |
|
|
|
|
|
|
|
// ==================== 左滑删除功能 ==================== |
|
|
|
|
|
|
|
// 触摸开始 |
|
|
|
handleTouchStart(event, item, index) { |
|
|
|
this.touchStartX = event.touches[0].clientX; |
|
|
|
this.touchStartY = event.touches[0].clientY; |
|
|
|
|
|
|
|
// 关闭其他已打开的项 |
|
|
|
this.materialList.forEach((material, idx) => { |
|
|
|
if (idx !== index && material.swipeOffset) { |
|
|
|
this.$set(material, 'isAnimating', true); |
|
|
|
this.$set(material, 'swipeOffset', 0); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
this.$set(item, 'isAnimating', false); |
|
|
|
}, |
|
|
|
|
|
|
|
// 触摸移动 |
|
|
|
handleTouchMove(event, item) { |
|
|
|
const touchCurrentX = event.touches[0].clientX; |
|
|
|
const touchCurrentY = event.touches[0].clientY; |
|
|
|
|
|
|
|
const deltaX = touchCurrentX - this.touchStartX; |
|
|
|
const deltaY = touchCurrentY - this.touchStartY; |
|
|
|
|
|
|
|
// 如果垂直滑动距离大于水平滑动,则认为是滚动操作,不处理左滑 |
|
|
|
if (Math.abs(deltaY) > Math.abs(deltaX)) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 阻止默认的滚动行为 |
|
|
|
if (Math.abs(deltaX) > 10) { |
|
|
|
event.preventDefault(); |
|
|
|
} |
|
|
|
|
|
|
|
// 只允许向左滑动 |
|
|
|
if (deltaX < 0) { |
|
|
|
const offset = Math.max(deltaX, -this.deleteButtonWidth); |
|
|
|
this.$set(item, 'swipeOffset', offset); |
|
|
|
} else if (item.swipeOffset) { |
|
|
|
// 如果已经打开,允许向右滑动关闭 |
|
|
|
const offset = Math.min(deltaX + (item.swipeOffset || 0), 0); |
|
|
|
this.$set(item, 'swipeOffset', offset); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 触摸结束 |
|
|
|
handleTouchEnd(event, item) { |
|
|
|
const currentOffset = item.swipeOffset || 0; |
|
|
|
|
|
|
|
this.$set(item, 'isAnimating', true); |
|
|
|
|
|
|
|
// 如果滑动距离超过删除按钮宽度的一半,则完全展开,否则收回 |
|
|
|
if (currentOffset < -this.deleteButtonWidth / 2) { |
|
|
|
this.$set(item, 'swipeOffset', -this.deleteButtonWidth); |
|
|
|
} else { |
|
|
|
this.$set(item, 'swipeOffset', 0); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
// 删除物料项 |
|
|
|
handleDeleteItem(item, index) { |
|
|
|
this.$confirm('确定要删除该物料吗?', '提示', { |
|
|
|
confirmButtonText: '确定', |
|
|
|
cancelButtonText: '取消', |
|
|
|
type: 'warning' |
|
|
|
}).then(() => { |
|
|
|
// 调用存储过程删除(operationType: 'D') |
|
|
|
const params = { |
|
|
|
site: this.inboundInfo.site, |
|
|
|
buNo: this.inboundInfo.buNo, |
|
|
|
inboundNo: this.inboundNo, |
|
|
|
materialCode: item.materialCode, |
|
|
|
labelCode: item.labelCode, |
|
|
|
actualQty: item.actualQty, |
|
|
|
batchNo: item.batchNo, |
|
|
|
warehouseId: getCurrentWarehouse(), |
|
|
|
operationType: 'D', // D表示删除 |
|
|
|
documentType: '其他入库' |
|
|
|
}; |
|
|
|
|
|
|
|
validateLabelWithOtherInbound(params).then(({ data }) => { |
|
|
|
if (data && data.code === 0) { |
|
|
|
this.$message.success('删除成功'); |
|
|
|
// 重新加载已扫描标签列表 |
|
|
|
this.loadScannedLabelList(); |
|
|
|
} else { |
|
|
|
this.$message.error(data.msg || '删除失败'); |
|
|
|
} |
|
|
|
}).catch(error => { |
|
|
|
console.error('删除物料失败:', error); |
|
|
|
this.$message.error('删除失败'); |
|
|
|
}); |
|
|
|
}).catch(() => { |
|
|
|
// 用户取消删除,收回滑动 |
|
|
|
this.$set(item, 'isAnimating', true); |
|
|
|
this.$set(item, 'swipeOffset', 0); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// ==================== 原有功能 ==================== |
|
|
|
|
|
|
|
// 处理物料选择 |
|
|
|
handleMaterialSelect() { |
|
|
|
if (!this.materialCode) { |
|
|
|
@ -525,7 +652,9 @@ export default { |
|
|
|
labelCode: item.labelCode, |
|
|
|
materialCode: item.materialCode, |
|
|
|
actualQty: item.actualQty, |
|
|
|
batchNo: item.batchNo |
|
|
|
batchNo: item.batchNo, |
|
|
|
swipeOffset: 0, // 左滑偏移量 |
|
|
|
isAnimating: false // 是否正在动画 |
|
|
|
})); |
|
|
|
|
|
|
|
// 更新入库信息卡片的统计数据 |
|
|
|
@ -942,6 +1071,53 @@ export default { |
|
|
|
background: #0d8f7f; |
|
|
|
} |
|
|
|
|
|
|
|
/* 左滑删除容器 */ |
|
|
|
.swipe-item-wrapper { |
|
|
|
position: relative; |
|
|
|
overflow: hidden; |
|
|
|
background: white; |
|
|
|
} |
|
|
|
|
|
|
|
/* 可滑动的内容区域 */ |
|
|
|
.swipe-content { |
|
|
|
position: relative; |
|
|
|
z-index: 2; |
|
|
|
background: white; |
|
|
|
touch-action: pan-y; /* 允许垂直滚动 */ |
|
|
|
} |
|
|
|
|
|
|
|
/* 删除按钮(隐藏在右侧) */ |
|
|
|
.delete-action { |
|
|
|
position: absolute; |
|
|
|
right: 0; |
|
|
|
top: 0; |
|
|
|
bottom: 0; |
|
|
|
width: 80px; |
|
|
|
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
color: white; |
|
|
|
cursor: pointer; |
|
|
|
z-index: 1; |
|
|
|
transition: background 0.2s ease; |
|
|
|
} |
|
|
|
|
|
|
|
.delete-action:active { |
|
|
|
background: linear-gradient(135deg, #ee5a52 0%, #ff6b6b 100%); |
|
|
|
} |
|
|
|
|
|
|
|
.delete-action i { |
|
|
|
font-size: 20px; |
|
|
|
margin-bottom: 4px; |
|
|
|
} |
|
|
|
|
|
|
|
.delete-action span { |
|
|
|
font-size: 12px; |
|
|
|
font-weight: 500; |
|
|
|
} |
|
|
|
|
|
|
|
.list-header { |
|
|
|
display: flex; |
|
|
|
background: #f8f9fa; |
|
|
|
|