pda-uni-app-perkins/pages/stock-in/manual.vue
2025-10-31 22:49:51 +08:00

392 lines
8.2 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="header">
<button class="back" @click="back"><i class="icon icon-arrow_back"
style="color:#05DCEF;font-size:36rpx"></i></button>
<text class="title">手动码盘入库</text>
</view>
<view class="content">
<!-- 顶部提示 -->
<view class="tip">
<view class="tip-icon"><i class="icon icon-info" style="color:#05DCEF"></i></view>
<text class="tip-text">请先扫描载具号然后添加物料信息进行码盘入库</text>
</view>
<!-- 载具条码 -->
<view class="field">
<text class="label">载具号</text>
<view class="input-wrap">
<i class="left-icon icon icon-qr_code_2" style="font-size:36rpx"></i>
<input class="input" placeholder="请扫描或输入载具号" v-model="vehicleCode" @blur="resolveVehicle" />
</view>
</view>
<!-- 物料条码 -->
<view class="field">
<text class="label">物料条码</text>
<view class="input-wrap">
<i class="left-icon icon icon-qr_code_2" style="font-size:36rpx"></i>
<input class="input" placeholder="请扫描物料二维码" v-model="goodsCode" @blur="resolveCode" />
</view>
</view>
<!-- 操作按钮组 -->
<view class="button-row">
<button class="btn" @click="addGoods"><i class="icon icon-add"
style="margin-right:8rpx"></i>添加物料</button>
<button class="btn" @click="finish"><i class="icon icon-task_alt"
style="margin-right:8rpx"></i>码盘完成</button>
</view>
<!-- 列表统计 -->
<view class="list-header"><text>已添加物料 ({{ packageData.length }})</text></view>
<!-- 物料卡片列表:尽量还原 RN 的布局与字段 -->
<view class="list">
<view v-for="item in packageData" :key="item.id" class="card">
<view class="card-header">
<view class="card-header-left">
<text class="card-header-text">批次:{{ item.batch }}</text>
<text class="card-header-text">物料:{{ item.segment1 }}</text>
</view>
<view class="card-actions">
<button class="card-action-button" @click="editItem(item)"><i
class="icon icon-edit"></i></button>
<button class="card-action-button" @click="deleteItem(item.id)"><i
class="icon icon-delete"></i></button>
</view>
</view>
<view class="card-content">
<view class="card-row">
<view class="card-field">
<text class="card-label">物料编码</text>
<text class="card-value">{{ item.segment1 }}</text>
</view>
<view class="card-field">
<text class="card-label">物料ID</text>
<text class="card-value">{{ item.itemId }}</text>
</view>
</view>
<view class="card-row">
<view class="card-field">
<text class="card-label">数量</text>
<view class="editable-value">
<input class="num-input" type="number" v-model="item.quantity" />
</view>
</view>
<view class="card-field">
<text class="card-label">重量(kg)</text>
<view class="editable-value">
<input class="num-input" type="number" v-model="item.weight" />
</view>
</view>
</view>
<view class="card-row">
<view class="card-field">
<text class="card-label">产品数据</text>
<text class="card-value">{{ item.productData }}</text>
</view>
<view class="card-field">
<text class="card-label">区域/库位</text>
<text class="card-value">{{ item.area || '-' }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { DialogUtils } from '@/utils/dialog.js';
let nextId = 1
export default {
data() {
return {
vehicleCode: '',
goodsCode: '',
packageData: []
}
},
methods: {
back() {
uni.navigateBack()
},
resolveVehicle() {
const code = (this.vehicleCode || '').trim()
if (!code) return
if (code.length === 15) {
DialogUtils.showSuccessMessage('扫描成功', `车辆码: ${code}`)
} else {
DialogUtils.showErrorMessage('校验失败', '无效的车辆码长度')
}
},
resolveCode() {
const code = (this.goodsCode || '').trim()
if (!code) return
const parts = code.split(',')
if (![6, 7, 8].includes(parts.length)) {
DialogUtils.showWarningMessage('提示', '物料条码格式不正确')
return
}
const p = parts.slice(0, 6)
const item = {
id: String(nextId++),
segment1: p[0],
itemId: p[1],
batch: p[2],
quantity: p[3],
weight: p[4],
productData: p[5],
area: ''
}
if (this.packageData.some(x => x.batch === item.batch)) {
DialogUtils.showWarningMessage('重复', '该物料已在列表中')
} else {
this.packageData.push(item)
}
this.goodsCode = ''
},
addGoods() {
this.resolveCode()
},
deleteItem(id) {
this.packageData = this.packageData.filter(x => x.id !== id)
},
editItem(item) {
DialogUtils.toast('可编辑数量与重量')
},
finish() {
DialogUtils.toast('码盘完成')
}
}
}
</script>
<style scoped>
.header {
position: relative;
height: 120rpx;
padding: 0;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
display: flex;
align-items: center;
justify-content: center;
}
.container {
min-height: 100vh;
background: #F5F5F5;
}
.title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
}
.content {
padding: 24rpx;
}
.tip {
flex-direction: row;
display: flex;
align-items: center;
background: #f2fdff;
border-radius: 12rpx;
padding: 24rpx;
color: #333;
margin-bottom: 28rpx;
}
.tip-icon {
width: 40rpx;
height: 40rpx;
border-radius: 20rpx;
background: #e6f7ff;
text-align: center;
line-height: 40rpx;
margin-right: 12rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
}
.tip-text {
color: #333;
font-size: 26rpx;
}
.field {
margin-bottom: 20rpx;
}
.label {
color: #333;
font-size: 30rpx;
margin-bottom: 12rpx;
display: block;
}
.input-wrap {
height: 96rpx;
border-radius: 12rpx;
border: 1px solid #e6e6e6;
background: #fff;
padding: 0 20rpx;
display: flex;
align-items: center;
}
.left-icon {
color: #05DCEF;
font-size: 36rpx;
margin-right: 12rpx;
}
.input {
flex: 1;
height: 100%;
font-size: 30rpx;
}
.button-row {
display: flex;
gap: 24rpx;
margin: 24rpx 0;
}
.btn {
flex: 1;
height: 92rpx;
border: none;
color: #fff;
border-radius: 46rpx;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
font-size: 30rpx;
box-shadow: 0 8rpx 22rpx rgba(5, 220, 239, .25);
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.list-header {
margin-top: 8rpx;
color: #333;
font-size: 28rpx;
}
.card {
background: #fff;
border-radius: 12rpx;
padding: 0;
margin-top: 16rpx;
overflow: hidden;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, .06)
}
.card-header {
flex-direction: row;
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx;
border-bottom: 1px solid rgba(0, 0, 0, .08);
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
}
.card-header-left {
flex: 1
}
.card-header-text {
color: #fff;
font-size: 24rpx;
margin-right: 16rpx
}
.card-actions {
display: flex;
gap: 8rpx
}
.card-action-button {
width: 64rpx;
height: 64rpx;
border: none;
border-radius: 8rpx;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.card-content {
padding: 16rpx;
background: #fff
}
.card-row {
display: flex;
gap: 16rpx;
margin-bottom: 12rpx
}
.card-field {
flex: 1
}
.card-label {
color: #888;
font-size: 24rpx;
margin-bottom: 4rpx;
display: block
}
.card-value {
color: #333;
font-size: 28rpx
}
.editable-value {
display: flex;
align-items: center;
gap: 8rpx
}
.num-input {
width: 220rpx;
height: 64rpx;
border: 1px solid #e6e6e6;
border-radius: 8rpx;
padding: 0 12rpx;
font-size: 28rpx
}
.back {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 80rpx;
height: 64rpx;
line-height: 64rpx;
border: none;
color: #05DCEF;
background: #fff;
border-radius: 12rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
</style>