fixed price
This commit is contained in:
@@ -3,13 +3,17 @@
|
||||
class="w-full relative mt-2 rounded-lg py-3 flex flex-col justify-center home_appear_fade_in transition-colors duration-300"
|
||||
:class="containerClass"
|
||||
>
|
||||
<template v-if="isBoursecu && showStoreClosed">
|
||||
<div class="boursecu-closed-box">
|
||||
<div class="boursecu-closed-box__icon-wrap">
|
||||
<Icon icon="vuesax-linear:lock" size="22" color="#ffffff" />
|
||||
<template v-if="displayState !== 'open'">
|
||||
<div class="status-box" :class="isBoursecu ? 'status-box--boursecu' : 'status-box--default'">
|
||||
<div class="status-box__icon-wrap">
|
||||
<Icon
|
||||
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
||||
size="22"
|
||||
:color="isBoursecu ? '#ffffff' : '#64748b'"
|
||||
/>
|
||||
</div>
|
||||
<div class="boursecu-closed-box__title">فروشگاه بسته است</div>
|
||||
<div class="boursecu-closed-box__hint">{{ storeClosedHint }}</div>
|
||||
<div class="status-box__title">{{ statusTitle }}</div>
|
||||
<div class="status-box__hint">{{ statusHint }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -52,7 +56,11 @@ import { useConfigStore } from '@/store/configStore'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { isBoursecuProject } from '@/utils/config'
|
||||
import { getTradeBuyPrice, lastPrice, percentPriceChanged, price } from '@/utils/price'
|
||||
import { getStoreClosedMessage, isStoreClosed } from '@/utils/storeHours'
|
||||
import {
|
||||
NO_QUOTE_MESSAGE,
|
||||
getPriceDisplayState,
|
||||
getStoreClosedMessage,
|
||||
} from '@/utils/storeHours'
|
||||
import Vue3Odometer from 'vue3-odometer'
|
||||
import 'odometer/themes/odometer-theme-default.css'
|
||||
import { formatSignedPercentChange } from '@/utils/usePrice'
|
||||
@@ -65,26 +73,28 @@ const priceLabel = computed(() =>
|
||||
isBoursecu ? 'قیمت لحظهای کاتد مس' : `قیمت خرید از ${config.config.name_fa}`
|
||||
)
|
||||
|
||||
const showStoreClosed = computed(() => {
|
||||
if (isBoursecu) {
|
||||
return isStoreClosed()
|
||||
}
|
||||
return lastPrice?.value?.goldir === 0 && getTradeBuyPrice(lastPrice.value) === 0
|
||||
})
|
||||
const displayState = computed(() => getPriceDisplayState())
|
||||
|
||||
const storeClosedHint = computed(() => {
|
||||
const custom = userStore.getValueByKey('closed_message')
|
||||
if (typeof custom === 'string' && custom.trim()) {
|
||||
return custom.replace(/<[^>]*>/g, '').trim()
|
||||
const statusTitle = computed(() =>
|
||||
displayState.value === 'closed' ? 'فروشگاه بسته است' : NO_QUOTE_MESSAGE
|
||||
)
|
||||
|
||||
const statusHint = computed(() => {
|
||||
if (displayState.value === 'closed') {
|
||||
const custom = userStore.getValueByKey('closed_message')
|
||||
if (typeof custom === 'string' && custom.trim()) {
|
||||
return custom.replace(/<[^>]*>/g, '').trim()
|
||||
}
|
||||
return getStoreClosedMessage()
|
||||
}
|
||||
return getStoreClosedMessage()
|
||||
return 'در حال حاضر مظنهای برای نمایش وجود ندارد.'
|
||||
})
|
||||
|
||||
const containerClass = computed(() => {
|
||||
if (!isBoursecu) {
|
||||
return 'border-gray-200 border-1'
|
||||
}
|
||||
if (showStoreClosed.value) {
|
||||
if (displayState.value !== 'open') {
|
||||
return 'boursecu-price-box boursecu-price-box--closed'
|
||||
}
|
||||
return 'boursecu-price-box boursecu-price-box--open'
|
||||
@@ -96,7 +106,7 @@ const percentChange = computed(() => {
|
||||
})
|
||||
|
||||
const displayGoldVal = computed(() => {
|
||||
if (showStoreClosed.value) return 0
|
||||
if (displayState.value !== 'open') return 0
|
||||
return getTradeBuyPrice(lastPrice.value)
|
||||
})
|
||||
|
||||
@@ -137,7 +147,7 @@ void price
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.boursecu-closed-box {
|
||||
.status-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -147,30 +157,51 @@ void price
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.boursecu-closed-box__icon-wrap {
|
||||
.status-box__icon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.boursecu-closed-box__title {
|
||||
color: #ffffff;
|
||||
.status-box__title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.boursecu-closed-box__hint {
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
.status-box__hint {
|
||||
font-size: 11px;
|
||||
line-height: 1.6;
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.status-box--boursecu .status-box__icon-wrap {
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.status-box--boursecu .status-box__title {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.status-box--boursecu .status-box__hint {
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.status-box--default .status-box__icon-wrap {
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
.status-box--default .status-box__title {
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.status-box--default .status-box__hint {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.price-change-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -84,7 +84,9 @@ export function useHomePage() {
|
||||
const closedMessage = computed(() => userStore.getValueByKey('closed_message'))
|
||||
const marketClosedText = computed(() => {
|
||||
if (!isStoreClosed()) return ''
|
||||
return closedMessage.value || getStoreClosedMessage()
|
||||
// فقط پیام سفارشی ادمین رو نشون بده — پیام ساعت کاری در CurrentPrice نمایش داده میشه
|
||||
const custom = typeof closedMessage.value === 'string' ? closedMessage.value.trim() : ''
|
||||
return custom || ''
|
||||
})
|
||||
const showClosedMessage = computed(() => !!marketClosedText.value)
|
||||
const limitedPrice = computed(() => walletStore.limitedPrice?.[0])
|
||||
|
||||
@@ -2,17 +2,21 @@
|
||||
<div
|
||||
class="dhome-surface dhome-hero-price"
|
||||
:class="{
|
||||
'dhome-hero-price--boursecu-open': isBoursecu && !showStoreClosed,
|
||||
'dhome-hero-price--boursecu-closed': isBoursecu && showStoreClosed,
|
||||
'dhome-hero-price--boursecu-open': isBoursecu && displayState === 'open',
|
||||
'dhome-hero-price--boursecu-closed': isBoursecu && displayState !== 'open',
|
||||
}"
|
||||
>
|
||||
<template v-if="isBoursecu && showStoreClosed">
|
||||
<div class="dhome-hero-price__closed">
|
||||
<template v-if="displayState !== 'open'">
|
||||
<div class="dhome-hero-price__closed" :class="{ 'dhome-hero-price__closed--default': !isBoursecu }">
|
||||
<div class="dhome-hero-price__closed-icon">
|
||||
<BasicIcon icon="vuesax-linear:lock" size="22" color="#ffffff" />
|
||||
<BasicIcon
|
||||
:icon="displayState === 'closed' ? 'vuesax-linear:lock' : 'vuesax-linear:info-circle'"
|
||||
size="22"
|
||||
:color="isBoursecu ? '#ffffff' : '#64748b'"
|
||||
/>
|
||||
</div>
|
||||
<p class="dhome-hero-price__closed-title">فروشگاه بسته است</p>
|
||||
<p class="dhome-hero-price__closed-hint">{{ storeClosedHint }}</p>
|
||||
<p class="dhome-hero-price__closed-title">{{ statusTitle }}</p>
|
||||
<p class="dhome-hero-price__closed-hint">{{ statusHint }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -54,30 +58,36 @@ import { useConfigStore } from '@/store/configStore'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { isBoursecuProject } from '@/utils/config'
|
||||
import { getTradeBuyPrice, lastPrice, percentPriceChanged } from '@/utils/price'
|
||||
import { getStoreClosedMessage, isStoreClosed } from '@/utils/storeHours'
|
||||
import {
|
||||
NO_QUOTE_MESSAGE,
|
||||
getPriceDisplayState,
|
||||
getStoreClosedMessage,
|
||||
} from '@/utils/storeHours'
|
||||
import { formatSignedPercentChange } from '@/utils/usePrice'
|
||||
|
||||
const config = useConfigStore()
|
||||
const userStore = useUserStore()
|
||||
const isBoursecu = isBoursecuProject()
|
||||
|
||||
const showStoreClosed = computed(() => {
|
||||
if (isBoursecu) {
|
||||
return isStoreClosed()
|
||||
}
|
||||
return lastPrice?.value?.goldir === 0 && getTradeBuyPrice(lastPrice.value) === 0
|
||||
})
|
||||
const displayState = computed(() => getPriceDisplayState())
|
||||
|
||||
const storeClosedHint = computed(() => {
|
||||
const custom = userStore.getValueByKey('closed_message')
|
||||
if (typeof custom === 'string' && custom.trim()) {
|
||||
return custom.replace(/<[^>]*>/g, '').trim()
|
||||
const statusTitle = computed(() =>
|
||||
displayState.value === 'closed' ? 'فروشگاه بسته است' : NO_QUOTE_MESSAGE
|
||||
)
|
||||
|
||||
const statusHint = computed(() => {
|
||||
if (displayState.value === 'closed') {
|
||||
const custom = userStore.getValueByKey('closed_message')
|
||||
if (typeof custom === 'string' && custom.trim()) {
|
||||
return custom.replace(/<[^>]*>/g, '').trim()
|
||||
}
|
||||
return getStoreClosedMessage()
|
||||
}
|
||||
return getStoreClosedMessage()
|
||||
return 'در حال حاضر مظنهای برای نمایش وجود ندارد.'
|
||||
})
|
||||
|
||||
const displayGoldVal = computed(() => {
|
||||
if (showStoreClosed.value) return 0
|
||||
if (displayState.value !== 'open') return 0
|
||||
return getTradeBuyPrice(lastPrice.value)
|
||||
})
|
||||
|
||||
@@ -143,4 +153,18 @@ const percentChange = computed(() => {
|
||||
line-height: 1.7;
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.dhome-hero-price__closed--default {
|
||||
.dhome-hero-price__closed-icon {
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
.dhome-hero-price__closed-title {
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.dhome-hero-price__closed-hint {
|
||||
color: #64748b;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
subtitle="محصول مورد نظر را انتخاب کنید و سفارش خود را ثبت کنید"
|
||||
/>
|
||||
|
||||
<!-- بنر بسته بودن فروشگاه -->
|
||||
<div v-if="storeClosed" class="dproducts-closed-banner">
|
||||
<span>🔒</span>
|
||||
<span class="dproducts-closed-banner__title">فروشگاه بسته است</span>
|
||||
<span v-if="storeClosedMessage" class="dproducts-closed-banner__hint">— {{ storeClosedMessage }}</span>
|
||||
</div>
|
||||
|
||||
<div class="dproducts-tabs">
|
||||
<button
|
||||
type="button"
|
||||
@@ -50,6 +57,8 @@
|
||||
import DesktopPageTopbar from '@/layouts/components/DesktopPageTopbar.vue'
|
||||
import DesktopProductCard from './components/DesktopProductCard.vue'
|
||||
import { useProductsPageContext } from '../composables/useProductsPage'
|
||||
import { getPriceDisplayState, isStoreClosedBySchedule, getStoreClosedMessage } from '@/utils/storeHours'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const {
|
||||
activekey,
|
||||
@@ -60,6 +69,34 @@ const {
|
||||
clickProduct,
|
||||
isProductPriceInactive,
|
||||
} = useProductsPageContext()
|
||||
|
||||
const storeClosed = computed(() => getPriceDisplayState() === 'closed' || isStoreClosedBySchedule())
|
||||
const storeClosedMessage = computed(() => getStoreClosedMessage())
|
||||
</script>
|
||||
|
||||
<style lang="less" src="./styles/desktop-products.less"></style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.dproducts-closed-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: rgba(239, 68, 68, 0.07);
|
||||
border: 1px solid rgba(239, 68, 68, 0.22);
|
||||
border-radius: 10px;
|
||||
padding: 10px 16px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 13px;
|
||||
direction: rtl;
|
||||
|
||||
&__title {
|
||||
font-weight: 700;
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
&__hint {
|
||||
color: #9b1c1c;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,6 +6,16 @@
|
||||
<MobilePageHeader title="خرید و فروش" />
|
||||
<a-spin :spinning="loading">
|
||||
<div class="!h-full overflow-y-scroll mpage-content mpage-scroll">
|
||||
|
||||
<!-- بنر بسته بودن فروشگاه -->
|
||||
<div v-if="storeClosed" class="mx-4 mt-4 closed-banner">
|
||||
<div class="closed-banner__icon">🔒</div>
|
||||
<div class="closed-banner__body">
|
||||
<div class="closed-banner__title">فروشگاه بسته است</div>
|
||||
<div v-if="storeClosedMessage" class="closed-banner__hint">{{ storeClosedMessage }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex justify-center top-0 py-5">
|
||||
<ARadioGroup
|
||||
v-model:value="activekey"
|
||||
@@ -44,6 +54,8 @@ import img from '@/assets/img/user_ly1.svg'
|
||||
import MobilePageHeader from '@/layouts/components/MobilePageHeader.vue'
|
||||
import ProductItem from '@/views/base/products/components/ProductItem.vue'
|
||||
import { useProductsPageContext } from '../composables/useProductsPage'
|
||||
import { getPriceDisplayState, isStoreClosedBySchedule, getStoreClosedMessage } from '@/utils/storeHours'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const {
|
||||
activekey,
|
||||
@@ -54,6 +66,9 @@ const {
|
||||
clickProduct,
|
||||
isProductPriceInactive,
|
||||
} = useProductsPageContext()
|
||||
|
||||
const storeClosed = computed(() => getPriceDisplayState() === 'closed' || isStoreClosedBySchedule())
|
||||
const storeClosedMessage = computed(() => getStoreClosedMessage())
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@@ -61,4 +76,38 @@ const {
|
||||
--un-text-opacity: 1;
|
||||
color: rgba(206, 163, 76, var(--un-text-opacity)) !important;
|
||||
}
|
||||
|
||||
.closed-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background: rgba(239, 68, 68, 0.08);
|
||||
border: 1px solid rgba(239, 68, 68, 0.25);
|
||||
border-radius: 12px;
|
||||
padding: 12px 14px;
|
||||
direction: rtl;
|
||||
|
||||
&__icon {
|
||||
font-size: 22px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
&__hint {
|
||||
font-size: 11px;
|
||||
color: #9b1c1c;
|
||||
margin-top: 3px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user