Files
FT577-WMS/pda/pages/warehouse/inbound/bindTray.vue
FT577-Server fc86389d66 运行调整
2026-10-08 08:57:15 +08:00

685 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page-container">
<!-- 任务信息 -->
<view class="task-info" v-if="taskNo">
<text class="task-label">任务编号</text>
<text class="task-value">{{ taskNo }}</text>
</view>
<!-- 托盘信息 -->
<view class="form-section">
<!-- <text class="form-title">托盘信息</text> -->
<!-- <view class="form-item">
<text class="form-label">托盘号</text>
<input class="form-input" v-model="trayCode" placeholder="请输入托盘号" />
</view> -->
<view class="scan-header">
<text class="scan-title">托盘信息</text>
<view class="scan-btn" @click="startScan">
<uni-icons type="scan" size="18" color="#1890ff"></uni-icons>
<text class="scan-btn-text">扫码</text>
</view>
</view>
<view class="input-wrap">
<input class="scan-input" v-model="trayCode" placeholder="请输入或扫描托盘条码"
@confirm="handleBarcode" />
</view>
</view>
<!-- 扫码添加物料 -->
<view class="scan-section">
<view class="scan-header">
<text class="scan-title">版辊信息</text>
<!-- <view class="scan-btn" @click="startScan">
<uni-icons type="scan" size="18" color="#1890ff"></uni-icons>
<text class="scan-btn-text">扫码</text>
</view> -->
</view>
<uni-data-select class="sel"
v-model="stockinId"
:localdata="inStockinOptions"
placeholder="请选择入库单据"
@change="handleInStockinChange">
</uni-data-select>
<uni-data-select class="sel"
v-model="barcode"
:localdata="rollerNumberOptions"
placeholder="请选择版辊号"
@change="handleBarcode">
</uni-data-select>
<!-- <view class="input-wrap">
<input class="scan-input" v-model="barcode" placeholder="请输入或扫描版辊编号"
@confirm="handleBarcode" />
</view> -->
<!-- <button class="btn-add" @click="addItem" :disabled="!this.barcode || !this.trayCode">
<uni-icons type="plus" size="16" color="#fff"></uni-icons>
<text class="btn-add-text">加入列表</text>
</button> -->
</view>
<!-- 当前扫码物料信息(待添加) -->
<view class="form-section" v-if="currentMaterial">
<text class="form-title">物料信息</text>
<!-- <view class="info-row">
<text class="info-label">物料编码</text>
<text class="info-value">{{ currentMaterial.productId }}</text>
</view>
<view class="info-row">
<text class="info-label">物料名称</text>
<text class="info-value">{{ currentMaterial.productName }}</text>
</view> -->
<view class="info-row">
<text class="info-label">子单号</text>
<text class="info-value">{{ currentMaterial.stockinDetailId }}</text>
</view>
<view class="info-row">
<text class="info-label">辊号</text>
<text class="info-value">{{ currentMaterial.rollerNumber }}</text>
</view>
<view class="info-row">
<text class="info-label">产品名称</text>
<text class="info-value">{{ currentMaterial.productName }}</text>
</view>
<view class="info-row">
<text class="info-label">版长</text>
<text class="info-value">{{ currentMaterial.length }}</text>
</view>
<view class="info-row">
<text class="info-label">版周</text>
<text class="info-value">{{ currentMaterial.perimeter }}</text>
</view>
<view class="form-item">
<text class="form-label">绑定数量</text>
<input class="form-input" v-model="currentQty" disabled type="number" placeholder="请输入绑定数量" />
</view>
<button class="btn-add" @click="addItem">
<uni-icons type="plus" size="16" color="#fff"></uni-icons>
<text class="btn-add-text">加入列表</text>
</button>
</view>
<!-- 已添加物料列表 -->
<view class="list-section" v-if="items.length > 0">
<view class="section-header">
<text class="section-title">已绑定物料({{ items.length }} 种)</text>
</view>
<view class="item-card" v-for="(item, index) in items" :key="index">
<view class="item-body">
<!-- <view class="item-row">
<text class="item-label">物料编码</text>
<text class="item-value">{{ item.productId }}</text>
</view>
<view class="item-row">
<text class="item-label">物料名称</text>
<text class="item-value">{{ item.productName }}</text>
</view> -->
<view class="item-row">
<text class="item-label">辊号</text>
<text class="item-value">{{ item.rollerNumber }}</text>
</view>
<view class="item-row">
<text class="item-label">产品名称</text>
<text class="item-value">{{ item.productName }}</text>
</view>
<view class="item-row">
<text class="item-label">版长</text>
<text class="item-value">{{ item.length }}</text>
</view>
<view class="item-row">
<text class="item-label">版周</text>
<text class="item-value">{{ item.perimeter }}</text>
</view>
<view class="item-row">
<text class="item-label">绑定数量</text>
<text class="item-value highlight">{{ item.quantity }}</text>
</view>
</view>
<view class="item-delete" @click="removeItem(index)">
<uni-icons type="trash" size="20" color="#f5222d"></uni-icons>
</view>
</view>
</view>
<!-- 空状态提示 -->
<view class="empty-state" v-if="items.length === 0">
<text class="empty-text">请扫码添加版辊信息</text>
</view>
<!-- 操作按钮 -->
<view class="btn-section">
<button class="btn btn-primary" :disabled="items.length === 0 || !trayCode" @click="submitBindTrayAction">
确认绑盘({{ items.length }} 种物料)
</button>
<!-- <button class="btn btn-success" :disabled="!trayCode" @click="submitAddInJobAction">
生成入库作业
</button> -->
<button class="btn btn-default" @click="resetAll">全部重置</button>
</view>
</view>
</template>
<script>
import { getMaterialByDetailId, getMaterialByRollerNumber, submitBindTray, submitBindTrayMsg, submitAddInJob, getInboundStockList, getDetailList } from '@/api/warehouse/inbound/bindTray'
export default {
data() {
return {
taskNo: '',
trayCode: '',
// 当前扫码
barcode: '',
stockinId:'',
currentMaterial: null,
currentQty: '',
// 已加入列表的物料
items: [],
inStockinOptions:[],
rollerNumberOptions:[],
}
},
onLoad(options) {
// if (options.taskNo) {
// this.taskNo = options.taskNo
// this.getInStockinList()
// }
this.getInStockinList()
},
methods: {
// 调用摄像头扫码
startScan() {
var that = this
uni.scanCode({
onlyFromCamera: false,
scanType: ['barCode', 'qrCode'],
success: function(res) {
that.barcode = res.result
that.handleBarcode()
}
})
},
//获取入库单据
async getInStockinList() {
try {
// 发起请求,RuoYi 的分页接口通常返回 { rows: [], total: number }
const res = await getInboundStockList({});
// 将后端返回的 rows 数据转换为 uni-data-select 需要的格式
this.inStockinOptions = (res.rows || []).map(item => {
return {
value: item.stockinId, // 实际传给后端的值(如单据ID)
text: item.stockinId // 显示给用户看的文本(如单据编号)
};
});
} catch (error) {
console.error('获取入库单列表失败:', error);
uni.showToast({ title: '获取数据失败', icon: 'none' });
}
},
handleInStockinChange(value) {
// 1. 参数 value 直接就是选中的 stockinId,无需 e.detail.value
const stockinId = value;
// 2. 使用 v-model 时,组件会自动更新 this.stockinId,无需手动赋值
// this.stockinId = value; (可省略)
// 3. 每次切换单据,清空并重置版辊号下拉框
this.barcode = '';
this.rollerNumberOptions = [];
// 4. 只有选中了值才去请求下级数据,且不要再重复请求入库单列表了
if (stockinId) {
this.fetchRollerNumberOptions(stockinId); // 传入正确的变量名
}
},
// 根据单据号获取版辊号列表
async fetchRollerNumberOptions(stockinId) {
try {
const res = await getDetailList({ stockinId });
// console.log(res)
this.rollerNumberOptions = (res.data || []).map(item => {
return {
value: item.rollerNumber, // 实际传给后端的值(如单据ID)
text: item.rollerNumber // 显示给用户看的文本(如单据编号)
};
});
} catch (error) {
console.error('获取版辊号失败,请检查单据明细:', error);
}
},
handleRollerNumberChange(value) {
// 1. 参数 value 直接就是选中的 stockinId,无需 e.detail.value
const rollerNumber = value;
// 4. 只有选中了值才去请求下级数据,且不要再重复请求入库单列表了
if (value) {
var that = this
// getMaterialByDetailId(this.barcode).then(function(res) {
getMaterialByRollerNumber(this.barcode).then(function(res) {
that.currentMaterial = res.data
that.currentQty = res.data.quantity ? String(res.data.quantity) : ''
that.$modal.msgSuccess('物料信息获取成功')
}).catch(function() {
that.currentMaterial = null
that.currentQty = ''
// that.$modal.msg('未找到该入库子单信息')
that.$modal.msg('未找到该版辊信息,可能是无单据明细或已绑定完成')
})
}
},
// 根据入库明细ID查询物料
handleBarcode() {
if (!this.barcode) {
// this.$modal.msg('请输入入库子单号')
this.$modal.msg('请输入版辊信息')
return
}
var that = this
// getMaterialByDetailId(this.barcode).then(function(res) {
getMaterialByRollerNumber(this.barcode).then(function(res) {
that.currentMaterial = res.data
that.currentQty = res.data.quantity ? String(res.data.quantity) : ''
that.$modal.msgSuccess('物料信息获取成功')
}).catch(function() {
that.currentMaterial = null
that.currentQty = ''
// that.$modal.msg('未找到该入库子单信息')
that.$modal.msg('未找到该版辊信息,可能是无单据明细或已绑定完成')
})
},
// 将当前物料加入绑定列表
addItem() {
if (!this.trayCode) {
this.$modal.msg('请输入或扫描托盘号')
return
}
if (!this.barcode) {
this.$modal.msg('请选择要绑定的辊号')
return
}
// 检查是否已存在相同子单
var exists = this.items.some(function(i) {
return i.stockinDetailId === this.currentMaterial.stockinDetailId
}.bind(this))
if (exists) {
this.$modal.msg('该物料已在列表中,请勿重复添加')
return
}
this.items.push({
stockinDetailId: this.currentMaterial.stockinDetailId,
productId: this.currentMaterial.rollerNumber,
productName: this.currentMaterial.productName,
rollerNumber: this.currentMaterial.rollerNumber,
length: this.currentMaterial.length,
perimeter: this.currentMaterial.perimeter,
// colorSequence: this.currentMaterial.colorSequence,
// color: this.currentMaterial.color,
// spec: this.currentMaterial.spec,
quantity: Number(this.currentQty)
})
// 清空当前扫码区,继续扫下一个
this.barcode = ''
this.currentMaterial = null
this.currentQty = ''
this.$modal.msgSuccess('已加入列表')
},
// 从列表中移除某条物料
removeItem(index) {
this.items.splice(index, 1)
},
// 提交绑盘
submitBindTrayAction() {
if (!this.trayCode) {
this.$modal.msg('请输入托盘号')
return
}
if (this.items.length === 0) {
this.$modal.msg('请至少添加一种物料')
return
}
var data = {
trayCode: this.trayCode,
items: this.items.map(function(i) {
return {
stockinDetailId: i.stockinDetailId,
productId: i.rollerNumber,
productName: i.productName,
rollerNumber: i.rollerNumber,
length: i.length,
perimeter: i.perimeter,
// colorSequence: i.colorSequence,
// color: i.color,
// spec: i.spec,
quantity: i.quantity
}
})
}
var that = this
// submitBindTray(data).then(function(res) {
submitBindTrayMsg(data).then(function(res) {
that.$modal.msgSuccess(res.msg || '入库绑盘成功')
that.resetAll()
}).catch(function() {})
},
submitAddInJobAction() {
if (!this.trayCode) {
this.$modal.msg('请输入托盘号')
return
}
// if (this.items.length === 0) {
// this.$modal.msg('请至少添加一种物料')
// return
// }
var data = {
trayCode: this.trayCode,
}
var that = this
submitAddInJob(data).then(function(res) {
that.$modal.msgSuccess(res.msg || '生成入库作业成功')
that.resetAll()
}).catch(function() {})
},
// 全部重置
resetAll() {
this.trayCode = ''
this.barcode = ''
this.currentMaterial = null
this.currentQty = ''
this.items = []
}
}
}
</script>
<style lang="scss" scoped>
page {
background-color: #f5f7fa;
min-height: 100%;
}
.page-container {
padding: 24rpx;
padding-bottom: 60rpx;
}
/* 任务信息 */
.task-info {
background: #e6f7ff;
border-radius: 12rpx;
padding: 20rpx 24rpx;
margin-bottom: 24rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.task-label {
font-size: 26rpx;
color: #1890ff;
}
.task-value {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
/* 扫码区 */
.scan-section {
background: #fff;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}
.scan-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.scan-title {
font-size: 30rpx;
font-weight: 500;
color: #333;
}
.scan-btn {
display: flex;
align-items: center;
padding: 8rpx 20rpx;
border: 1rpx solid #1890ff;
border-radius: 8rpx;
}
.scan-btn-text {
font-size: 24rpx;
color: #1890ff;
margin-left: 8rpx;
}
.input-wrap {
border: 1rpx solid #e8e8e8;
border-radius: 8rpx;
padding: 4rpx;
}
.scan-input {
font-size: 28rpx;
padding: 16rpx;
word-break: break-all;
width: 100%;
height: auto;
line-height: 1.4;
}
/* 通用 form-section */
.form-section {
background: #fff;
border-radius: 16rpx;
padding: 28rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
}
.form-title {
font-size: 30rpx;
font-weight: 500;
color: #333;
margin-bottom: 24rpx;
padding-bottom: 16rpx;
border-bottom: 1rpx solid #f0f0f0;
display: block;
}
.form-item {
display: flex;
align-items: center;
padding: 16rpx 0;
}
.form-label {
font-size: 28rpx;
color: #666;
width: 160rpx;
flex-shrink: 0;
}
.form-input {
flex: 1;
font-size: 28rpx;
border: 1rpx solid #e8e8e8;
border-radius: 8rpx;
padding: 16rpx;
word-break: break-all;
min-width: 0;
height: auto;
line-height: 1.4;
}
.info-row {
display: flex;
justify-content: space-between;
padding: 16rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
.info-label {
font-size: 28rpx;
color: #999;
}
.info-value {
font-size: 28rpx;
color: #333;
}
/* 加入列表按钮 */
.btn-add {
margin-top: 24rpx;
background: #1890ff;
color: #fff;
border-radius: 12rpx;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: center;
padding: 10rpx 0;
border: none;
}
.btn-add-text {
font-size: 28rpx;
color: #fff;
margin-left: 8rpx;
}
/* 已添加物料列表 */
.list-section {
margin-bottom: 24rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.section-title {
font-size: 30rpx;
font-weight: 500;
color: #333;
}
.item-card {
background: #fff;
border-radius: 16rpx;
padding: 24rpx 28rpx;
margin-bottom: 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
display: flex;
align-items: center;
justify-content: space-between;
}
.item-body {
flex: 1;
margin-right: 20rpx;
}
.item-row {
display: flex;
justify-content: space-between;
padding: 8rpx 0;
}
.item-label {
font-size: 26rpx;
color: #999;
}
.item-value {
font-size: 26rpx;
color: #333;
}
.item-value.highlight {
color: #1890ff;
font-weight: 500;
}
.item-delete {
padding: 8rpx;
}
/* 空状态 */
.empty-state {
background: #fff;
border-radius: 16rpx;
padding: 60rpx 0;
margin-bottom: 24rpx;
display: flex;
align-items: center;
justify-content: center;
}
.empty-text {
font-size: 28rpx;
color: #ccc;
}
/* 底部按钮 */
.btn-section {
padding: 8rpx 0 24rpx;
}
.btn {
font-size: 30rpx;
border-radius: 12rpx;
margin-bottom: 20rpx;
}
.btn-primary {
background: #1890ff;
color: #fff;
}
.btn-success {
background: #0cca1f;
color: #fff;
}
.btn-primary[disabled] {
background: #b0d4f5;
color: #fff;
}
.btn-default {
background: #fff;
color: #666;
border: 1rpx solid #d9d9d9;
}
</style>