From eb07b068aaf004608f1e29af3a5feb45888ed2f4 Mon Sep 17 00:00:00 2001 From: Timi Date: Wed, 9 Sep 2026 13:14:20 +0800 Subject: [PATCH] add occurredAt --- .../product/ProductStockOperationPopup.vue | 70 +++++++++++++++++++ src/types/Product.ts | 1 + 2 files changed, 71 insertions(+) diff --git a/src/pages/product/ProductStockOperationPopup.vue b/src/pages/product/ProductStockOperationPopup.vue index 5136239..965f2ca 100644 --- a/src/pages/product/ProductStockOperationPopup.vue +++ b/src/pages/product/ProductStockOperationPopup.vue @@ -21,6 +21,25 @@ + +
+ + +
+
+ + + import { watch } from "vue"; import { BottomPopup } from "timi-tdesign-mobile"; +import { Time } from "timi-web"; import ProductAPI from "@/api/ProductAPI"; import PhotoScroller from "@/components/PhotoScroller.vue"; import type { @@ -100,6 +132,9 @@ const isSaving = ref(false); const quantity = ref(""); const remark = ref(""); const requestNo = ref(""); +const occurredAtText = ref(""); +const occurredAtDraftText = ref(""); +const occurredAtPickerVisible = ref(false); const photoItems = ref([]); const photoUrlList = computed(() => photoItems.value.map(item => item.url)); const selectedUnitId = ref(""); @@ -107,6 +142,7 @@ const unitPickerVisible = ref(false); const unitDraft = ref([]); const unitPickerZIndex = 12001; const unitPickerOverlayZIndex = unitPickerZIndex - 1; +const minimumDateTimeText = "1970-01-01 00:00"; const isInbound = computed(() => props.operation === "MANUAL_IN" || props.operation === "STOCKTAKE_GAIN"); const selectableUnits = computed(() => (props.sku.unitList || []).filter(unit => isInbound.value ? unit.allowPurchase : unit.allowSale)); @@ -118,10 +154,28 @@ function resetForm(): void { quantity.value = ""; remark.value = ""; requestNo.value = ""; + occurredAtText.value = ""; + occurredAtDraftText.value = ""; + occurredAtPickerVisible.value = false; photoItems.value = []; selectedUnitId.value = selectableUnits.value[0]?.id || ""; } +function openOccurredAtPicker(): void { + occurredAtDraftText.value = occurredAtText.value || Time.formatDateTime(new Date()); + occurredAtPickerVisible.value = true; +} + +function confirmOccurredAt(value?: string | number): void { + occurredAtText.value = String(value || occurredAtDraftText.value); + occurredAtPickerVisible.value = false; +} + +function resetOccurredAt(): void { + occurredAtText.value = ""; + occurredAtDraftText.value = ""; +} + function openUnitPicker(): void { if (selectableUnits.value.length) { unitDraft.value = [selectedUnitId.value]; @@ -170,11 +224,20 @@ function buildRequest(): ProductStockChangeRequest { skuId: props.sku.id || "", skuUnitId: selectedUnitId.value, quantity: quantity.value, + occurredAt: resolveTimestamp(occurredAtText.value), remark: remark.value.trim(), attachmentList: photoItems.value.flatMap(item => item.tempFileId ? [{ tempFileId: item.tempFileId, attachType: item.attachType || "PHOTO" }] : []) }; } +function resolveTimestamp(value: string): number | undefined { + if (!value) { + return undefined; + } + const timestamp = new Date(value.replace(" ", "T")).getTime(); + return Number.isFinite(timestamp) ? timestamp : undefined; +} + async function submit(): Promise { if (isSaving.value || !validate()) { return; @@ -227,5 +290,12 @@ watch(() => [visible.value, props.operation] as const, ([isVisible]) => { align-items: start; justify-content: space-between; } + + .time-actions { + gap: .5rem; + display: flex; + align-items: center; + justify-content: flex-end; + } } diff --git a/src/types/Product.ts b/src/types/Product.ts index c739331..6819ccf 100644 --- a/src/types/Product.ts +++ b/src/types/Product.ts @@ -195,6 +195,7 @@ export type ProductStockChangeRequest = { skuId: string; skuUnitId: string; quantity: number | string; + occurredAt?: number; remark: string; attachmentList: Partial[]; };