<template>
|
<view class="page-container">
|
<!-- 头部导航 -->
|
<u-navbar
|
title="组托"
|
:fixed="true"
|
:placeholder="true"
|
bgColor="#ffffff"
|
titleStyle="font-weight: 600; color: #303133; font-size: 32rpx;"
|
autoBack
|
></u-navbar>
|
|
<!-- 表单区域 -->
|
<view class="panel-section">
|
<view class="panel form-panel">
|
<u--form
|
labelPosition="left"
|
labelWidth="auto"
|
>
|
<u-form-item borderBottom>
|
<template slot="label">
|
<view class="form-label">
|
<u-icon
|
name="scan"
|
color="#409eff"
|
customStyle="margin-right: 10rpx;"
|
></u-icon>
|
<text class="label-text">托盘码</text>
|
</view>
|
</template>
|
<view class="input-wrap">
|
<u--input
|
v-model="barcode"
|
placeholder="扫码 / 输入托盘码"
|
clearable
|
border="none"
|
:focus="barcodeFocus"
|
@change="barcodeInput"
|
></u--input>
|
</view>
|
</u-form-item>
|
<u-form-item>
|
<template slot="label">
|
<view class="form-label">
|
<u-icon
|
name="list"
|
color="#409eff"
|
customStyle="margin-right: 10rpx;"
|
></u-icon>
|
<text class="label-text">物料码</text>
|
</view>
|
</template>
|
<view class="input-wrap">
|
<u--input
|
v-model="matnr"
|
placeholder="扫码 / 输入物料码"
|
clearable
|
border="none"
|
:focus="matFocus"
|
@change="findMat"
|
></u--input>
|
</view>
|
</u-form-item>
|
</u--form>
|
</view>
|
</view>
|
|
<!-- 列表区域 -->
|
<view class="list-section">
|
<view class="list-header">
|
<view class="title-indicator"></view>
|
<text class="header-title">
|
商品列表 ({{ dataList.length }})
|
</text>
|
</view>
|
|
<view class="list-container">
|
<view
|
class="panel mat-card"
|
v-for="(item, i) in dataList"
|
:key="i"
|
>
|
<view class="card-top">
|
<view class="card-index">{{ i + 1 }}</view>
|
<text class="mat-code">{{ item.matnr }}</text>
|
</view>
|
|
<view class="card-content">
|
<view class="info-row">
|
<text class="info-label">品名</text>
|
<text class="info-value">
|
{{ item.maktx || '-' }}
|
</text>
|
</view>
|
<view class="info-row">
|
<view class="info-col">
|
<text class="info-label">规格</text>
|
<text class="info-value">
|
{{ item.specs || '-' }}
|
</text>
|
</view>
|
<view class="info-col">
|
<text class="info-label">批号</text>
|
<text class="info-value highlight">
|
{{ item.batch || '-' }}
|
</text>
|
</view>
|
</view>
|
<view class="info-row">
|
<view class="info-col">
|
<text class="info-label">数量</text>
|
<text class="info-value qty">
|
{{ item.anfme }}
|
</text>
|
</view>
|
</view>
|
</view>
|
|
<view class="card-actions">
|
<u-button
|
type="primary"
|
size="small"
|
plain
|
text="修改"
|
@click="revise(item, i)"
|
customStyle="width: 140rpx; margin: 0;"
|
></u-button>
|
<view style="width: 20rpx"></view>
|
<u-button
|
type="error"
|
size="small"
|
plain
|
text="移除"
|
@click="remove(item, i)"
|
customStyle="width: 140rpx; margin: 0;"
|
></u-button>
|
</view>
|
</view>
|
|
<u-empty
|
v-if="dataList.length === 0"
|
mode="list"
|
text="暂无商品,请扫描物料码添加"
|
marginTop="40"
|
></u-empty>
|
</view>
|
</view>
|
|
<!-- 底部操作按钮 -->
|
<view class="bottom-bar">
|
<view class="btn-wrap">
|
<u-button
|
type="info"
|
text="重置"
|
@click="resetConfirmBtn"
|
></u-button>
|
</view>
|
<view
|
class="btn-wrap"
|
style="flex: 2; margin-left: 20rpx"
|
>
|
<u-button
|
type="primary"
|
text="确认组托"
|
@click="combConfirmBtn"
|
:disabled="dataList.length === 0"
|
:throttleTime="1500"
|
></u-button>
|
</view>
|
</view>
|
|
<!-- 修改数量弹窗 -->
|
<u-popup
|
:show="showRevise"
|
mode="center"
|
round="12"
|
@close="showRevise = false"
|
>
|
<view class="popup-card">
|
<view class="popup-header"><text>修改信息</text></view>
|
<view class="popup-body">
|
<u--form
|
labelWidth="80"
|
labelPosition="left"
|
>
|
<u-form-item label="编码">
|
<text class="popup-text-val">{{ editMatnr }}</text>
|
</u-form-item>
|
<u-form-item label="批号">
|
<u--input
|
v-model="batch"
|
placeholder="输入批号"
|
border="surround"
|
></u--input>
|
</u-form-item>
|
<u-form-item label="数量">
|
<u-number-box
|
v-model="count"
|
:step="0.01"
|
:max="9999999"
|
@change="changeValue"
|
></u-number-box>
|
</u-form-item>
|
</u--form>
|
</view>
|
<view class="popup-footer">
|
<u-button
|
text="取消"
|
@click="showRevise = false"
|
customStyle="margin-right: 20rpx; flex: 1;"
|
></u-button>
|
<u-button
|
type="primary"
|
text="确认"
|
@click="reviseConfirm"
|
customStyle="flex: 1;"
|
></u-button>
|
</view>
|
</view>
|
</u-popup>
|
|
<!-- 模态框 -->
|
<u-modal
|
:show="showRemove"
|
title="确认移除"
|
content="是否移除该商品?"
|
showCancelButton
|
@confirm="removeConfirm"
|
@cancel="showRemove = false"
|
></u-modal>
|
<u-modal
|
:show="showComb"
|
title="确认组托"
|
content="确认将商品组托入库?"
|
showCancelButton
|
@confirm="comb"
|
@cancel="showComb = false"
|
></u-modal>
|
<u-modal
|
:show="showReset"
|
title="确认重置"
|
content="是否清空所有商品?"
|
showCancelButton
|
@confirm="resetConfirm"
|
@cancel="showReset = false"
|
></u-modal>
|
<u-toast ref="uToast"></u-toast>
|
</view>
|
</template>
|
|
<script>
|
import { findMatAuth, combAuth } from './api.js'
|
|
export default {
|
data() {
|
return {
|
barcode: '',
|
matnr: '',
|
dataList: [],
|
count: 0,
|
rowNum: '',
|
editMatnr: '',
|
batch: '',
|
weight: '',
|
|
barcodeFocus: true,
|
matFocus: false,
|
matData: '',
|
removeNum: 0,
|
|
showRevise: false,
|
showRemove: false,
|
showComb: false,
|
showReset: false
|
}
|
},
|
methods: {
|
barcodeInput(val) {
|
setTimeout(() => {
|
var len = this.barcode.length
|
if (len > 0 && len !== 8 && len !== 9) {
|
this.$showToast({
|
type: 'error',
|
message: '托盘码有误请重试'
|
})
|
this.barcodeFocuss()
|
return
|
}
|
this.focuss()
|
}, 200)
|
},
|
barcodeFocuss() {
|
this.barcodeFocus = false
|
setTimeout(() => {
|
this.barcode = ''
|
this.barcodeFocus = true
|
}, 100)
|
},
|
focuss() {
|
this.matFocus = false
|
setTimeout(() => {
|
this.matnr = ''
|
this.matFocus = true
|
}, 100)
|
},
|
async findMat(val) {
|
if (!this.matnr) return
|
try {
|
const { code, data, msg } = await findMatAuth(
|
{ matnr: this.matnr },
|
{ custom: { catch: true } }
|
)
|
if (code === 200 && data) {
|
this.matData = data
|
this.matnr = ''
|
this.matData['batch'] = ''
|
|
let that = this
|
uni.navigateTo({
|
url: '/pages/mat/matSelected',
|
success: function (resNav) {
|
resNav.eventChannel.emit('mat', {
|
data: data
|
})
|
},
|
events: {
|
matList: function (data) {
|
that.checkMat(data.data)
|
that.focuss()
|
}
|
}
|
})
|
} else if (code === 403) {
|
this.$showToast({ type: 'error', message: msg })
|
setTimeout(() => {
|
uni.reLaunch({ url: '/pages/login/login' })
|
}, 1000)
|
} else {
|
if (!data && data !== null) {
|
this.$showToast({
|
type: 'error',
|
message: msg || '查询失败'
|
})
|
}
|
}
|
} catch (err) {
|
// interceptor toasts the error natively
|
}
|
},
|
checkMat(mat) {
|
var len = this.dataList.length
|
var add = true,
|
sameItem = false
|
for (var i = 0; i < len; i++) {
|
if (mat.matnr == this.dataList[i].matnr) {
|
for (var j = 0; j < len; j++) {
|
if (mat.batch == this.dataList[j].batch) {
|
sameItem = true
|
}
|
}
|
// 相同物料 不同批号 新加列表
|
if (mat.batch != this.dataList[i].batch) {
|
if (sameItem) {
|
add = false
|
} else {
|
add = true
|
}
|
} else {
|
// 相同物料相同批号 数量累加
|
this.dataList[i].anfme += mat.anfme
|
add = false
|
}
|
}
|
}
|
if (add) {
|
this.dataList.unshift(mat)
|
}
|
},
|
revise(item, i) {
|
this.editMatnr = this.dataList[i].matnr
|
this.count = this.dataList[i].anfme
|
this.batch = this.dataList[i].batch
|
this.weight = this.dataList[i].weight
|
this.rowNum = i
|
this.showRevise = true
|
},
|
changeValue(e) {
|
this.count = e.value
|
},
|
reviseConfirm() {
|
this.dataList[this.rowNum].anfme = this.count
|
this.dataList[this.rowNum].batch = this.batch
|
this.dataList[this.rowNum].weight = this.weight
|
this.editMatnr = ''
|
this.$showToast({ type: 'success', message: '修改成功' })
|
this.showRevise = false
|
},
|
remove(item, i) {
|
this.removeNum = i
|
this.showRemove = true
|
},
|
removeConfirm() {
|
this.dataList.splice(this.removeNum, 1)
|
this.$showToast({ type: 'success', message: '移除成功' })
|
this.showRemove = false
|
},
|
combConfirmBtn() {
|
if (this.dataList.length === 0) return
|
this.showComb = true
|
},
|
async comb() {
|
if (this.barcode === '') {
|
this.$showToast({ type: 'error', message: '请扫描托盘条码' })
|
this.showComb = false
|
return
|
}
|
for (var i = 0; i < this.dataList.length; i++) {
|
if (
|
this.dataList[i].anfme == 0 ||
|
this.dataList[i].anfme == ''
|
) {
|
this.$showToast({
|
type: 'error',
|
message: this.dataList[i].matnr + '组托数量不能为0'
|
})
|
this.showComb = false
|
return
|
}
|
}
|
|
this.showComb = false
|
uni.vibrateShort()
|
|
try {
|
const { code, msg } = await combAuth(
|
{
|
barcode: this.barcode,
|
combMats: this.dataList
|
},
|
{ custom: { catch: true } }
|
)
|
|
if (code === 200) {
|
this.resst()
|
this.$showToast({ type: 'success', message: '组托成功' })
|
} else if (code === 403) {
|
this.$showToast({ type: 'error', message: msg })
|
setTimeout(() => {
|
uni.reLaunch({ url: '/pages/login/login' })
|
}, 1000)
|
} else {
|
this.$showToast({
|
type: 'error',
|
message: msg || '组托失败'
|
})
|
}
|
} catch (err) {
|
// http interceptor handles fail toast
|
}
|
},
|
resetConfirmBtn() {
|
this.showReset = true
|
},
|
resetConfirm() {
|
this.dataList = []
|
this.barcode = ''
|
this.$showToast({ type: 'success', message: '重置完成' })
|
this.showReset = false
|
},
|
resst() {
|
this.dataList = []
|
this.barcode = ''
|
this.barcodeFocuss()
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
page {
|
background-color: #f0f2f5;
|
}
|
|
.page-container {
|
min-height: 100vh;
|
background-color: #f0f2f5;
|
padding-bottom: 140rpx; /* 给底部悬浮按钮留出空间 */
|
}
|
|
/* 面板区域 */
|
.panel-section {
|
padding: 24rpx;
|
}
|
|
.panel {
|
background-color: #ffffff;
|
border-radius: 12rpx;
|
padding: 24rpx;
|
box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.05);
|
margin-bottom: 24rpx;
|
}
|
|
.form-panel {
|
padding: 10rpx 24rpx; /* 减小表单面板的上下内边距 */
|
}
|
|
.form-label {
|
display: flex;
|
align-items: center;
|
height: 100%; /* 确保能沾满父级高度 */
|
padding-right: 20rpx; /* 输入框与文字设置间距 */
|
}
|
|
.label-text {
|
font-size: 28rpx;
|
color: #606266;
|
white-space: nowrap;
|
line-height: 1; /* 统一行高消除偏差 */
|
}
|
|
.input-wrap {
|
flex: 1;
|
display: flex;
|
align-items: center; /* 垂直居中输入框内部 */
|
justify-content: center;
|
height: 100%;
|
}
|
|
/* 覆盖 uView form-item 默认对齐,强制居中 */
|
::v-deep .u-form-item__body {
|
align-items: center !important;
|
padding: 10rpx 0 !important; /* 调整单行高度 */
|
}
|
::v-deep .u-form-item__body__left {
|
align-items: center !important;
|
margin-bottom: 0 !important;
|
}
|
|
/* 列表区域 */
|
.list-section {
|
padding: 0 24rpx;
|
}
|
|
.list-header {
|
display: flex;
|
align-items: center;
|
margin-bottom: 24rpx;
|
}
|
|
.title-indicator {
|
width: 6rpx;
|
height: 30rpx;
|
background-color: #409eff;
|
border-radius: 4rpx;
|
margin-right: 16rpx;
|
}
|
|
.header-title {
|
font-size: 30rpx;
|
color: #303133;
|
font-weight: 600;
|
}
|
|
/* 卡片样式 */
|
.mat-card {
|
display: flex;
|
flex-direction: column;
|
}
|
|
.card-top {
|
display: flex;
|
align-items: center;
|
border-bottom: 1px solid #ebeef5;
|
padding-bottom: 16rpx;
|
margin-bottom: 16rpx;
|
}
|
|
.card-index {
|
background-color: #409eff;
|
color: #fff;
|
width: 40rpx;
|
height: 40rpx;
|
border-radius: 50%;
|
text-align: center;
|
line-height: 40rpx;
|
font-size: 24rpx;
|
margin-right: 16rpx;
|
}
|
|
.mat-code {
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #303133;
|
}
|
|
.card-content {
|
display: flex;
|
flex-direction: column;
|
}
|
|
.info-row {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 12rpx;
|
}
|
|
.info-col {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
}
|
|
.info-label {
|
color: #909399;
|
font-size: 26rpx;
|
width: 80rpx;
|
}
|
|
.info-value {
|
color: #303133;
|
font-size: 28rpx;
|
}
|
|
.highlight {
|
color: #e6a23c;
|
}
|
|
.qty {
|
color: #f56c6c;
|
font-weight: bold;
|
}
|
|
.card-actions {
|
display: flex;
|
justify-content: flex-end;
|
margin-top: 10rpx;
|
border-top: 1px dashed #ebeef5;
|
padding-top: 20rpx;
|
}
|
|
/* 底部操作条 */
|
.bottom-bar {
|
position: fixed;
|
bottom: 0;
|
left: 0;
|
right: 0;
|
background-color: #fff;
|
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
display: flex;
|
padding: 20rpx 24rpx;
|
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
z-index: 99;
|
}
|
|
.btn-wrap {
|
display: flex;
|
flex: 1;
|
}
|
|
/* 弹窗样式 */
|
.popup-card {
|
width: 600rpx;
|
background-color: #fff;
|
border-radius: 12rpx;
|
padding: 40rpx 30rpx;
|
}
|
|
.popup-header {
|
text-align: center;
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #303133;
|
margin-bottom: 30rpx;
|
}
|
|
.popup-text-val {
|
font-size: 28rpx;
|
color: #606266;
|
}
|
|
.popup-footer {
|
display: flex;
|
margin-top: 40rpx;
|
}
|
</style>
|