Files
klp-mono/apps/hand-factory/components/panels/code/apart.vue
砂糖 771f4ab006 feat(扫码功能): 重构扫码页面并新增分卷录入功能
- 重构扫码页面结构,采用标签页形式组织功能模块
- 新增分卷录入功能组件(apart.vue)和基础录入功能组件(typing.vue)
- 新增物料选择组件(klp-product-select)和标签页组件(klp-tabs)
- 新增WMS相关API接口(product.js, warehouse.js等)
- 更新uni-data-select组件支持多选和插槽功能
- 更新uni-icons和uni-load-more组件版本及功能
- 移除冗余样式和代码,优化现有组件结构

refactor(组件): 优化acidity.vue组件使用新的标签页组件
style: 移除冗余CSS样式代码
chore: 更新多个uni_modules组件的package.json版本号
2025-10-28 18:11:46 +08:00

390 lines
9.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">
<!-- 扫码按钮 -->
<button class="scan-btn" @click="handleScan">点击扫码</button>
<!-- 表单区域扫码后显示 -->
<uni-form ref="form" v-model="form" :rules="rules" v-if="form.coilId" label-width="160rpx">
<!-- 分卷数量控制 -->
<view class="coil-control">
<text class="control-text">分卷数量{{ form.newCoils.length }} </text>
<button class="add-btn" @click="addCoil">+ 添加卷</button>
</view>
<!-- 动态渲染多卷表单 -->
<view v-for="(coil, index) in form.newCoils" :key="index" class="coil-group">
<!-- 卷标识 -->
<view class="coil-title">
<text> {{ index + 1 }}</text>
<!-- 仅当卷数量大于1时显示删除按钮 -->
<button
class="delete-btn"
@click="deleteCoil(index)"
v-if="form.newCoils.length > 1"
>
删除
</button>
</view>
<!-- 卷信息表单项 -->
<uni-form-item :label="`物料类型(${index + 1})`" :prop="`newCoils.${index}.itemType`">
<uni-data-checkbox
v-model="coil.itemType"
:localdata="[{ text: '原料', value: 'raw_material' }, { text: '产品', value: 'product' }]"
/>
</uni-form-item>
<uni-form-item :label="`原料/产品(${index + 1})`" :prop="`newCoils.${index}.itemId`">
<klp-product-select
:item-type="coil.itemType"
v-model="coil.itemId"
></klp-product-select>
</uni-form-item>
<uni-form-item :label="`所属班组(${index + 1})`" :prop="`newCoils.${index}.team`">
<input
v-model="coil.team"
placeholder="请输入班组名称"
class="input-control"
/>
</uni-form-item>
<uni-form-item :label="`当前卷号(${index + 1})`" :prop="`newCoils.${index}.currentCoilNo`">
<input
v-model="coil.currentCoilNo"
placeholder="请输入卷号信息"
class="input-control"
/>
</uni-form-item>
<uni-form-item :label="`毛重(kg)(${index + 1})`" :prop="`newCoils.${index}.grossWeight`">
<input
v-model="coil.grossWeight"
type="number"
placeholder="请输入毛重"
class="input-control"
/>
</uni-form-item>
<uni-form-item :label="`净重(kg)(${index + 1})`" :prop="`newCoils.${index}.netWeight`">
<input
v-model="coil.netWeight"
type="number"
placeholder="请输入净重"
class="input-control"
/>
</uni-form-item>
<!-- 卷分隔线 -->
<view class="coil-divider" v-if="index !== form.newCoils.length - 1"></view>
</view>
<!-- 确认按钮 -->
<uni-form-item>
<button class="confirm-btn" @click="handleConfirm">
确认信息并录入系统
</button>
</uni-form-item>
</uni-form>
</view>
</template>
<script>
import { getGenerateRecord } from '@/api/wms/code.js'
import { updateMaterialCoil } from '@/api/wms/coil.js'
export default {
data() {
return {
form: {
coilId: undefined,
hasMergeSplit: 1, // 1表示分卷
newCoils: [
{
itemType: 'raw_material',
itemId: undefined,
team: undefined,
currentCoilNo: undefined,
warehouseId: undefined,
grossWeight: undefined,
netWeight: undefined,
}
]
},
// 表单验证规则(适配数组形式的多卷数据)
rules: {
// 基础验证:必须扫码
coilId: {
required: true,
message: '请先扫码获取卷ID',
trigger: ['change', 'blur']
},
// 多卷验证规则通过newCoils[index].xxx形式匹配
'newCoils.*.itemType': {
required: true,
message: '请选择物料类型',
trigger: 'change'
},
'newCoils.*.itemId': {
required: true,
message: '请选择对应原料/产品',
trigger: 'change'
},
'newCoils.*.team': {
required: true,
message: '请输入所属班组',
trigger: 'blur'
},
'newCoils.*.currentCoilNo': {
required: true,
message: '请输入当前卷号',
trigger: 'blur'
},
'newCoils.*.grossWeight': {
required: true,
message: '请输入毛重',
trigger: 'blur',
type: 'number'
},
'newCoils.*.netWeight': {
required: true,
message: '请输入净重',
trigger: 'blur',
type: 'number'
}
}
}
},
methods: {
// 处理扫码逻辑
handleScan() {
uni.scanCode({
success: (res) => {
console.log('扫码结果:', res.result)
getGenerateRecord(res.result).then(res => {
const result = JSON.parse(res.data.content);
this.$set(this.form, 'coilId', result.coil_id);
this.$refs.form?.validateField('coilId'); // 验证扫码字段
console.log('扫码获取的卷信息:', result);
}).catch(err => {
uni.showToast({
title: '扫码信息解析失败',
icon: 'none'
})
})
},
fail: (err) => {
console.error('扫码失败:', err)
uni.showToast({
title: '扫码失败,请重试',
icon: 'none'
})
}
})
},
// 添加新卷
addCoil() {
// 初始化新卷数据(与初始卷结构一致)
const newCoil = {
itemType: 'raw_material',
itemId: undefined,
team: undefined,
currentCoilNo: undefined,
warehouseId: undefined,
grossWeight: undefined,
netWeight: undefined,
};
this.form.newCoils.push(newCoil);
// 清除表单验证状态(避免新增项显示错误)
this.$refs.form?.clearValidate();
},
// 删除指定卷
deleteCoil(index) {
uni.showModal({
title: '确认删除',
content: `确定要删除第${index + 1}卷吗?`,
success: (res) => {
if (res.confirm) {
this.form.newCoils.splice(index, 1);
// 清除表单验证状态
this.$refs.form?.clearValidate();
}
}
})
},
// 处理确认提交
handleConfirm() {
this.$refs.form.validate(valid => {
if (valid) {
// 提交的数据包含原始卷ID + 分卷标识 + 所有新卷信息
updateMaterialCoil(this.form).then(res => {
uni.showToast({
title: '分卷信息录入成功',
icon: 'success'
})
// 重置表单
this.resetForm();
}).catch(err => {
console.error('提交失败:', err)
uni.showToast({
title: '录入失败,请重试',
icon: 'none'
})
})
} else {
// 验证失败时滚动到第一个错误项
this.scrollToErrorField();
return false;
}
})
},
// 重置表单
resetForm() {
this.form = {
coilId: undefined,
hasMergeSplit: 1,
newCoils: [
{
itemType: 'raw_material',
itemId: undefined,
team: undefined,
currentCoilNo: undefined,
warehouseId: undefined,
grossWeight: undefined,
netWeight: undefined,
}
]
};
this.$refs.form?.resetFields();
},
// 滚动到第一个错误的表单项
scrollToErrorField() {
const errorEl = document.querySelector('.uni-form-item--error');
if (errorEl) {
errorEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}
}
}
</script>
<style>
.container {
padding: 30rpx 20rpx;
}
/* 扫码按钮样式 */
.scan-btn {
width: 600rpx;
height: 100rpx;
line-height: 100rpx;
font-size: 36rpx;
background-color: #007aff;
color: white;
border-radius: 50rpx;
margin: 0 auto 60rpx;
display: block;
box-shadow: 0 4rpx 10rpx rgba(0, 122, 255, 0.3);
}
/* 分卷控制区 */
.coil-control {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 0 40rpx 20rpx;
}
.control-text {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
.add-btn {
width: 180rpx;
height: 60rpx;
line-height: 60rpx;
font-size: 28rpx;
background-color: #4cd964;
color: white;
border-radius: 8rpx;
}
/* 单卷表单组样式 */
.coil-group {
padding: 20rpx;
margin-bottom: 20rpx;
background-color: #f9f9f9;
border-radius: 10rpx;
}
/* 卷标题 */
.coil-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 10rpx;
border-bottom: 1px solid #eee;
}
.coil-title text {
font-size: 34rpx;
color: #007aff;
font-weight: bold;
}
/* 删除按钮 */
.delete-btn {
width: 120rpx;
height: 50rpx;
line-height: 50rpx;
font-size: 26rpx;
background-color: #ff3b30;
color: white;
border-radius: 8rpx;
}
/* 输入框样式 */
.input-control {
width: 100%;
height: 80rpx;
line-height: 80rpx;
border: 1px solid #eee;
border-radius: 8rpx;
padding: 0 20rpx;
box-sizing: border-box;
font-size: 32rpx;
}
/* 确认按钮样式 */
.confirm-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
font-size: 32rpx;
background-color: #00b42a;
color: white;
border-radius: 10rpx;
margin-top: 30rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 180, 42, 0.2);
}
/* 表单项间距 */
.uni-form-item {
margin-bottom: 25rpx !important;
}
/* 卷分隔线 */
.coil-divider {
height: 1px;
background-color: #eee;
margin: 30rpx 0;
}
</style>