| | |
| | | </view> |
| | | <view> |
| | | <text class="label">已领用</text> |
| | | {{ items.length }} 件 |
| | | <!-- 件数可点击:展开领用统计(产品大类 / 规格型号 / 数量) --> |
| | | <view class="count-link" @click="openRequisitionStats"> |
| | | <text class="count-link-text">{{ items.length }} 件</text> |
| | | <text class="count-link-arrow">▾</text> |
| | | </view> |
| | | </view> |
| | | <view> |
| | | <text class="label">温度</text> |
| | |
| | | </wd-card> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <wd-popup |
| | | v-model="statsPopupVisible" |
| | | position="bottom" |
| | | :z-index="31" |
| | | :close-on-click-modal="true" |
| | | custom-style="max-height: 60vh; border-radius: 24rpx 24rpx 0 0;" |
| | | > |
| | | <view class="popup-layout"> |
| | | <view class="popup-header"> |
| | | <view> |
| | | <text class="popup-title">领用统计</text> |
| | | <text class="popup-subtitle">产品大类 / 规格型号 / 数量</text> |
| | | </view> |
| | | <wd-icon name="close" size="20px" @click="statsPopupVisible = false" /> |
| | | </view> |
| | | |
| | | <scroll-view class="stats-list" scroll-y> |
| | | <view v-if="statsLoading" class="state-box"> |
| | | <wd-loading /> |
| | | <text>统计中...</text> |
| | | </view> |
| | | <wd-status-tip v-else-if="!statsRows.length" image="content" tip="暂无领用数据" /> |
| | | <block v-else> |
| | | <view |
| | | v-for="(row, index) in statsRows" |
| | | :key="`${row.categoryName}-${row.model}-${index}`" |
| | | class="stats-item" |
| | | > |
| | | <view class="stats-item-main"> |
| | | <text class="stats-category">{{ row.categoryName || "-" }}</text> |
| | | <text class="stats-model">{{ row.model || "-" }}</text> |
| | | </view> |
| | | <text class="stats-count">{{ row.count }} 件</text> |
| | | </view> |
| | | </block> |
| | | </scroll-view> |
| | | |
| | | <view class="popup-footer"> |
| | | <text>合计 {{ statsTotal }} 件</text> |
| | | <wd-button custom-class="footer-action-button" @click="statsPopupVisible = false"> |
| | | 关闭 |
| | | </wd-button> |
| | | </view> |
| | | </view> |
| | | </wd-popup> |
| | | |
| | | <wd-popup |
| | | v-model="rackSelectorVisible" |
| | |
| | | import type { TagType } from "wot-design-uni/components/wd-tag/types"; |
| | | import CardTitle from "@/components/card-title/index.vue"; |
| | | import Scan from "@/components/scan/index.vue"; |
| | | import TimeSensitiveTaskApi, { type TimelinessMaterialType } from "@/api/timeSensitiveTask"; |
| | | import TimeSensitiveTaskApi, { |
| | | type RequisitionStatVO, |
| | | type TimelinessMaterialType, |
| | | } from "@/api/timeSensitiveTask"; |
| | | |
| | | const toast = useToast(); |
| | | const message = useMessage(); |
| | |
| | | const selectedRackNos = ref<string[]>([]); |
| | | const rackSelectorVisible = ref(false); |
| | | const rackSelectionRows = ref<Array<{ label: string; value: string; selected: boolean }>>([]); |
| | | |
| | | /* ==================== 领用统计 ==================== */ |
| | | const statsPopupVisible = ref(false); |
| | | const statsLoading = ref(false); |
| | | const statsRows = ref<RequisitionStatVO[]>([]); |
| | | const statsTotal = computed(() => |
| | | statsRows.value.reduce((sum, item) => sum + Number(item.count || 0), 0) |
| | | ); |
| | | |
| | | /** 点击「已领用 N 件」:请求领用统计并弹出 */ |
| | | const openRequisitionStats = async () => { |
| | | statsRows.value = []; |
| | | statsPopupVisible.value = true; |
| | | statsLoading.value = true; |
| | | try { |
| | | const { code, data } = await TimeSensitiveTaskApi.getRequisitionStats( |
| | | taskId.value, |
| | | materialType.value |
| | | ); |
| | | statsRows.value = code === 200 ? data || [] : []; |
| | | } catch (error) { |
| | | statsRows.value = []; |
| | | toast.error("领用统计查询失败"); |
| | | } finally { |
| | | statsLoading.value = false; |
| | | } |
| | | }; |
| | | const activeRackNo = ref(""); |
| | | const candidateRackNo = ref(""); |
| | | const pendingScanEvent = ref<any>(null); |
| | |
| | | color: #7e8987; |
| | | } |
| | | |
| | | /* 已领用件数:可点击,展开领用统计 */ |
| | | .count-link { |
| | | display: flex; |
| | | gap: 2px; |
| | | align-items: center; |
| | | } |
| | | |
| | | .count-link-text { |
| | | color: #0d867f; |
| | | border-bottom: 1px solid rgba(13, 134, 127, 0.4); |
| | | } |
| | | |
| | | .count-link-arrow { |
| | | font-size: 12px; |
| | | color: #0d867f; |
| | | } |
| | | |
| | | /* 领用统计弹框 */ |
| | | .stats-list { |
| | | max-height: 40vh; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .stats-item { |
| | | display: flex; |
| | | gap: 12px; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 14px 16px; |
| | | border-bottom: 1px solid #f2f4f3; |
| | | } |
| | | |
| | | .stats-item-main { |
| | | display: flex; |
| | | flex: 1; |
| | | flex-direction: column; |
| | | gap: 4px; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .stats-category { |
| | | font-size: 15px; |
| | | font-weight: 500; |
| | | color: #252525; |
| | | overflow-wrap: anywhere; |
| | | } |
| | | |
| | | .stats-model { |
| | | font-size: 13px; |
| | | color: #7e8987; |
| | | overflow-wrap: anywhere; |
| | | } |
| | | |
| | | .stats-count { |
| | | flex-shrink: 0; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #0d867f; |
| | | } |
| | | |
| | | .scan-tip { |
| | | display: flex; |
| | | gap: 8px; |