<template>
|
<view class="sockpage">
|
<view class="column">
|
<view class="form-card">
|
<view class="form-row">
|
<view class="label">
|
<text class="required">*</text>托盘编码:
|
</view>
|
<view class="picker-wrap" hover-class="picker-hover">
|
<view class="input-box">
|
<input
|
id="pdacode"
|
type="text"
|
v-model="barcode"
|
placeholder="请扫码"
|
/>
|
</view>
|
</view>
|
</view>
|
</view>
|
|
<!-- 箱型栏(对应后端boxType) -->
|
<view class="form-card">
|
<view class="form-row">
|
<view class="label">
|
<text class="required">*</text>箱 型:
|
</view>
|
<view class="picker-wrap" hover-class="picker-hover">
|
<picker @change="modePickerChange" :value="index_mode" :range="mode">
|
<view class="input-box">
|
<text class="input-placeholder" v-if="!mode.length || !mode[index_mode]">请选择箱型</text>
|
<text class="input-value" v-else>{{mode[index_mode]}}</text>
|
</view>
|
</picker>
|
</view>
|
</view>
|
</view>
|
|
<view class="form-card">
|
<view class="form-row">
|
<view class="label">
|
<text class="required">*</text>物料码:
|
</view>
|
<view class="picker-wrap" hover-class="picker-hover">
|
<view class="textareainput">
|
<textarea
|
style="max-height: 15px;overflow: hidden;"
|
id="pdacode"
|
type="text"
|
v-model="thingCode"
|
placeholder="请扫码"
|
@input="handleBarcodeInput"
|
/>
|
</view>
|
</view>
|
</view>
|
</view>
|
<!-- 物料信息输入栏(对应后端MatList) -->
|
<view class="form-card material-card">
|
<view class="card-title">物料信息</view>
|
<view class="material-grid">
|
<view class="material-item">
|
<text class="material-label"><text class="required">*</text>卷号:</text>
|
<input
|
class="material-input"
|
type="text"
|
v-model="matList.model"
|
placeholder="请扫码或输入卷号"
|
placeholder-class="input-placeholder"
|
ref="modelInput"
|
/>
|
</view>
|
<view class="material-item">
|
<text class="material-label"><text class="required">*</text>箱号:</text>
|
<input
|
class="material-input"
|
type="text"
|
v-model="matList.batch"
|
placeholder="请扫码或输入箱号"
|
placeholder-class="input-placeholder"
|
ref="batchInput"
|
/>
|
</view>
|
<view class="material-item">
|
<text class="material-label">规格:</text>
|
<input
|
class="material-input"
|
type="text"
|
v-model="matList.matnr"
|
placeholder="请输入规格"
|
placeholder-class="input-placeholder"
|
/>
|
</view>
|
<view class="material-item">
|
<text class="material-label">长度:</text>
|
<input
|
class="material-input"
|
type="number"
|
v-model="matList.rollExtent"
|
placeholder="请输入长度"
|
placeholder-class="input-placeholder"
|
/>
|
</view>
|
<view class="material-item">
|
<text class="material-label">净重:</text>
|
<input
|
class="material-input"
|
type="number"
|
v-model="matList.weight"
|
placeholder="请输入净重"
|
placeholder-class="input-placeholder"
|
/>
|
</view>
|
<view class="material-item">
|
<text class="material-label">毛重:</text>
|
<input
|
class="material-input"
|
type="number"
|
v-model="matList.roughWeight"
|
placeholder="请输入毛重"
|
placeholder-class="input-placeholder"
|
/>
|
</view>
|
<view class="material-item">
|
<text class="material-label">接头:</text>
|
<input
|
class="material-input"
|
type="number"
|
v-model="matList.joint"
|
placeholder="请输入接头数"
|
placeholder-class="input-placeholder"
|
/>
|
</view>
|
</view>
|
</view>
|
<!-- 操作按钮组 -->
|
<view class="btn-group">
|
<button class="operate-btn submit-btn" @click="submit">成品入库</button>
|
</view>
|
</view>
|
</view>
|
</template>
|
<script>
|
export default {
|
onLoad(options){
|
this.checkLoginStatus();
|
this.POSTinfo();
|
},
|
|
onShow() {
|
this.checkLoginStatus();
|
},
|
|
onHide() {
|
if (this.scanTimeout) {
|
clearTimeout(this.scanTimeout);
|
this.scanTimeout = null;
|
}
|
},
|
|
data() {
|
return {
|
thingCode:'',
|
focusState: false,
|
baseUrl: '',
|
token: '',
|
barcode: '',
|
palletizingNo: '1',
|
boxType: '',
|
matList: {
|
matnr: '',
|
maktx: '',
|
batch: '',
|
model: '',
|
position: '1',
|
weight: '',
|
roughWeight: '',
|
anfme: 1.0,
|
rollExtent: '',
|
joint: 0,
|
cutting: 2,
|
qualified: 0,
|
modelFront: '',
|
batchFront: ''
|
},
|
mode: [],
|
index_mode: 0,
|
submitData: {},
|
scanBuffer: '',
|
scanTimeout: null,
|
lastScanTime: 0,
|
isProcessingScan: false
|
}
|
},
|
methods: {
|
// 检查登录状态
|
checkLoginStatus() {
|
this.token = uni.getStorageSync('token');
|
this.baseUrl = uni.getStorageSync('baseUrl');
|
|
if (!this.token || !this.baseUrl) {
|
uni.showModal({
|
title: '提示',
|
content: '请先登录',
|
showCancel: false,
|
success: (res) => {
|
if (res.confirm) {
|
uni.navigateTo({
|
url: '/pages/login/login'
|
});
|
}
|
}
|
});
|
return false;
|
}
|
return true;
|
},
|
|
// 获取箱型数据
|
POSTinfo(){
|
if (!this.checkLoginStatus()) return;
|
|
uni.showLoading({
|
title: '加载中...'
|
});
|
|
uni.request({
|
url: this.baseUrl + '/mobile/box/type/complete/auth/v2',
|
method: 'POST',
|
header: {
|
'Content-Type': 'application/json',
|
'Authorization': 'Bearer ' + this.token
|
},
|
success: (res) => {
|
uni.hideLoading();
|
console.log('箱型接口返回:', res.data);
|
|
if (res.data && res.data.code === 200) {
|
if (Array.isArray(res.data.data)) {
|
// 尝试多种可能的字段名
|
this.mode = res.data.data
|
.map(item => item.boxSpecs || item.boxType || item.typeName || item.name || '')
|
.filter(item => item && item.trim() !== '');
|
|
console.log('提取的箱型列表:', this.mode);
|
|
if (this.mode.length === 0) {
|
uni.showToast({
|
title: '无可用箱型',
|
icon: 'none'
|
});
|
}
|
} else {
|
console.warn('返回数据格式不符,不是数组:', res.data.data);
|
uni.showToast({
|
title: '数据格式错误',
|
icon: 'none'
|
});
|
}
|
} else {
|
uni.showToast({
|
title: res.data?.message || '获取箱型失败',
|
icon: 'none'
|
});
|
}
|
},
|
fail: (err) => {
|
uni.hideLoading();
|
console.error('获取箱型失败:', err);
|
uni.showToast({
|
title: '网络错误',
|
icon: 'none'
|
});
|
}
|
});
|
},
|
modePickerChange(e) {
|
this.index_mode = e.detail.value;
|
this.boxType = this.mode[this.index_mode];
|
console.log('选择的箱型:', this.boxType);
|
},
|
|
handleBarcodeInput(e) {
|
// 在uni-app中,textarea的input事件可能是e.detail.value
|
const value = e.detail ? e.detail.value : e.target.value;
|
this.thingCode = value;
|
this.parseBarcodeContent(value);
|
},
|
|
parseBarcodeContent(content) {
|
if (!content) return;
|
|
// 按行分割内容
|
const lines = content.split('\n').filter(line => line.trim() !== '');
|
|
console.log('解析的行数据:', lines);
|
|
// 根据你提供的样例格式解析
|
// 格式为:
|
// 2511080305A22B6 (卷号)
|
// Y251113764 (箱号)
|
// 5μm×1050mm (规格)
|
// 8700 m (长度)
|
// 418.0 kg (净重)
|
// 441.0 kg (毛重)
|
// 0 个 (接头)
|
|
if (lines.length >= 7) {
|
// 卷号 (第一行)
|
this.matList.model = lines[0].trim();
|
|
// 箱号 (第二行)
|
this.matList.batch = lines[1].trim();
|
|
// 规格 (第三行)
|
this.matList.matnr = lines[2].trim();
|
|
// 长度 (第四行) - 提取数字部分
|
const lengthMatch = lines[3].match(/([\d.]+)/);
|
if (lengthMatch) {
|
this.matList.rollExtent = lengthMatch[1];
|
}
|
|
// 净重 (第五行) - 提取数字部分
|
const weightMatch = lines[4].match(/([\d.]+)/);
|
if (weightMatch) {
|
this.matList.weight = weightMatch[1];
|
}
|
|
// 毛重 (第六行) - 提取数字部分
|
const roughWeightMatch = lines[5].match(/([\d.]+)/);
|
if (roughWeightMatch) {
|
this.matList.roughWeight = roughWeightMatch[1];
|
}
|
|
// 接头 (第七行) - 提取数字部分
|
const jointMatch = lines[6].match(/([\d.]+)/);
|
if (jointMatch) {
|
this.matList.joint = jointMatch[1];
|
}
|
|
console.log('解析后的数据:', this.matList);
|
} else if (lines.length > 0) {
|
// 如果行数不够,也可以尝试智能匹配
|
this.autoMatchFields(lines);
|
}
|
},
|
|
// 智能匹配方法,用于处理可能的不规则数据
|
autoMatchFields(lines) {
|
lines.forEach((line, index) => {
|
line = line.trim();
|
|
// 根据内容特征匹配
|
if (index === 0 && !this.matList.model) {
|
// 假设第一行总是卷号
|
this.matList.model = line;
|
} else if (index === 1 && !this.matList.batch) {
|
// 假设第二行总是箱号
|
this.matList.batch = line;
|
} else if (line.includes('μm') || line.includes('mm') || line.includes('×')) {
|
// 包含规格特征的
|
this.matList.matnr = line;
|
} else if (line.includes('m') && line.match(/[\d.]+ m/)) {
|
// 长度特征
|
const match = line.match(/([\d.]+)/);
|
if (match) this.matList.rollExtent = match[1];
|
} else if (line.includes('kg') && line.match(/[\d.]+ kg/)) {
|
// 重量特征,需要区分净重和毛重
|
const match = line.match(/([\d.]+)/);
|
if (match) {
|
const weightValue = match[1];
|
if (!this.matList.weight) {
|
this.matList.weight = weightValue;
|
} else if (!this.matList.roughWeight) {
|
this.matList.roughWeight = weightValue;
|
}
|
}
|
} else if (line.includes('个') && line.match(/[\d.]+ 个/)) {
|
// 接头特征
|
const match = line.match(/([\d.]+)/);
|
if (match) this.matList.joint = match[1];
|
}
|
});
|
},
|
// 重置表单
|
resetForm() {
|
this.barcode = '';
|
this.boxType = '';
|
this.index_mode = 0;
|
this.matList = {
|
matnr: '',
|
maktx: '',
|
batch: '',
|
model: '',
|
position: '1',
|
weight: '',
|
roughWeight: '',
|
anfme: 1.0,
|
rollExtent: '',
|
joint: 0,
|
cutting: 2,
|
qualified: 0,
|
modelFront: '',
|
batchFront: ''
|
};
|
this.scanBuffer = '';
|
this.focusState = false;
|
},
|
|
// 提交数据
|
submit() {
|
// 1. 验证登录
|
if (!this.checkLoginStatus()) return;
|
|
// 2. 验证必填项
|
if (!this.barcode) {
|
uni.showToast({title: '请扫描托盘编码', icon: 'none'});
|
return;
|
}
|
|
if (!this.boxType) {
|
uni.showToast({title: '请选择箱型', icon: 'none'});
|
return;
|
}
|
|
if (!this.matList.model) {
|
uni.showToast({title: '请填写卷号', icon: 'none'});
|
return;
|
}
|
|
if (!this.matList.batch) {
|
uni.showToast({title: '请填写箱号', icon: 'none'});
|
return;
|
}
|
|
// 3. 准备数据
|
const matItem = {
|
...this.matList,
|
weight: this.matList.weight ? Number(this.matList.weight) : null,
|
roughWeight: this.matList.roughWeight ? Number(this.matList.roughWeight) : null,
|
rollExtent: this.matList.rollExtent ? Number(this.matList.rollExtent) : null,
|
joint: this.matList.joint ? Number(this.matList.joint) : 0
|
};
|
|
const submitData = {
|
barcode: this.barcode,
|
palletizingNo: this.palletizingNo,
|
boxType: this.boxType,
|
matList: [matItem]
|
};
|
|
console.log('提交数据:', submitData);
|
|
// 4. 发送请求
|
uni.showLoading({
|
title: '提交中...',
|
mask: true
|
});
|
|
uni.request({
|
url: this.baseUrl + '/mobile/truss/comd/auth/v2',
|
method: 'POST',
|
header: {
|
'Content-Type': 'application/json',
|
'Authorization': 'Bearer ' + this.token
|
},
|
data: submitData,
|
success: (res) => {
|
uni.hideLoading();
|
console.log('提交返回:', res.data);
|
|
if (res.data.code === 200) {
|
uni.showToast({
|
title: '提交成功',
|
icon: 'success',
|
duration: 2000
|
});
|
|
setTimeout(() => {
|
this.resetForm();
|
}, 1500);
|
} else {
|
uni.showToast({
|
title: res.data.message || '提交失败',
|
icon: 'none'
|
});
|
}
|
},
|
fail: (err) => {
|
uni.hideLoading();
|
console.error('提交失败:', err);
|
uni.showToast({
|
title: '网络错误',
|
icon: 'none'
|
});
|
}
|
});
|
},
|
}
|
}
|
</script>
|
|
<style scoped>
|
/* 全局样式 */
|
.sockpage {
|
background-color: #f5f7fa;
|
padding: 24rpx;
|
min-height: 100vh;
|
}
|
|
/* 表单列容器 */
|
.column {
|
display: flex;
|
flex-direction: column;
|
gap: 24rpx;
|
}
|
|
/* 表单卡片 */
|
.form-card {
|
background: #ffffff;
|
border-radius: 12rpx;
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
padding: 24rpx;
|
transition: all 0.2s ease;
|
}
|
.textareainput{
|
width: 60%;
|
height: 15px;
|
font-size: 28rpx;
|
padding: 16rpx 12rpx;
|
border: 1rpx solid #e5e7eb;
|
border-radius: 8rpx;
|
transition: border-color 0.2s ease;
|
}
|
/* 物料信息卡片特殊样式 */
|
.material-card {
|
padding: 0;
|
}
|
.card-title {
|
font-size: 30rpx;
|
font-weight: 500;
|
color: #1f2937;
|
padding: 24rpx 24rpx 16rpx;
|
border-bottom: 1rpx solid #f0f0f0;
|
}
|
|
/* 表单行 */
|
.form-row {
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
gap: 16rpx;
|
}
|
|
/* 标签样式 */
|
.label {
|
font-size: 28rpx;
|
color: #374151;
|
font-weight: 500;
|
min-width: 140rpx;
|
}
|
|
/* 必填项标红 */
|
.required {
|
color: #ef4444;
|
margin-right: 4rpx;
|
}
|
|
/* 选择器容器 */
|
.picker-wrap {
|
flex: 1;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
}
|
|
/* 选择器hover态 */
|
.picker-hover {
|
background-color: #f9fafb;
|
border-radius: 8rpx;
|
}
|
|
/* 输入框容器 */
|
.input-box {
|
flex: 1;
|
font-size: 28rpx;
|
padding: 16rpx 12rpx;
|
border: 1rpx solid #e5e7eb;
|
border-radius: 8rpx;
|
transition: border-color 0.2s ease;
|
}
|
|
.input-box:focus-within {
|
border-color: #f97316;
|
}
|
|
/* 输入值样式 */
|
.input-value {
|
color: #1f2937;
|
}
|
|
/* 扫码图标 */
|
.scan-icon {
|
font-size: 24rpx;
|
margin-left: 8rpx;
|
color: #6b7280;
|
}
|
|
/* 物料信息网格布局 */
|
.material-grid {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 20rpx;
|
padding: 24rpx;
|
}
|
|
/* 物料信息项 */
|
.material-item {
|
display: flex;
|
flex-direction: column;
|
gap: 8rpx;
|
}
|
|
/* 物料标签 */
|
.material-label {
|
font-size: 26rpx;
|
color: #4b5563;
|
}
|
|
/* 物料输入框 */
|
.material-input {
|
width: 45%;
|
font-size: 28rpx;
|
color: #1f2937;
|
padding: 16rpx 12rpx;
|
border: 1rpx solid #e5e7eb;
|
border-radius: 8rpx;
|
background-color: #ffffff;
|
transition: border-color 0.2s ease;
|
}
|
|
.material-input:focus {
|
border-color: #f97316;
|
outline: none;
|
}
|
|
/* 按钮组 */
|
.btn-group {
|
display: flex;
|
gap: 20rpx;
|
justify-content: center;
|
margin-top: 16rpx;
|
padding: 8rpx 0;
|
}
|
|
/* 操作按钮通用样式 */
|
.operate-btn {
|
flex: 1;
|
max-width: 200rpx;
|
height: 80rpx;
|
line-height: 80rpx;
|
font-size: 28rpx;
|
font-weight: 500;
|
border-radius: 12rpx;
|
border: none;
|
transition: all 0.2s ease;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
/* 扫码按钮 */
|
.scan-btn {
|
background-color: #3b82f6;
|
color: #ffffff;
|
}
|
|
.scan-btn:active {
|
background-color: #2563eb;
|
transform: scale(0.98);
|
}
|
|
/* 提交按钮 */
|
.submit-btn {
|
background-color: #f97316;
|
color: #ffffff;
|
}
|
|
.submit-btn:active {
|
background-color: #ea580c;
|
transform: scale(0.98);
|
}
|
|
/* 适配小屏幕 */
|
@media (max-width: 375px) {
|
.material-grid {
|
grid-template-columns: 1fr;
|
}
|
|
.operate-btn {
|
max-width: 160rpx;
|
height: 72rpx;
|
line-height: 72rpx;
|
font-size: 26rpx;
|
}
|
}
|
</style>
|