From dad6b0b82cadd309631c1e199ca1973fda769509 Mon Sep 17 00:00:00 2001 From: adonis Date: Sun, 14 Jun 2026 21:46:06 +0330 Subject: [PATCH] fix bug --- src/utils/storeHours.ts | 63 +++++++++++++++++++ src/views/base/copper&silver/index.vue | 10 +++ src/views/base/gold/index.vue | 10 +++ .../base/products/components/DealProduct.vue | 10 +++ src/views/base/products/index.vue | 51 ++++++++++----- 5 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 src/utils/storeHours.ts diff --git a/src/utils/storeHours.ts b/src/utils/storeHours.ts new file mode 100644 index 0000000..6a41347 --- /dev/null +++ b/src/utils/storeHours.ts @@ -0,0 +1,63 @@ +import { useSettingsStore } from '@/store/settingsStore' +import { lastPrice } from '@/utils/price' + +export interface StoreTradingHours { + start: string + end: string + closePriceEnabled: boolean +} + +function parseTimeToSeconds(time: string): number { + const parts = time.trim().split(':').map(Number) + const [hours = 0, minutes = 0, seconds = 0] = parts + return hours * 3600 + minutes * 60 + seconds +} + +export function formatTradingTimeDisplay(time: string): string { + const parts = time.trim().split(':') + if (parts.length >= 3) { + return `${parts[0]}:${parts[1]}:${parts[2]}` + } + if (parts.length >= 2) { + return `${parts[0]}:${parts[1]}:00` + } + return time +} + +export function getStoreTradingHours(): StoreTradingHours { + const settings = useSettingsStore() + const closeRaw = settings.getSettingByKey('close_price') + const closePriceEnabled = + closeRaw === true || + closeRaw === 1 || + String(closeRaw ?? 'false').trim().toLowerCase() === 'true' + + return { + start: String(settings.getSettingByKey('startDay') ?? '00:00'), + end: String(settings.getSettingByKey('endDay') ?? '23:59'), + closePriceEnabled, + } +} + +export function isStoreClosedBySchedule(now = new Date()): boolean { + const { start, end, closePriceEnabled } = getStoreTradingHours() + if (!closePriceEnabled) { + return false + } + + const currentSeconds = now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds() + const openSeconds = parseTimeToSeconds(start) + const closeSeconds = parseTimeToSeconds(end) + + return currentSeconds < openSeconds || currentSeconds > closeSeconds +} + +export function isStoreClosed(): boolean { + if (lastPrice.value?.closed === true) { + return true + } + + return isStoreClosedBySchedule() +} + +export const STORE_CLOSED_MESSAGE = 'فروشگاه در حال حاضر بسته است.' diff --git a/src/views/base/copper&silver/index.vue b/src/views/base/copper&silver/index.vue index 65369b3..ebd927c 100644 --- a/src/views/base/copper&silver/index.vue +++ b/src/views/base/copper&silver/index.vue @@ -239,6 +239,7 @@ import {useConfigStore} from "@/store/configStore"; import { calcFeeInGrams } from '@/utils/serviceFee' import { formatCashWalletBalanceText, formatGoldWalletBalanceText } from '@/utils/productDealMethod' import { getCashWalletBalance } from '@/utils/productAssets' +import { isStoreClosed, STORE_CLOSED_MESSAGE } from '@/utils/storeHours' const infoVisible = ref(false) const walletStore = useWalletStore() @@ -325,6 +326,7 @@ const equivalentPrice = computed(() => usePriceWithoutType(feeInRial.value.toFix const disableTransaction = computed(() => loading.value || + isStoreClosed() || form.value?.goldValue === undefined || form.value?.goldValue === '' || form.value?.goldCash === '' || @@ -640,10 +642,18 @@ async function initPrice() { } function okConfirm() { + if (isStoreClosed()) { + message.warning(STORE_CLOSED_MESSAGE) + return + } confirmAction.value = true } async function ok() { + if (isStoreClosed()) { + message.warning(STORE_CLOSED_MESSAGE) + return + } try { loading.value = true infoVisible.value = true diff --git a/src/views/base/gold/index.vue b/src/views/base/gold/index.vue index e9431df..c17c89b 100644 --- a/src/views/base/gold/index.vue +++ b/src/views/base/gold/index.vue @@ -236,6 +236,7 @@ import type { Product } from '@/models/products' import { useFundUserStore } from '@/store/fundStore' import {useConfigStore} from "@/store/configStore"; import { calcFeeInGrams, loadServiceFeeFromSettings } from '@/utils/serviceFee' +import { isStoreClosed, STORE_CLOSED_MESSAGE } from '@/utils/storeHours' import { formatCashWalletBalanceText, getWeightUnit } from '@/utils/productDealMethod' import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets' import { useWalletAssets } from '@/composables/useWalletAssets' @@ -344,6 +345,7 @@ const priceUnavailable = computed(() => { const disableTransaction = computed(() => loading.value || + isStoreClosed() || form.value?.goldValue === undefined || form.value?.goldValue === '' || form.value?.goldCash === '' || @@ -633,6 +635,10 @@ async function initPrice() { } function okConfirm() { + if (isStoreClosed()) { + message.warning(STORE_CLOSED_MESSAGE) + return + } if (cashValidationMessage.value) { message.warning(cashValidationMessage.value) return @@ -641,6 +647,10 @@ function okConfirm() { } async function ok() { + if (isStoreClosed()) { + message.warning(STORE_CLOSED_MESSAGE) + return + } try { loading.value = true infoVisible.value = true diff --git a/src/views/base/products/components/DealProduct.vue b/src/views/base/products/components/DealProduct.vue index d41776c..53b2832 100644 --- a/src/views/base/products/components/DealProduct.vue +++ b/src/views/base/products/components/DealProduct.vue @@ -297,6 +297,7 @@ import { } from '@/utils/productOrderLimit' import { useWalletAssets } from '@/composables/useWalletAssets' import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets' +import { isStoreClosed, STORE_CLOSED_MESSAGE } from '@/utils/storeHours' const typeDeal = computed(() => getProductDealMethodOptions(props?.ProductItem?.group_type, isBuy.value)) @@ -438,6 +439,7 @@ const cashValidationMessage = computed(() => const disableTransaction = computed(() => loading.value || + isStoreClosed() || form.value?.goldValue === undefined || form.value?.goldValue === '' || form.value?.goldCash === '' || @@ -795,11 +797,19 @@ async function initPrice() { // }) function okConfirm() { + if (isStoreClosed()) { + message.warning(STORE_CLOSED_MESSAGE) + return + } confirmAction.value = true refInput.value?.validateFields() } async function ok() { + if (isStoreClosed()) { + message.warning(STORE_CLOSED_MESSAGE) + return + } try { loading.value = true infoVisible.value = true diff --git a/src/views/base/products/index.vue b/src/views/base/products/index.vue index 2ff0e1b..1c5655d 100644 --- a/src/views/base/products/index.vue +++ b/src/views/base/products/index.vue @@ -103,7 +103,13 @@ import { isMetalCommodityGroup, isMeltedTradeGroup } from '@/utils/productCatego import { isBoursecuDealProductGroup } from '@/utils/productDealMethod' import { loadServiceFeeFromSettings } from '@/utils/serviceFee' import { loadProductCategoryTabNames } from '@/utils/categoryTabs' -import { getLastPrices, startLastPricePolling, stopLastPricePolling } from '@/utils/price' +import { getLastPrices, lastPrice, startLastPricePolling, stopLastPricePolling } from '@/utils/price' +import { + formatTradingTimeDisplay, + getStoreTradingHours, + isStoreClosed, + STORE_CLOSED_MESSAGE +} from '@/utils/storeHours' const activekey = ref('طلا' ||'آبشده') const showFilter = ref(false) @@ -114,20 +120,26 @@ const openTime = ref('') const isAfterCloseTime = ref(false) const isProductInactive = ref(false) -watch([openTime, closeTime], ([open, close]) => { - if (!open || !close) return - const now = new Date() - const currentSeconds = now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds() - const [oh, om, os] = open.split(':').map(Number) - const [ch, cm, cs] = close.split(':').map(Number) - const openSeconds = oh * 3600 + om * 60 + os - const closeSeconds = ch * 3600 + cm * 60 + cs - isAfterCloseTime.value = currentSeconds < openSeconds || currentSeconds > closeSeconds +watch([openTime, closeTime], () => { + syncStoreClosedState() }) +function syncStoreClosedState() { + if (isStoreClosed()) { + showFilter.value = false + isAfterCloseTime.value = true + } +} + function clickProduct(item?: Product) { if (!item?.show) return + if (isStoreClosed()) { + showFilter.value = false + isAfterCloseTime.value = true + return + } + if (isProductPriceInactive(item)) { showFilter.value = false isProductInactive.value = true @@ -144,6 +156,11 @@ function onProductOrdered() { } watch(showFilter, (open) => { + if (open && isStoreClosed()) { + showFilter.value = false + isAfterCloseTime.value = true + return + } if (!open) { orderSheetKey.value += 1 } @@ -212,6 +229,8 @@ async function refreshProducts() { } } +watch(() => lastPrice.value?.closed, syncStoreClosedState) + onMounted(async () => { try { loading.value = true @@ -219,10 +238,10 @@ onMounted(async () => { startLastPricePolling() items.value = await getProducts() - if (items.value?.length) { - closeTime.value = items.value[0].auto_close_at - openTime.value = items.value[0].auto_open_at - } + const hours = getStoreTradingHours() + openTime.value = formatTradingTimeDisplay(hours.start) + closeTime.value = formatTradingTimeDisplay(hours.end) + syncStoreClosedState() await loadCategoryTabs() firstItems.value = items.value @@ -239,7 +258,9 @@ onMounted(async () => { } if (router.currentRoute.value.query.state) { - if (router.currentRoute.value.query.product) { + if (isStoreClosed()) { + isAfterCloseTime.value = true + } else if (router.currentRoute.value.query.product) { clickProduct(items.value?.find(x => x.title === 'سکه')) } else { clickProduct(items.value?.find(x => x.title === 'آبشده نقدی'))