diff --git a/src/pages/product/ProductStockDetail.vue b/src/pages/product/ProductStockDetail.vue
index 655b355..c0c5a32 100644
--- a/src/pages/product/ProductStockDetail.vue
+++ b/src/pages/product/ProductStockDetail.vue
@@ -55,8 +55,8 @@
-
-
+
+
{
}
async function openRecordList(): Promise {
- if (product.value?.id) {
+ if (product.value?.id && sku.value?.id) {
await router.push({
name: "ProductStockRecordList",
query: {
productId: product.value.id,
+ skuId: sku.value.id,
transitionDepth: String(getCurrentRouteDepth() + 1)
}
});
@@ -211,11 +212,12 @@ async function openRecordList(): Promise {
}
async function openReservedRecordList(): Promise {
- if (product.value?.id) {
+ if (product.value?.id && sku.value?.id) {
await router.push({
name: "ProductStockRecordList",
query: {
productId: product.value.id,
+ skuId: sku.value.id,
operationType: "ORDER_RESERVE",
activeReservationOnly: "true",
transitionDepth: String(getCurrentRouteDepth() + 1)
diff --git a/src/pages/product/ProductStockRecordList.vue b/src/pages/product/ProductStockRecordList.vue
index 8d11fc2..057a416 100644
--- a/src/pages/product/ProductStockRecordList.vue
+++ b/src/pages/product/ProductStockRecordList.vue
@@ -20,70 +20,103 @@
@refresh="refresh"
@scrolltolower="loadMore"
>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -94,9 +127,9 @@ import { PassTimeLabel } from "timi-web";
import { UserAPI } from "timi-web-api";
import ProductAPI from "@/api/ProductAPI";
import { useNavBarStore } from "@/store/navBarStore";
-import type { StockOperationType, StockRecord, StockRecordDirection } from "@/types/Product";
+import type { Product, ProductSku, StockOperationType, StockRecord, StockRecordDirection } from "@/types/Product";
import { getErrorMessage } from "@/utils/error";
-import { getProductQuantityText, getStockOperationText } from "@/utils/product";
+import { getProductPhotoURL, getProductQuantityText, getProductTypeText, getStockOperationText } from "@/utils/product";
import { Message } from "@/utils/message";
import { permissionCodes } from "@/utils/permission";
import { getCustomerPhotoURL } from "@/utils/customer";
@@ -118,6 +151,12 @@ const loading = ref(false);
const isRefreshing = ref(false);
const noMore = ref(false);
const productId = computed(() => getQueryText("productId"));
+const skuId = computed(() => getQueryText("skuId"));
+const filteredProduct = ref();
+const filteredSku = ref();
+const filteredSkuUnitId = ref("");
+const filteredSkuUnitList = computed(() => (filteredSku.value?.unitList || []).filter(unit => !!unit.id));
+const filteredSkuPhotoURL = computed(() => filteredSku.value ? getProductPhotoURL(filteredSku.value) || (filteredProduct.value ? getProductPhotoURL(filteredProduct.value) : "") : "");
const activeReservationRequested = getQueryText("activeReservationOnly") === "true";
const operationType = ref(getQueryText("operationType") as OperationFilter || (activeReservationRequested ? "ORDER_RESERVE" : "ALL"));
const direction = ref(getQueryText("direction") as DirectionFilter || "ALL");
@@ -132,7 +171,7 @@ const emptyText = computed(() => {
if (activeReservationOnly.value) {
return "暂无有效的预占流水";
}
- return keyword.value.trim() || productId.value || operationType.value !== "ALL" || direction.value !== "ALL" ? "未找到匹配的库存流水" : "暂无库存流水";
+ return keyword.value.trim() || productId.value || skuId.value || operationType.value !== "ALL" || direction.value !== "ALL" ? "未找到匹配的库存流水" : "暂无库存流水";
});
const loadStateText = computed(() => loading.value ? "正在加载" : noMore.value ? "已经到底了" : "上拉加载更多");
const operationOptions = [
@@ -159,6 +198,10 @@ function getQueryText(key: string): string {
return Array.isArray(value) ? String(value[0] || "") : String(value || "");
}
+function getDefaultFilteredSkuUnitId(): string {
+ return filteredSkuUnitList.value.find(unit => unit.isBase)?.id || filteredSkuUnitList.value[0]?.id || "";
+}
+
function getOperationIcon(type?: StockOperationType): string {
return ({
INITIAL_IN: "import",
@@ -235,6 +278,7 @@ async function loadMore(force = false): Promise {
try {
const result = await ProductAPI.recordList({
productId: productId.value || undefined,
+ skuId: skuId.value || undefined,
keyword: keyword.value.trim() || undefined,
operationType: operationType.value === "ALL" ? undefined : operationType.value,
activeReservationOnly: activeReservationOnly.value || undefined,
@@ -257,6 +301,23 @@ async function loadMore(force = false): Promise {
}
}
+async function loadSkuFilter(): Promise {
+ if (!skuId.value) {
+ filteredProduct.value = undefined;
+ filteredSku.value = undefined;
+ filteredSkuUnitId.value = "";
+ return;
+ }
+ const sku = await ProductAPI.skuDetail(skuId.value);
+ const product = sku.productId ? await ProductAPI.detail(sku.productId) : undefined;
+ if (skuId.value !== getQueryText("skuId")) {
+ return;
+ }
+ filteredSku.value = sku;
+ filteredProduct.value = product;
+ filteredSkuUnitId.value = getDefaultFilteredSkuUnitId();
+}
+
async function selectOperationType(value: DropdownValue): Promise {
if (!Array.isArray(value)) {
operationType.value = String(value) as OperationFilter;
@@ -292,7 +353,7 @@ async function refresh(): Promise {
onMounted(async () => {
navBarStore.clearRight();
try {
- await reload();
+ await Promise.all([loadSkuFilter(), reload()]);
} catch (error) {
Message.error(getErrorMessage(error, "库存流水加载失败"));
}
@@ -372,83 +433,113 @@ onUnmounted(() => {
}
}
- .list {
- margin: 0;
+ .list-wrap {
+ gap: 1rem;
+ display: flex;
+ flex-direction: column;
+
+ .sku {
+ --td-tag-square-border-radius: .5rem;
- .item {
padding: 10px;
- min-width: 0;
:deep(.t-cell__title) {
- min-width: 0;
- width: 0;
- }
-
- :deep(.t-cell__title-text) {
- min-width: 0;
- width: 100%;
+ display: flex;
+ align-items: center;
}
.avatar {
- width: 3.5rem;
- height: 3.5rem;
- }
-
- .icon {
- width: 2.25rem;
- height: 2.25rem;
- display: inline-flex;
- background: var(--td-bg-color-secondarycontainer);
- align-items: center;
- border-radius: 50%;
- justify-content: center;
+ width: 2rem;
+ height: 2rem;
+ border-radius: .5rem !important;
}
.title {
gap: .5rem;
+ display: flex;
min-width: 0;
- max-width: 100%;
- flex: 1;
- display: flex;
- font-size: .75rem;
align-items: center;
- white-space: nowrap;
-
- .actor {
- color: var(--td-text-color-secondary);
- flex: 0 0 auto;
- }
-
- .operation {
- flex: 0 0 auto;
- }
-
- .product-name {
- min-width: 0;
- flex: 0 1 auto;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .quantity {
- color: var(--td-text-color-secondary);
- flex: 0 0 auto;
- font-weight: 400;
- }
}
+ }
- .description {
- gap: .5rem;
- display: flex;
- font-size: .75rem;
- align-items: center;
- justify-content: space-between;
+ .list {
+ margin: 0;
- .delta {
+ .item {
+ padding: 10px;
+ min-width: 0;
- .value {
- font-size: 1.25rem;
+ :deep(.t-cell__title) {
+ min-width: 0;
+ width: 0;
+ }
+
+ :deep(.t-cell__title-text) {
+ min-width: 0;
+ width: 100%;
+ }
+
+ .avatar {
+ width: 3.5rem;
+ height: 3.5rem;
+ }
+
+ .icon {
+ width: 2.25rem;
+ height: 2.25rem;
+ display: inline-flex;
+ background: var(--td-bg-color-secondarycontainer);
+ align-items: center;
+ border-radius: 50%;
+ justify-content: center;
+ }
+
+ .title {
+ gap: .5rem;
+ min-width: 0;
+ max-width: 100%;
+ flex: 1;
+ display: flex;
+ font-size: .75rem;
+ align-items: center;
+ white-space: nowrap;
+
+ .actor {
+ color: var(--td-text-color-secondary);
+ flex: 0 0 auto;
+ }
+
+ .operation {
+ flex: 0 0 auto;
+ }
+
+ .product-name {
+ min-width: 0;
+ flex: 0 1 auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .quantity {
+ color: var(--td-text-color-secondary);
+ flex: 0 0 auto;
+ font-weight: 400;
+ }
+ }
+
+ .description {
+ gap: .5rem;
+ display: flex;
+ font-size: .75rem;
+ align-items: center;
+ justify-content: space-between;
+
+ .delta {
+
+ .value {
+ font-size: 1.25rem;
+ }
}
}
}
diff --git a/src/types/Product.ts b/src/types/Product.ts
index 6439c2f..9d7a711 100644
--- a/src/types/Product.ts
+++ b/src/types/Product.ts
@@ -192,6 +192,7 @@ export type StockRecord = {
export type StockRecordPage = {
storeId?: string;
productId?: string;
+ skuId?: string;
keyword?: string;
bizType?: StockBizType;
bizId?: string;