<template>
|
<view class="container">
|
<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
|
<block slot="backText">返回</block>
|
<block slot="content">上料</block>
|
</cu-custom>
|
|
<!-- 骨架屏 -->
|
<view v-if="loading" class="skeleton-container">
|
<view class="skeleton-group">
|
<view class="skeleton-divider"></view>
|
<view class="skeleton-item">
|
<view class="skeleton-label"></view>
|
<view class="skeleton-input"></view>
|
</view>
|
<view class="skeleton-item">
|
<view class="skeleton-label"></view>
|
<view class="skeleton-input"></view>
|
</view>
|
<view class="skeleton-item">
|
<view class="skeleton-label"></view>
|
<view class="skeleton-input"></view>
|
</view>
|
<view class="skeleton-item">
|
<view class="skeleton-label"></view>
|
<view class="skeleton-input"></view>
|
</view>
|
</view>
|
<view class="skeleton-button"></view>
|
</view>
|
|
<!-- 实际内容 -->
|
<view v-else class="container">
|
<uni-forms ref="form" :modelValue="formData" :rules="formRules" validate-trigger="bind"
|
err-show-type="undertext">
|
<uni-group top="1">
|
<view class="divider"><text>上料信息</text></view>
|
<uni-forms-item :required="true" :label-width="80" name="workOrderNumber" label="物料编码:">
|
<uni-easyinput v-model="formData.workOrderNumber" :disabled="isScan" placeholder="请输入/扫码识别"
|
@blur="handleInputComplete" />
|
</uni-forms-item>
|
<uni-forms-item :required="true" :label-width="80" name="materialCode" label="物料名称:">
|
<uni-easyinput v-model="formData.materialCode" placeholder="请输入/扫码识别" />
|
</uni-forms-item>
|
|
<uni-forms-item :required="true" :label-width="80" name="materialDescription" label="批次号 :">
|
<uni-easyinput v-model="formData.materialDescription" placeholder="请输入/扫码识别" />
|
</uni-forms-item>
|
<uni-forms-item :required="true" :label-width="80" name="plannedQuantity" label="数量:">
|
<uni-easyinput v-model="formData.plannedQuantity" placeholder="请输入/扫码识别" />
|
</uni-forms-item>
|
<uni-forms-item :required="true" :label-width="80" name="plannedQuantity" label="尺寸:">
|
<uni-easyinput v-model="formData.plannedQuantity" placeholder="请输入/扫码识别" />
|
</uni-forms-item>
|
|
|
|
</uni-group>
|
</uni-forms>
|
|
<view class="padding flex flex-direction">
|
<view class="flex-sub bg-blue padding-sm margin-xl radius text-sm text-center text-white"
|
@click.stop="ProductionTask()" hover-class="is-hover">确定</view>
|
</view>
|
</view>
|
|
<pdaScanVue></pdaScanVue>
|
</view>
|
</template>
|
|
<script>
|
import pdaScanVue from "@/components/mes/pdaScan.vue";
|
import QRCode from 'qrcode';
|
|
export default {
|
components: {
|
pdaScanVue
|
},
|
data() {
|
return {
|
isScan: false,
|
loading: true,
|
isShow: false,
|
isSubmitting: false, // 防重复提交
|
SpareList: [{
|
text: "是",
|
value: 1
|
},
|
{
|
text: "否",
|
value: 0
|
}
|
],
|
scrollLeft: 0,
|
formData: {
|
workOrderNumber: '',
|
materialCode: '',
|
materialDescription: '',
|
plannedQuantity: '',
|
},
|
formRules: {
|
workOrderNumber: [{
|
required: true,
|
message: '请输入物料编码',
|
trigger: 'blur'
|
},
|
{
|
pattern: /^[A-Za-z0-9]{6,20}$/, // 示例:仅允许6-20位字母/数字
|
message: '物料编码需为6-20位字母或数字',
|
trigger: 'blur'
|
}
|
]
|
},
|
NavBarColor: this.NavBarColor,
|
url: {
|
upload: "/eam/sysFiles/batch_upload",
|
stallList: "/eam/eamRepairOrder/queryById",
|
getEquipmentList: 'eam/equipment/list',
|
approval: '/eam/eamRepairOrder/perform'
|
},
|
styles: {
|
color: '#2979FF',
|
borderColor: '#2979FF'
|
},
|
msg1Count: 0
|
}
|
},
|
computed: {
|
top() {
|
return this.CustomBar * 2 + 160
|
},
|
style() {
|
var StatusBar = this.StatusBar;
|
var CustomBar = this.CustomBar;
|
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
|
return style
|
},
|
},
|
onShow() {
|
var that = this
|
uni.$off('scancodedate') // 每次进来先 移除全局自定义事件监听器
|
uni.$on('scancodedate', function(data) {
|
that.isScan = true
|
console.log(data.code)
|
let code = data.code;
|
/**
|
* 获取物料类型
|
*/
|
that.sacanHandel(code)
|
})
|
|
},
|
created() {
|
this.loading = false;
|
},
|
methods: {
|
sacanHandel(code) {
|
this.$http.get(this.url.approval).then(res => {
|
if (res.data.success) {
|
console.log("res", res.data)
|
/**
|
* 判断物料类型
|
* 给from表单赋值
|
* 保存库存信息库存id
|
* 根据物料类型是否显示特殊属性
|
*/
|
}
|
}).catch(() => {
|
uni.showToast({
|
title: '网络异常,请稍后再试',
|
icon: 'none'
|
});
|
})
|
},
|
// 物料编码输入完成(失去焦点)触发的逻辑
|
handleInputComplete() {
|
// 1. 强制去除输入值前后所有空格(包括多个空格、全角空格)
|
const rawValue = this.formData.workOrderNumber || '';
|
const materialCode = rawValue.replace(/\s+/g, ''); // 用正则去除所有空白字符(空格、换行等)
|
|
// 2. 无效值拦截:去空格后为空 → 直接提示,不触发后续逻辑
|
if (!materialCode) {
|
uni.showToast({
|
title: '请输入有效的物料编码(不能为空)',
|
icon: 'none',
|
duration: 1500
|
});
|
// 可选:清空输入框的纯空格内容,避免用户误以为输入有效
|
this.formData.workOrderNumber = '';
|
return; // 终止后续流程
|
}
|
|
// 3. 无效值已排除,更新表单值为去空格后的有效内容(保持表单显示整洁)
|
this.formData.workOrderNumber = materialCode;
|
console.log('当前有效物料编码:', materialCode);
|
|
// 4. 执行原有校验(格式是否符合6-20位字母/数字)
|
this.$refs.form.validateField('workOrderNumber', (errorMsg, isValid) => {
|
console.log('格式校验结果:', isValid ? '通过' : '失败', '错误信息:', errorMsg);
|
|
if (isValid) {
|
// 5. 校验通过 → 触发接口查询
|
this.requestMaterialInfo(materialCode);
|
} else if (errorMsg) {
|
// 格式校验失败 → 提示具体错误(如“需6-20位字母/数字”)
|
uni.showToast({
|
title: errorMsg,
|
icon: 'none',
|
duration: 1500
|
});
|
}
|
});
|
},
|
requestMaterialInfo(materialCode) {
|
console.log("我执行了")
|
uni.showLoading({
|
title: '查询中...'
|
})
|
this.$http.get(this.url.approval).then(res => {
|
if (res.data.success) {
|
console.log("res", res.data)
|
/**
|
* 判断物料类型
|
* 给from表单赋值
|
* 保存库存信息库存id
|
* 根据物料类型是否显示特殊属性
|
*/
|
}
|
}).catch(() => {
|
uni.hideLoading();
|
uni.showToast({
|
title: '网络异常,请稍后再试',
|
icon: 'none'
|
});
|
})
|
},
|
async ProductionTask() {
|
// 防止重复提交
|
if (this.isSubmitting) {
|
uni.showToast({
|
icon: "none",
|
title: "正在提交中,请勿重复点击",
|
duration: 2000
|
});
|
return;
|
}
|
|
uni.showLoading({
|
mask: true,
|
title: "提交中..."
|
});
|
|
try {
|
this.isSubmitting = true;
|
// 发送报工请求
|
const response = await this.$http.post(this.url.approval, {
|
workOrderNumber: this.formData.workOrderNumber,
|
materialCode: this.formData.materialCode,
|
|
plannedQuantity: this.formData.plannedQuantity,
|
inspectionOrderNumber: this.formData.inspectionOrderNumber,
|
|
});
|
|
if (response.data.success) {
|
uni.showToast({
|
icon: "success",
|
title: '提交成功',
|
duration: 2000
|
});
|
|
// 延迟跳转
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
this.$Router.replaceAll({
|
name: 'qualityInspection'
|
});
|
} else {
|
uni.showModal({
|
title: "提交失败",
|
content: response.data.message || "服务器处理失败,请稍后重试",
|
confirmText: '确定',
|
showCancel: false,
|
icon: "none"
|
});
|
}
|
} catch (error) {
|
// 错误处理
|
if (error.errMsg) {
|
uni.showToast({
|
icon: "none",
|
title: error,
|
duration: 2000
|
});
|
} else {
|
console.error("请求失败:", error);
|
let errorMessage = "网络请求失败";
|
if (error.errMsg) {
|
if (error.errMsg.includes("timeout")) {
|
errorMessage = "请求超时,请检查网络连接";
|
} else if (error.errMsg.includes("fail")) {
|
errorMessage = "网络连接失败,请检查网络设置";
|
}
|
}
|
uni.showToast({
|
icon: "none",
|
title: errorMessage,
|
duration: 3000
|
});
|
}
|
} finally {
|
this.isSubmitting = false;
|
uni.hideLoading();
|
}
|
},
|
}
|
}
|
</script>
|
|
<style>
|
.is-hover {
|
color: rgba(255, 255, 255, 0.6);
|
background-color: #55aaff;
|
border-color: #55aaff;
|
}
|
|
.divider {
|
display: flex;
|
font-weight: bold;
|
align-items: center;
|
text-align: center;
|
color: #1E90FF;
|
font-size: 24rpx;
|
margin: 20px 0;
|
}
|
|
.divider::before,
|
.divider::after {
|
content: '';
|
flex: 1;
|
border-bottom: 1px solid gray;
|
margin: 0 16px;
|
}
|
|
.divider text {
|
white-space: nowrap;
|
}
|
|
.content {
|
margin-top: 5px;
|
}
|
|
.content scroll-view {
|
scrollIndicator: "none"
|
}
|
|
.popupView {
|
margin-top: 45px;
|
height: auto;
|
}
|
|
/* 骨架屏样式 */
|
.skeleton-container {
|
padding: 20rpx;
|
}
|
|
.skeleton-group {
|
margin-bottom: 40rpx;
|
}
|
|
.skeleton-divider {
|
height: 40rpx;
|
width: 300rpx;
|
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
|
background-size: 400% 100%;
|
border-radius: 4rpx;
|
animation: skeleton-loading 1.4s ease infinite;
|
margin-bottom: 30rpx;
|
}
|
|
.skeleton-item {
|
display: flex;
|
align-items: center;
|
margin-bottom: 30rpx;
|
}
|
|
.skeleton-label {
|
width: 160rpx;
|
height: 40rpx;
|
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
|
background-size: 400% 100%;
|
border-radius: 4rpx;
|
animation: skeleton-loading 1.4s ease infinite;
|
margin-right: 20rpx;
|
}
|
|
.skeleton-input {
|
flex: 1;
|
height: 60rpx;
|
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
|
background-size: 400% 100%;
|
border-radius: 8rpx;
|
animation: skeleton-loading 1.4s ease infinite;
|
}
|
|
.skeleton-select {
|
flex: 1;
|
height: 60rpx;
|
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
|
background-size: 400% 100%;
|
border-radius: 8rpx;
|
animation: skeleton-loading 1.4s ease infinite;
|
}
|
|
.skeleton-datetime {
|
flex: 1;
|
height: 60rpx;
|
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
|
background-size: 400% 100%;
|
border-radius: 8rpx;
|
animation: skeleton-loading 1.4s ease infinite;
|
}
|
|
.skeleton-button {
|
width: 90%;
|
height: 80rpx;
|
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
|
background-size: 400% 100%;
|
border-radius: 10rpx;
|
animation: skeleton-loading 1.4s ease infinite;
|
margin: 40rpx auto;
|
}
|
|
@keyframes skeleton-loading {
|
0% {
|
background-position: 100% 50%;
|
}
|
|
100% {
|
background-position: 0 50%;
|
}
|
}
|
</style>
|