Files
FT541-WMS/RuoYi-App-master/pages/in/bindManypk.vue

389 lines
8.9 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="container">
<view class="form card">
<view class="field">
<text class="input-label">仓库</text>
<uni-data-select
v-model="warehouseId"
:localdata="warehouseList"
:clear="false"
placeholder="请选择仓库"
/>
</view>
<view class="field">
<text class="label">入库子单</text>
<uni-easyinput v-model="materialCode" @input="onMaterialInput" placeholder="请输入入库子单编码"
:clearable="true">
<template #right>
<text class="scan-icon" @click="handleScanMaterial">📷</text>
</template>
</uni-easyinput>
</view>
</view>
<uni-popup ref="detailPopup" type="bottom">
<view class="popup">
<text class="popup-title">物料详情</text>
<view v-if="materialDetail">
<view class="row">
<text class="row-label">物料名称</text>
<text class="row-value">{{ materialDetail.productName }}</text>
</view>
<view class="row">
<text class="row-label">物料编码</text>
<text class="row-value">{{ materialDetail.productId }}</text>
</view>
<view class="row">
<text class="row-label">可用数量</text>
<text class="row-value">{{ materialDetail.quantityX }}</text>
</view>
<view class="row">
<text class="row-label">入库数量</text>
<uni-easyinput v-model="bindQty" type="number" placeholder="输入数量"/>
</view>
<view class="actions">
<button class="btn primary" @click="handleConfirmIn" :disabled="isBinding">确认入库</button>
<button class="btn secondary" @click="closePopup">取消</button>
</view>
</view>
</view>
</uni-popup>
<!-- 页脚操作区:确认入库 -->
<!-- <view class="footer-actions">-->
<!-- <button class="confirm-btn" @click="handleConfirmIn" :disabled="!trayCode || isConfirming">-->
<!-- {{ isConfirming ? '入库中...' : '确认入库' }}-->
<!-- </button>-->
<!-- </view>-->
</view>
</template>
<script>
import {addInJobpk, bindTray, getOrderGoods, getTrayInfo} from '@/api/in/order.js'
import {getBasWarehouList} from '@/api/bas/bas.js'
export default {
data() {
return {
trayCode: '',
materialCode: '',
warehouseId: '',
warehouseList: [],
trayMaterials: [],
loadingTray: false,
materialDetail: null,
bindQty: null,
isBinding: false,
// 入库确认相关
isConfirming: false,
selectedEntrance: ''
}
},
onReady() {
// 获取仓库列表
this.getWarehouseList()
},
methods: {
// 获取仓库列表
async getWarehouseList() {
try {
const response = await getBasWarehouList({
pageNum: 1,
pageSize: 100,
warehouseType: 2
})
if (response.code === 200) {
this.warehouseList = response.rows.map(item => ({
value: item.warehouseId,
text: item.warehouseName
// type: item.warehouseType
}))
}
} catch (error) {
console.error('获取仓库列表失败:', error)
uni.showToast({
title: '获取仓库列表失败',
icon: 'none'
})
}
},
mapTrayMaterials(res) {
const list = Array.isArray(res.data) ? res.data : (Array.isArray(res.rows) ? res.rows : (res.data.rows || []))
return list.map(item => ({
productId: item.productId,
materialDesc: item.productName,
quantity: item.quantity,
}))
},
async onTrayInput(val) {
this.trayCode = String(val || '').trim()
if (!this.trayCode) {
this.trayMaterials = [];
return
}
try {
this.loadingTray = true
const res = await getTrayInfo(this.trayCode)
this.trayMaterials = res.data
} catch (e) {
console.error('getTrayInfo error', e)
uni.showToast({title: '查询托盘失败', icon: 'none'})
} finally {
this.loadingTray = false
}
},
// 确认入库
async handleConfirmIn() {
if (!this.warehouseId) {
uni.showToast({title: '请先选择仓库', icon: 'none'})
return
}
try {
this.isConfirming = true
const payload = {
warehouseId: this.warehouseId,
stockinDetailId: this.materialCode,
inQuantity: this.bindQty
}
const resp = await addInJobpk(payload)
if (resp && resp.code === 200) {
uni.showToast({title: '入库成功', icon: 'success'})
// 清空托盘与列表,便于下一次操作
this.trayCode = ''
this.trayMaterials = []
} else {
uni.showToast({title: (resp && resp.msg) || '入库失败', icon: 'none'})
}
} catch (e) {
console.error('addInJob error', e)
uni.showToast({title: '入库失败', icon: 'none'})
} finally {
this.isConfirming = false
this.isBinding = false
}
},
extractMaterialDetail(res) {
const pickFirst = (r) => {
if (Array.isArray(r)) return r[0]
if (Array.isArray(r?.rows)) return r.rows[0]
if (Array.isArray(r?.data)) return r.data[0]
if (Array.isArray(r?.data?.rows)) return r.data.rows[0]
return r
}
const raw = pickFirst(res)
if (!raw) return null
return {
stockinDetailId: raw.stockinDetailId || raw.id || raw.detailId,
productName: raw.productName || raw.materialName || raw.extraField?.materialDesc || '',
productId: raw.productId || raw.materialId || raw.productCode || raw.extraField?.productId || '',
quantity: raw.quantity ?? raw.availableQty ?? raw.inQuantity ?? 0,
}
},
async onMaterialInput(val) {
this.materialCode = String(val || '').trim()
if (!this.materialCode) return
try {
const res = await getOrderGoods({stockinDetailId: this.materialCode})
const detail = res.data
if (!detail) {
uni.showToast({title: '未找到物料信息', icon: 'none'})
return
}
this.materialDetail = detail
this.bindQty = detail.quantityX
this.$refs.detailPopup.open()
} catch (e) {
console.error('get material detail error', e)
uni.showToast({title: '查询物料失败', icon: 'none'})
}
},
closePopup() {
this.$refs.detailPopup.close()
},
handleScanTray() {
uni.scanCode({
success: (res) => {
this.trayCode = res.result || ''
this.onTrayInput(this.trayCode)
}
})
},
handleScanMaterial() {
uni.scanCode({
success: (res) => {
this.materialCode = res.result || ''
this.onMaterialInput(this.materialCode)
}
})
}
}
}
</script>
<style>
.container {
padding: 12px;
background: #f6f7fb;
min-height: 100vh;
}
.card {
background: #fff;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
padding: 12px;
margin-bottom: 12px;
}
.form {
display: flex;
flex-direction: column;
gap: 12px;
}
.field {
display: flex;
flex-direction: column;
gap: 6px;
}
.label {
color: #666;
font-size: 12px;
}
.scan-icon {
font-size: 16px;
padding: 0 8px;
color: #2979ff;
}
.section-title {
font-size: 14px;
font-weight: 600;
margin-bottom: 8px;
}
.list {
margin-top: 4px;
display: flex;
flex-direction: column;
gap: 10px;
}
.item {
padding: 10px;
border: 1px solid #eee;
border-radius: 8px;
}
.item-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.name {
font-size: 14px;
color: #333;
}
.qty-tag {
background: #eef3ff;
color: #2979ff;
padding: 2px 6px;
border-radius: 12px;
font-size: 12px;
}
.meta {
color: #888;
font-size: 12px;
margin-top: 6px;
}
.empty {
color: #999;
font-size: 12px;
padding: 12px;
text-align: center;
}
.popup {
padding: 16px;
background: #fff;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
}
.popup-title {
font-weight: 600;
font-size: 16px;
margin-bottom: 10px;
}
.row {
margin: 8px 0;
display: flex;
justify-content: space-between;
}
.row-label {
color: #666;
}
.row-value {
color: #333;
}
.actions {
display: flex;
gap: 10px;
margin-top: 12px;
}
.btn {
flex: 1;
padding: 10px;
border-radius: 8px;
}
.primary {
background: #2979ff;
color: #fff;
}
.secondary {
background: #f1f1f1;
color: #333;
}
/* 页脚操作区 */
.footer-actions {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 10px 12px;
background: #fff;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
}
.confirm-btn {
width: 100%;
padding: 12px;
border-radius: 8px;
background: #07c160;
color: #fff;
font-size: 16px;
}
</style>