add ProductStockPackageSummary.vue

This commit is contained in:
Timi
2026-10-05 16:11:24 +08:00
parent f643656eb4
commit 58d99e52c5
3 changed files with 103 additions and 0 deletions
+2
View File
@@ -55,6 +55,7 @@
</div>
</template>
</t-cell>
<product-stock-package-summary :sku="sku" :stock="stock" />
<t-cell title="查看库存流水" arrow @click="openRecordList" />
<t-cell v-if="0 < Number(stock.reservedQuantity || 0)" title="查看库存预占流水" arrow @click="openReservedRecordList" />
</t-cell-group>
@@ -100,6 +101,7 @@ import { shallowRef } from "vue";
import { useUserStore } from "timi-web-api";
import ProductAPI from "@/api/ProductAPI";
import ProductProfile from "@/pages/product/component/ProductProfile.vue";
import ProductStockPackageSummary from "@/pages/product/component/ProductStockPackageSummary.vue";
import ProductStockOperationPopup from "@/pages/product/ProductStockOperationPopup.vue";
import { useNavBarStore } from "@/store/navBarStore";
import type { Product, ProductSku, ProductStock, ProductSkuUnit, StockOperationType } from "@/types/Product";
@@ -0,0 +1,78 @@
<template>
<template v-if="packageUnits.length">
<t-cell class="packages" title="整包装换算">
<template #note>
<div class="options" role="group" aria-label="选择整包装换算单位">
<t-button
v-for="unit in packageUnits"
:key="unit.id"
size="extra-small"
:theme="selectedUnit?.id === unit.id ? 'primary' : 'default'"
:variant="selectedUnit?.id === unit.id ? 'base' : 'outline'"
:aria-label="`按${unit.name || '未命名单位'}换算`"
:aria-pressed="selectedUnit?.id === unit.id"
@click="selectedUnitId = unit.id || ''"
>
<span v-text="`按${unit.name || '未命名单位'}`" />
</t-button>
</div>
</template>
</t-cell>
<t-cell title="库存折合" :note="summary.onHand" />
<t-cell title="可用折合" :note="summary.available" />
</template>
</template>
<script setup lang="ts">
import type { ProductSku, ProductStock } from "@/types/Product";
import { splitBaseQuantityIntoPackages } from "@/utils/package";
const props = defineProps<{ sku: ProductSku; stock: ProductStock }>();
// ---------- 整包装换算 ----------
const selectedUnitId = ref("");
const baseUnits = computed(() => (props.sku.unitList || []).filter(unit => unit.isBase));
const packageUnits = computed(() => (props.sku.unitList || [])
.filter(unit => unit.id && !unit.isBase && 1 < Number(unit.baseQuantityPerUnit))
.sort((left, right) => Number(right.baseQuantityPerUnit) - Number(left.baseQuantityPerUnit)));
const selectedUnit = computed(() => packageUnits.value.find(unit => unit.id === selectedUnitId.value) || packageUnits.value[0]);
const summary = computed(() => ({
onHand: getSummaryText(props.stock.onHandQuantity),
available: getSummaryText(props.stock.availableQuantity)
}));
/** 使用原始基础库存换算,保留基础单位余数,异常数据不按零库存展示。 */
function getSummaryText(quantity?: number | string): string {
const baseUnit = baseUnits.value[0];
const unit = selectedUnit.value;
if (quantity === undefined || baseUnits.value.length !== 1 || !baseUnit?.name
|| Number(baseUnit.baseQuantityPerUnit) !== 1 || !unit?.name) {
return "无法换算";
}
const result = splitBaseQuantityIntoPackages(quantity, unit.baseQuantityPerUnit);
if (!result) {
return "无法换算";
}
const parts: string[] = [];
if (result.whole !== "0") {
parts.push(`${result.whole} ${unit.name}`);
}
if (result.remainder !== "0" || !parts.length) {
parts.push(`${result.remainder} ${baseUnit.name}`);
}
return parts.join(" ");
}
</script>
<style scoped lang="less">
.packages {
.options {
--td-button-border-radius: .5rem;
gap: .5rem;
display: flex;
flex-wrap: wrap;
}
}
</style>