<template>
|
<view class="container">
|
<cu-custom :bgColor="NavBarColor" :isBack="true" backRouterName="productionTask">
|
<block slot="backText">返回</block>
|
<block slot="content">报工</block>
|
<block slot="right">
|
<view v-show="isShow" @click="printHandel">
|
<image class="search" src="/static/icon_dayin.png" style="width: 25px; height: 25px;" alt="打印按钮" />
|
</view>
|
</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-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-select"></view>
|
</view>
|
<view class="skeleton-item">
|
<view class="skeleton-label"></view>
|
<view class="skeleton-select"></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-select"></view>
|
</view>
|
<view class="skeleton-item">
|
<view class="skeleton-label"></view>
|
<view class="skeleton-datetime"></view>
|
</view>
|
</view>
|
|
<view class="skeleton-button"></view>
|
</view>
|
|
<!-- 实际内容 -->
|
<view v-else class="container">
|
<uni-forms ref="form" :modelValue="formData" validate-trigger="bind" err-show-type="undertext">
|
<uni-group top="1">
|
<view class="divider"><text>工单信息</text></view>
|
<uni-forms-item :label-width="100" name="workOrderNumber" label="报工工单:">
|
<uni-data-select v-model="workOrderNumber" :localdata="productionOrderList"
|
@change="changeProductionOrder" placeholder="请选择" />
|
</uni-forms-item>
|
<uni-forms-item :label-width="100" name="reportCode" label="生产 订单:">
|
<uni-data-select v-model="reportCode" :localdata="reportCodeList" @change="changeReportCodeList"
|
placeholder="请选择" />
|
</uni-forms-item>
|
|
<uni-forms-item :label-width="100" name="materialDescription" label="产线:">
|
<uni-easyinput v-model="formData.materialDescription" :disabled="true" />
|
</uni-forms-item>
|
<uni-forms-item :label-width="100" name="plannedQuantity" label="报工数量:">
|
<uni-number-box :min="0" :max="9999" v-model="formData.plannedQuantity" />
|
</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';
|
import {
|
mapGetters
|
} from "vuex";
|
export default {
|
components: {
|
pdaScanVue
|
},
|
data() {
|
return {
|
loading: true,
|
isShow: false,
|
materialNumber: '',
|
isSubmitting: false, // 防重复提交
|
productionOrderList: [],
|
reportCodeList: [],
|
reportCode: '',
|
workOrderNumber: '',
|
scrollLeft: 0,
|
formData: {
|
workOrderNumber: '1111111',
|
materialCode: '120008194',
|
materialDescription: '三代轮毂轴承单元\\G3-487',
|
plannedQuantity: '200',
|
inspectionOrderNumber: '',
|
process: '',
|
inspectionType: '',
|
inspectionQuantity: '',
|
inspectionPlan: '',
|
inspectionTime: '',
|
// 新增字段用于标签数据
|
productName: '驱动轴总成',
|
palletNo: 'PAL20250822001',
|
produceDate: '',
|
workshop: '装配车间3号线'
|
},
|
|
NavBarColor: this.NavBarColor,
|
url: {
|
getEquipmentList: 'mes/mesProductionWorkOrder/list',
|
approval: '/mes/productionOrder/selectReportWorkOrderList',
|
add: 'mes/mesWorkReporting/add'
|
},
|
styles: {
|
color: '#2979FF',
|
borderColor: '#2979FF'
|
},
|
msg1Count: 0
|
}
|
},
|
computed: {
|
...mapGetters(["currentLineName", "username", "currentLineId"]),
|
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
|
},
|
},
|
created() {
|
this.formData.materialDescription = this.currentLineName;
|
this.getRelatedProdOrder();
|
|
},
|
methods: {
|
changeReportCodeList(e) {
|
this.reportCode = e;
|
},
|
changeProductionOrder(e) {
|
this.workOrderNumber = e;
|
// 通过 selectedValue 匹配 productionOrderList 中的项
|
const selectedItem = this.productionOrderList.find(
|
item => item.value === this.workOrderNumber
|
);
|
if (selectedItem) {
|
// 获取 materialNumber
|
this.materialNumber = selectedItem.materialNumber;
|
console.log('选中项的 materialNumber:', this.materialNumber);
|
|
// 获取索引(可选,若需要索引)
|
const index = this.productionOrderList.findIndex(
|
item => item.value === this.workOrderNumber
|
);
|
console.log('选中项的索引:', index);
|
}
|
|
this.getReportCodeList(this.materialNumber);
|
},
|
getReportCodeList(code) {
|
this.$http.get(this.url.approval, {
|
params: {
|
materialNumber: code,
|
}
|
}).then(res => {
|
if (res.data.success) {
|
this.loading = false;
|
this.reportCodeList = res.data.result
|
} else {
|
uni.showModal({
|
title: "提示",
|
content: res.data.message,
|
confirmText: '确定',
|
showCancel: false,
|
})
|
}
|
}).catch(() => {
|
this.$tip.loaded();
|
uni.showToast({
|
icon: "error",
|
title: res.data.message,
|
duration: 2000
|
});
|
});
|
|
|
},
|
getRelatedProdOrder() {
|
this.$http.get(this.url.getEquipmentList, {
|
params: {
|
workOrderStatus: "EXECUTING",
|
factoryId: this.currentLineId
|
|
}
|
}).then(res => {
|
if (res.data.success) {
|
this.loading = false;
|
this.productionOrderList = (res.data.result.records || []).map(line => ({
|
value: line.value,
|
text: line.text,
|
materialNumber: line.materialNumber // 确保映射type字段
|
}));
|
console.log(this.productionOrderList)
|
|
} else {
|
uni.showModal({
|
title: "提示",
|
content: res.data.message,
|
confirmText: '确定',
|
showCancel: false,
|
})
|
}
|
}).catch(() => {
|
this.$tip.loaded();
|
uni.showToast({
|
icon: "error",
|
title: res.data.message,
|
duration: 2000
|
});
|
});
|
|
|
},
|
|
// 点击打印按钮:生成HTML预览并跳转
|
async printHandel() {
|
// 1. 验证表单信息
|
if (!this.formData.inspectionQuantity || !this.formData.process) {
|
uni.showToast({
|
title: '请先填写报工数量和仓库信息',
|
icon: 'none',
|
duration: 2000
|
});
|
return;
|
}
|
|
try {
|
uni.showLoading({
|
title: '生成预览中...'
|
});
|
|
// 2. 收集打印数据
|
const tagData = this.getReportPrintData();
|
|
// 3. 跳转至预览页,并携带打印数据
|
await uni.navigateTo({
|
url: `/pages/finished-product-preview/finished-product-preview?tagData=${encodeURIComponent(JSON.stringify(tagData))}`
|
});
|
|
uni.hideLoading();
|
} catch (error) {
|
uni.hideLoading();
|
console.error('生成预览失败:', error);
|
uni.showToast({
|
title: '预览生成失败',
|
icon: 'none'
|
});
|
}
|
},
|
|
// 生成成品托标签数据(优化后)
|
getReportPrintData() {
|
const {
|
formData
|
} = this;
|
return {
|
|
material: '120034535',
|
batch: '25098814',
|
model: 'G3-2B259',
|
quantity: 216,
|
inspectDate: '20250408',
|
inspector: '王義/合格',
|
date: '2025.08.22'
|
};
|
},
|
|
changeisSpareList(e) {
|
this.formData.isSpare = e;
|
},
|
|
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.add, {
|
factoryId: this.currentLineId,
|
orderId: this.reportCode,
|
quantity: this.formData.plannedQuantity,
|
workOrderId: this.workOrderNumber
|
});
|
|
if (response.data.success) {
|
this.isShow = true;
|
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>
|