<template>
|
<view class="picking-detail">
|
<PageHeader title="领料详情"
|
@back="goBack" />
|
<scroll-view scroll-y
|
class="detail-list"
|
v-if="detailList.length > 0">
|
<view v-for="(item, index) in detailList"
|
:key="index"
|
class="material-card">
|
<view class="card-header">
|
<text class="material-name">{{ item.materialName || item.productName || '-' }}</text>
|
<up-tag :text="item.operationName || '-'"
|
type="info"
|
size="mini"
|
plain />
|
</view>
|
<view class="card-content">
|
<view class="info-grid">
|
<view class="info-item">
|
<text class="label">规格型号</text>
|
<text class="value">{{ item.model || '-' }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">单位</text>
|
<text class="value">{{ item.unit || '-' }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">需领数量</text>
|
<text class="value highlight">{{ item.qtyRequired || item.demandedQuantity || 0 }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">已领数量</text>
|
<text class="value success">{{ item.qtyPicked || item.pickQuantity || 0 }}</text>
|
</view>
|
<view class="info-item">
|
<text class="label">补料数量</text>
|
<view class="value link"
|
@click="showSupplementDetail(item)">
|
{{ item.qtySupplement || item.feedingQty || 0 }}
|
</view>
|
</view>
|
<view class="info-item">
|
<text class="label">退料数量</text>
|
<text class="value">{{ item.returnQty || 0 }}</text>
|
</view>
|
</view>
|
<view class="remark-row"
|
v-if="item.remark">
|
<text class="label">备注:</text>
|
<text class="value">{{ item.remark }}</text>
|
</view>
|
</view>
|
</view>
|
</scroll-view>
|
<view v-else
|
class="no-data">
|
<up-empty mode="data"
|
text="暂无领料详情"></up-empty>
|
</view>
|
<!-- 补料记录弹窗 -->
|
<up-popup :show="showPopup"
|
mode="bottom"
|
@close="showPopup = false"
|
round="10">
|
<view class="popup-content">
|
<view class="popup-header">
|
<text class="title">补料记录</text>
|
<up-icon name="close"
|
size="20"
|
@click="showPopup = false"></up-icon>
|
</view>
|
<scroll-view scroll-y
|
class="record-list">
|
<view v-if="supplementRecords.length > 0">
|
<view v-for="(record, rIndex) in supplementRecords"
|
:key="rIndex"
|
class="record-item">
|
<view class="record-row">
|
<text class="record-label">补料数量:</text>
|
<text class="record-value highlight">{{ record.pickQuantity || 0 }}</text>
|
</view>
|
<view class="record-row">
|
<text class="record-label">补料人:</text>
|
<text class="record-value">{{ record.supplementUserName || '-' }}</text>
|
</view>
|
<view class="record-row">
|
<text class="record-label">补料日期:</text>
|
<text class="record-value">{{ record.supplementTime || '-' }}</text>
|
</view>
|
<view class="record-row">
|
<text class="record-label">补料原因:</text>
|
<text class="record-value">{{ record.feedingReason || '-' }}</text>
|
</view>
|
</view>
|
</view>
|
<view v-else
|
class="no-record">
|
<text>暂无补料记录</text>
|
</view>
|
</scroll-view>
|
</view>
|
</up-popup>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, reactive } from "vue";
|
import { onLoad } from "@dcloudio/uni-app";
|
import {
|
listMaterialPickingDetail,
|
listMaterialSupplementRecord,
|
} from "@/api/productionManagement/productionOrder.js";
|
import PageHeader from "@/components/PageHeader.vue";
|
|
const npsNo = ref("");
|
const productionOrderId = ref("");
|
const detailList = ref([]);
|
const loading = ref(false);
|
|
// 弹窗相关
|
const showPopup = ref(false);
|
const supplementRecords = ref([]);
|
const recordLoading = ref(false);
|
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
const calculatePending = item => {
|
const required = Number(item.qtyRequired || item.demandedQuantity || 0);
|
const picked = Number(item.qtyPicked || item.pickQuantity || 0);
|
return Math.max(0, required - picked);
|
};
|
|
onLoad(options => {
|
if (options.id) {
|
productionOrderId.value = options.id;
|
npsNo.value = options.npsNo || "";
|
fetchDetail(options.id);
|
}
|
});
|
|
const fetchDetail = id => {
|
loading.value = true;
|
listMaterialPickingDetail(id)
|
.then(res => {
|
detailList.value = res.data?.records || res.data || [];
|
loading.value = false;
|
})
|
.catch(() => {
|
loading.value = false;
|
uni.showToast({
|
title: "获取详情失败",
|
icon: "error",
|
});
|
});
|
};
|
|
const showSupplementDetail = item => {
|
const qty = Number(item.qtySupplement || item.feedingQty || 0);
|
if (qty <= 0) return;
|
|
showPopup.value = true;
|
recordLoading.value = true;
|
supplementRecords.value = [];
|
|
listMaterialSupplementRecord({
|
pickId: item.id,
|
productionOrderId: productionOrderId.value,
|
})
|
.then(res => {
|
supplementRecords.value = res.data || [];
|
recordLoading.value = false;
|
})
|
.catch(() => {
|
recordLoading.value = false;
|
uni.showToast({
|
title: "获取补料记录失败",
|
icon: "error",
|
});
|
});
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.picking-detail {
|
min-height: 100vh;
|
background: #f8f9fa;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.detail-list {
|
flex: 1;
|
height: 0;
|
padding: 20rpx;
|
}
|
|
.material-card {
|
background: #fff;
|
margin-bottom: 24rpx;
|
padding: 24rpx;
|
border-radius: 16rpx;
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding-bottom: 20rpx;
|
border-bottom: 1rpx solid #f5f5f5;
|
margin-bottom: 20rpx;
|
|
.material-name {
|
font-size: 30rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
}
|
|
.info-grid {
|
display: grid;
|
grid-template-columns: repeat(2, 1fr);
|
gap: 20rpx;
|
|
.info-item {
|
display: flex;
|
flex-direction: column;
|
|
.label {
|
font-size: 24rpx;
|
color: #999;
|
margin-bottom: 4rpx;
|
}
|
|
.value {
|
font-size: 26rpx;
|
color: #333;
|
|
&.highlight {
|
color: #f56c6c;
|
font-weight: bold;
|
}
|
&.success {
|
color: #67c23a;
|
font-weight: bold;
|
}
|
&.warning {
|
color: #e6a23c;
|
font-weight: bold;
|
}
|
&.link {
|
color: #3c9cff;
|
text-decoration: underline;
|
}
|
}
|
}
|
}
|
|
.remark-row {
|
margin-top: 20rpx;
|
padding-top: 16rpx;
|
border-top: 1rpx dashed #eee;
|
display: flex;
|
|
.label {
|
font-size: 24rpx;
|
color: #999;
|
}
|
.value {
|
font-size: 24rpx;
|
color: #666;
|
flex: 1;
|
}
|
}
|
}
|
|
.no-data {
|
padding-top: 200rpx;
|
}
|
|
/* 弹窗样式 */
|
.popup-content {
|
background: #fff;
|
padding: 30rpx;
|
max-height: 70vh;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding-bottom: 30rpx;
|
border-bottom: 1rpx solid #eee;
|
|
.title {
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
}
|
|
.record-list {
|
flex: 1;
|
height: 0;
|
padding-top: 20rpx;
|
}
|
|
.record-item {
|
padding: 24rpx;
|
background: #f9f9f9;
|
border-radius: 12rpx;
|
margin-bottom: 20rpx;
|
|
.record-row {
|
display: flex;
|
margin-bottom: 10rpx;
|
&:last-child {
|
margin-bottom: 0;
|
}
|
|
.record-label {
|
font-size: 26rpx;
|
color: #999;
|
width: 140rpx;
|
}
|
|
.record-value {
|
font-size: 26rpx;
|
color: #333;
|
flex: 1;
|
|
&.highlight {
|
color: #f56c6c;
|
font-weight: bold;
|
}
|
}
|
}
|
}
|
|
.no-record {
|
padding: 100rpx 0;
|
text-align: center;
|
color: #999;
|
font-size: 28rpx;
|
}
|
</style>
|