中航光电PDA端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

528 lines
12 KiB

3 weeks ago
<template>
<ifrm ref="ifrm">
<!-- <view class="header">
<button v-if="activeBox" @click="handleResetBox" class="header-btn">
换箱
</button>
</view> -->
<uni-forms ref="wrForm" class="formBox" label-position="top">
<uni-forms-item label="物料箱条码:" label-width="100px">
<view class="bottom-input-row">
<view class="weight-input-wrapper">
<view class="input-box">
<input
type="text"
v-model="boxCode"
@confirm="handleBoxConfirm"
placeholder="物料箱条码"
class="uni-input-border"
confirm-type="done"
3 weeks ago
:focus="boxInputFocus"
:key="'box-' + boxInputFocus"
3 weeks ago
/>
</view>
</view>
<button class="submit-btn" :disabled="!canSubmit" @tap="handleSubmit">
装箱
</button>
</view>
<view v-if="activeBox" class="box-stats">
<view class="stats-left">
<text class="stats-label">当前物料箱</text>
<text class="stats-value-box">{{ activeBox }}</text>
</view>
<view class="stats-right">
<view class="stats-item">
<text class="stats-label">总数量</text>
<text class="stats-value">{{ totalCount }} </text>
</view>
<view class="stats-item">
<text class="stats-label">总重量</text>
<text class="stats-value-weight">{{ totalWeight }} g</text>
</view>
</view>
</view>
</uni-forms-item>
<uni-forms-item label="扫描流程卡(装箱):" label-width="200px">
<input
type="text"
v-model="cardCode"
@confirm="handleCardConfirm"
:disabled="!activeBox"
placeholder="流程卡号"
class="uni-input-border"
:class="{ 'input-disabled': !activeBox }"
confirm-type="done"
3 weeks ago
:focus="cardInputFocus"
:key="'card-' + cardInputFocus"
3 weeks ago
/>
</uni-forms-item>
</uni-forms>
<scroll-view class="orders-scroll" scroll-y>
<view class="orders-header">
<text class="orders-icon"></text>
<text class="orders-title"
>箱内明细 ({{
boxInfo.yieldOrderList ? boxInfo.yieldOrderList.length : 0
}})</text
>
</view>
<view v-if="boxInfo.yieldOrderList.length === 0" class="empty-tip">
<text>{{
activeBox ? "暂无明细,请扫描流程卡装箱" : "请先扫描物料箱"
}}</text>
</view>
<view v-else class="orders-list">
<view
v-for="(order, index) in boxInfo.yieldOrderList"
:key="order.id"
class="order-card"
:class="{ 'order-latest': index === 0 }"
>
3 weeks ago
<!-- <view v-if="index === 0" class="latest-badge">最新</view> -->
<view class="delete-btn" @tap="handleDeleteOrder(order, index)">
<text class="delete-icon"></text>
</view>
3 weeks ago
<view class="order-header">
<text class="order-no">{{ order.woOrder }}订单号</text>
<text class="order-no">{{ order.cardNo }}</text>
</view>
<view class="order-footer">
<text class="order-part">{{ order.partCode }}</text>
<text class="order-weight">{{ order.actualWeighing }} g</text>
</view>
</view>
</view>
</scroll-view>
</ifrm>
</template>
<script>
import ifrm from "@/pages/index/ifrm";
export default {
components: {
ifrm,
},
data() {
return {
boxInfo: {
yieldOrderList: [],
},
boxCode: "",
cardCode: "",
activeBox: null,
orders: [],
boxInputFocus: true,
cardInputFocus: false,
};
},
computed: {
canSubmit() {
return this.boxInfo.yieldOrderList.length > 0;
},
totalCount() {
return this.boxInfo.yieldOrderList.length;
},
totalWeight() {
if (
!this.boxInfo.yieldOrderList ||
this.boxInfo.yieldOrderList.length === 0
) {
return 0;
}
return this.boxInfo.yieldOrderList.reduce((sum, o) => {
return sum + (Number(o.actualWeighing) || 0);
}, 0);
},
},
methods: {
3 weeks ago
handleDeleteOrder(order, index) {
uni.showModal({
title: "确认删除",
content: `确定要删除流程卡 ${order.cardNo} 吗?`,
success: (res) => {
if (res.confirm) {
this.boxInfo.yieldOrderList.splice(index, 1);
uni.showToast({
title: "删除成功",
icon: "success",
});
}
},
});
},
3 weeks ago
// 扫描物料箱条码
handleBoxConfirm() {
const code = this.boxCode.trim();
if (!code) return;
this.$u.api
.boxbarcodeDetails({ boxBarcode: this.boxCode })
.then((res) => {
this.boxInfo = res.data;
if (this.boxInfo.yieldOrderList == null) {
3 weeks ago
this.boxInfo.yieldOrderList = [];
}
3 weeks ago
});
this.activeBox = code;
// 加载已有数据,如果没有则为空箱
uni.showToast({
title: `物料箱 ${code} 已就绪`,
icon: "success",
});
this.boxCode = "";
this.boxInputFocus = false;
this.cardInputFocus = true;
3 weeks ago
},
handleCardConfirm() {
const code = this.cardCode;
3 weeks ago
// if (!code) return;
if (this.cardCode) {
if (!this.activeBox) {
uni.showToast({
title: "请先扫描物料箱条码",
icon: "none",
});
this.boxInputFocus = false;
3 weeks ago
this.$nextTick(() => {
this.boxInputFocus = true;
});
return;
}
if (
this.boxInfo.yieldOrderList.some((o) => o.cardNo === this.cardCode)
) {
3 weeks ago
uni.showToast({
3 weeks ago
title: `订单 ${this.cardCode} 已在该箱中!`,
3 weeks ago
icon: "none",
});
this.cardCode = "";
3 weeks ago
this.cardInputFocus = false;
this.$nextTick(() => {
this.cardInputFocus = true;
});
3 weeks ago
return;
}
3 weeks ago
uni.showLoading({
title: "查询中...",
mask: true,
3 weeks ago
});
3 weeks ago
this.$u.api
.queryCardNo({ cardNo: this.cardCode })
.then((res) => {
this.boxInfo.yieldOrderList.push(res.data);
uni.hideLoading();
// 计算当前总重量
const currentWeight = this.boxInfo.yieldOrderList.reduce(
(sum, o) => {
return sum + (Number(o.actualWeighing) || 0);
},
0
);
if (currentWeight > 50000) {
uni.showToast({
title: `请注意箱子已超重!!!!!`,
icon: "warring",
});
} else {
uni.showToast({
title: `流程卡 ${code} 装箱成功`,
icon: "success",
});
}
3 weeks ago
this.cardCode = "";
this.cardInputFocus = false;
this.$nextTick(() => {
this.cardInputFocus = true;
});
})
.catch((err) => {
uni.showToast({
title: err,
icon: "error",
});
3 weeks ago
this.cardCode = "";
this.cardInputFocus = false;
this.$nextTick(() => {
this.cardInputFocus = true;
});
});
}
3 weeks ago
},
handleResetBox() {
this.activeBox = null;
this.boxCode = "";
this.orders = [];
this.boxInputFocus = true;
this.cardInputFocus = false;
},
// 装箱确认
handleSubmit() {
this.$u.api
.boxBinding({
boxBarcode: this.activeBox, //箱条码
orderIdList: this.boxInfo.yieldOrderList.map((o) => o.cardNo),
})
.then((res) => {
uni.showToast({
title: `装箱成功`,
icon: "success",
});
this.cardCode = "";
this.boxInfo.yieldOrderList = [];
});
},
},
};
</script>
<style scoped>
.formBox {
border-bottom: 4rpx solid #cbd5e1;
}
.box-stats {
margin-top: 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #eff6ff;
border: 2rpx solid #bfdbfe;
padding: 16rpx;
border-radius: 4rpx;
}
.stats-left {
display: flex;
flex-direction: column;
}
.stats-label {
color: #475569;
font-size: 22rpx;
}
.stats-value-box {
font-weight: bold;
color: #1e40af;
font-size: 26rpx;
}
.stats-right {
display: flex;
gap: 24rpx;
text-align: right;
}
.stats-item {
display: flex;
flex-direction: column;
}
.stats-value {
font-weight: bold;
color: #0f172a;
font-size: 26rpx;
}
.stats-value-weight {
font-weight: bold;
color: #059669;
font-size: 26rpx;
}
.orders-scroll {
flex: 1;
padding: 16rpx;
background-color: #f8fafc;
}
.orders-header {
display: flex;
align-items: center;
color: #334155;
font-weight: bold;
margin-bottom: 16rpx;
padding: 0 8rpx;
}
.orders-icon {
font-size: 32rpx;
margin-right: 8rpx;
}
.orders-title {
font-size: 26rpx;
}
.empty-tip {
text-align: center;
padding: 48rpx 0;
color: #94a3b8;
font-weight: 500;
font-size: 24rpx;
}
.orders-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.order-card {
background-color: #ffffff;
padding: 16rpx;
border: 4rpx solid #cbd5e1;
border-radius: 4rpx;
display: flex;
flex-direction: column;
position: relative;
}
.order-latest {
3 weeks ago
/* border-color: #fb923c; */
3 weeks ago
box-shadow: 0 0 0 2rpx rgba(251, 146, 60, 0.2);
}
.latest-badge {
position: absolute;
top: -8rpx;
right: -4rpx;
background-color: #f97316;
color: #ffffff;
font-size: 18rpx;
font-weight: bold;
padding: 4rpx 12rpx;
border-radius: 4rpx;
}
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2rpx solid #f1f5f9;
padding-bottom: 8rpx;
margin-bottom: 8rpx;
}
.order-no {
font-weight: bold;
color: #0f172a;
font-size: 28rpx;
}
.order-weight {
font-weight: bold;
color: #059669;
}
.order-footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.order-label {
color: #475569;
font-weight: 500;
}
.order-part {
font-weight: bold;
color: #1e293b;
}
.help-tip {
position: absolute;
top: 40%;
left: 0;
width: 100%;
display: flex;
justify-content: center;
pointer-events: none;
opacity: 0.5;
z-index: 10;
}
.tip-content {
background-color: #1e293b;
color: #ffffff;
font-size: 20rpx;
padding: 8rpx 16rpx;
border-radius: 4rpx;
display: flex;
align-items: center;
}
.tip-icon {
margin-right: 8rpx;
font-size: 24rpx;
}
.tip-text {
font-size: 20rpx;
}
.bottom-input-row {
display: flex;
gap: 10px;
margin-bottom: 12px;
}
.weight-input-wrapper {
flex: 1;
}
.submit-btn {
width: 88px;
height: 50px;
background-color: #155dfc;
border-radius: 10px;
color: #ffffff;
font-size: 16px;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.1),
0px 1px 2px 0px rgba(0, 0, 0, 0.1);
border: none;
padding: 0;
line-height: 50px;
}
.submit-btn.disabled {
opacity: 0.5;
}
3 weeks ago
/* 在 style scoped 中添加 */
.delete-btn {
position: absolute;
top: -20rpx;
right: 0rpx;
width: 40rpx;
height: 40rpx;
background-color: #ff4444;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
box-shadow: 0 2rpx 8rpx rgba(255, 68, 68, 0.3);
}
.delete-icon {
color: #ffffff;
font-size: 24rpx;
font-weight: bold;
line-height: 1;
}
.delete-btn:active {
background-color: #cc0000;
transform: scale(0.95);
}
3 weeks ago
</style>