diff --git a/src/config-loader.js b/src/config-loader.js index cdedbf4..2ca87ae 100644 --- a/src/config-loader.js +++ b/src/config-loader.js @@ -97,6 +97,22 @@ window.__APP_CONFIG__ = config window.__CONFIG_READY__ = true + if (config?.user?.name_fa) { + document.title = config.user.name_fa + } + + if (config?.user?.avatar) { + const faviconUrl = config.user.avatar + const existingIcons = document.querySelectorAll('link[rel*="icon"]') + existingIcons.forEach((icon) => icon.remove()) + + const link = document.createElement('link') + link.rel = 'icon' + link.type = 'image/png' + link.href = faviconUrl + '?v=' + Date.now() + document.head.appendChild(link) + } + // Resolve the promise if (configResolve) { configResolve(config) diff --git a/src/utils/inputRules.ts b/src/utils/inputRules.ts index a6c9624..01289d7 100644 --- a/src/utils/inputRules.ts +++ b/src/utils/inputRules.ts @@ -32,6 +32,7 @@ import {computed, ref} from 'vue' import type {Rule} from 'ant-design-vue/es/form' import {useWalletStore} from "@/store/walletStore"; import { isCashLikeDealMethod, isMainMetalWalletDealMethod, getInsufficientCashWalletMessage, getInsufficientGoldWalletMessage } from '@/utils/productDealMethod' +import { getCashWalletBalance } from '@/utils/productAssets' export const mobileValidation = (title?: string): Rule => { const label = title ?? 'شماره تلفن' @@ -160,13 +161,14 @@ const checkNumber = async (_rule: Rule, value: number) => { return Promise.reject('استفاده از اعداد اعشاری مجاز نمی باشد') } if (isBuyP){ - if (!walletCash?.walletInfo?.cash && isCashLikeDealMethod(methodP)){ + const availableCash = getCashWalletBalance(walletCash?.walletInfo) + if (!availableCash && isCashLikeDealMethod(methodP)){ return Promise.reject(getInsufficientCashWalletMessage(groupTypeP)) } if (!walletCash?.walletInfo?.gold && isMainMetalWalletDealMethod(methodP)){ return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP)) } - if (priceP * value > walletCash?.walletInfo?.cash && isCashLikeDealMethod(methodP)) + if (priceP * value > availableCash && isCashLikeDealMethod(methodP)) return Promise.reject(getInsufficientCashWalletMessage(groupTypeP)) if (amountP * value > walletCash?.walletInfo?.gold && isMainMetalWalletDealMethod(methodP)) return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP)) diff --git a/src/utils/productAssets.ts b/src/utils/productAssets.ts index fb2cd43..6e66ec7 100644 --- a/src/utils/productAssets.ts +++ b/src/utils/productAssets.ts @@ -334,17 +334,32 @@ export function getTotalMetalWeight( return Number(walletInfo?.treasure ?? walletInfo?.gold_sum ?? walletInfo?.count_gold ?? 0) } -/** فقط موجودی نقدی کیف اصلی — فیلد gold (مثل 0.3 کیلوگرم) جزو دارایی ریالی نیست */ +/** موجودی ریالی کیف اصلی — با main_wallet_products فیلد cash ممکن است کیف محصول باشد */ export function getRialCashAmount( walletInfo?: Record | null, wallets?: UserWalletLine[] | null ): number { + const aggregated = walletInfo?.count_cash_wallet ?? walletInfo?.count_cash + if (aggregated != null && aggregated !== '') { + const parsed = Number(aggregated) + if (!Number.isNaN(parsed)) { + return parsed + } + } + const mainCash = getMainWalletCash(wallets) if (mainCash > 0) { return mainCash } - return Number(walletInfo?.count_cash ?? walletInfo?.cash ?? 0) + return Number(walletInfo?.cash ?? 0) +} + +export function getCashWalletBalance( + walletInfo?: Record | null, + wallets?: UserWalletLine[] | null +): number { + return getRialCashAmount(walletInfo, wallets) } export function getTotalRialEquivalent(walletInfo?: Record | null): number { diff --git a/src/utils/productPrice.ts b/src/utils/productPrice.ts index 0f580de..11d2112 100644 --- a/src/utils/productPrice.ts +++ b/src/utils/productPrice.ts @@ -11,50 +11,84 @@ function applyPriceOffsetPercent(basePrice: number, offsetPercent?: number | nul return Math.round(basePrice * (1 + offset / 100)) } -/** قیمت خرید نمایشی محصول (همان مقداری که در لیست و اکشن‌شیت نشان داده می‌شود) */ -export function getProductBuyPrice(product: Product): number { +/** قیمت پایه بدون کارمزد — اگر صفر باشد نباید فقط cash_fee به‌عنوان قیمت نمایش داده شود */ +export function getProductBaseBuyPrice(product: Product): number { if (isMeltedProductUsingAppPrice(product)) { const tradeBuy = getTradeBuyPrice(lastPrice.value) - const base = tradeBuy > 0 - ? applyPriceOffsetPercent(tradeBuy, product.price_offset_percent) - : (product.price ?? 0) - return base + (product.cash_fee_buy ?? 0) + if (tradeBuy > 0) { + return applyPriceOffsetPercent(tradeBuy, product.price_offset_percent) + } + // provider صفر — آخرین قیمت ذخیره‌شده از API (وقتی use_last_price_if_zero فعال است) + return Number(product.price ?? 0) } if (isMeltedTradeGroup(product.group_type)) { - return (product.price ?? 0) + (product.cash_fee_buy ?? 0) + return Number(product.price ?? 0) } if (isMetalCommodityGroup(product.group_type)) { - const base = (product.price_profit ?? 0) + (product.price ?? 0) - return base + (product.cash_fee_buy ?? 0) + return Number(product.price_profit ?? 0) + Number(product.price ?? 0) } - const basePrice = (product.price ?? 0) + (product.cash_fee_buy ?? 0) - return product.direct_price === 0 - ? basePrice * (product.amount ?? 0) - : basePrice + return Number(product.price ?? 0) } -/** قیمت فروش نمایشی محصول آبشده‌ای */ -export function getProductSellPrice(product: Product): number { +/** قیمت خرید نمایشی محصول (همان مقداری که در لیست و اکشن‌شیت نشان داده می‌شود) */ +export function getProductBuyPrice(product: Product): number { + const base = getProductBaseBuyPrice(product) + if (base <= 0) { + return 0 + } + + const fee = Number(product.cash_fee_buy ?? 0) + + if ( + isMeltedProductUsingAppPrice(product) + || isMeltedTradeGroup(product.group_type) + || isMetalCommodityGroup(product.group_type) + ) { + return base + fee + } + + const withFee = base + fee + return product.direct_price === 0 + ? withFee * Number(product.amount ?? 0) + : withFee +} + +function getProductBaseSellPrice(product: Product): number { if (isMeltedProductUsingAppPrice(product)) { const tradeSell = getTradeSellPrice(lastPrice.value) - const base = tradeSell > 0 - ? applyPriceOffsetPercent(tradeSell, product.price_offset_percent) - : (product.price ?? 0) - return base - (product.cash_fee_sell ?? 0) + if (tradeSell > 0) { + return applyPriceOffsetPercent(tradeSell, product.price_offset_percent) + } + // provider صفر — همان آخرین قیمت ذخیره‌شده (فروش از همان مبنا) + return Number(product.price ?? 0) } if (isMeltedTradeGroup(product.group_type)) { - return (product.price ?? 0) - (product.cash_fee_sell ?? 0) + return Number(product.price ?? 0) } return getTradeSellPrice(lastPrice.value) } +/** قیمت فروش نمایشی محصول آبشده‌ای */ +export function getProductSellPrice(product: Product): number { + const base = getProductBaseSellPrice(product) + if (base <= 0) { + return 0 + } + + if (isMeltedProductUsingAppPrice(product) || isMeltedTradeGroup(product.group_type)) { + return base - Number(product.cash_fee_sell ?? 0) + } + + return base +} + export function isProductPriceInactive(product: Product): boolean { - return getProductBuyPrice(product) <= 0 + return getProductBaseBuyPrice(product) <= 0 } export { isMeltedTradeGroup, isMeltedProductUsingAppPrice } from '@/utils/productCategories' diff --git a/src/views/base/copper&silver/index.vue b/src/views/base/copper&silver/index.vue index a299c29..65369b3 100644 --- a/src/views/base/copper&silver/index.vue +++ b/src/views/base/copper&silver/index.vue @@ -68,14 +68,14 @@ -->
- {{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0), props?.ProductItem?.group_type) }} + {{ formatCashWalletBalanceText(usePriceWithoutType(cashWalletBalance), props?.ProductItem?.group_type) }}
+ getCashWalletBalance(walletStore.walletInfo, userStore.userInfo?.wallets) +) const fundStore = useFundUserStore() const confirmAction = ref(false) const noCompleteVisible = ref(false) @@ -490,7 +494,7 @@ const unitGoldCalculator = computed(() => { }) const unitCashCalculator = computed(() => { - return (walletStore?.walletInfo?.cash ?? 0) / 100 + return cashWalletBalance.value / 100 }) const limitedPrice = computed(() => { diff --git a/src/views/base/gold/index.vue b/src/views/base/gold/index.vue index a2399aa..e9431df 100644 --- a/src/views/base/gold/index.vue +++ b/src/views/base/gold/index.vue @@ -70,14 +70,14 @@ -->
- {{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0), props?.ProductItem?.group_type) }} + {{ formatCashWalletBalanceText(usePriceWithoutType(cashWalletBalance), props?.ProductItem?.group_type) }}
-
موجودی کیف پول ناکافی می باشد.
@@ -237,7 +237,7 @@ import { useFundUserStore } from '@/store/fundStore' import {useConfigStore} from "@/store/configStore"; import { calcFeeInGrams, loadServiceFeeFromSettings } from '@/utils/serviceFee' import { formatCashWalletBalanceText, getWeightUnit } from '@/utils/productDealMethod' -import { formatProductWalletBalanceText, getProductInventoryQuantity } from '@/utils/productAssets' +import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets' import { useWalletAssets } from '@/composables/useWalletAssets' import { isMeltedTradeGroup } from '@/utils/productCategories' import { useSettingsStore } from '@/store/settingsStore' @@ -256,6 +256,9 @@ const { meltedGoldLabel } = storeToRefs(settingsStore) const weightUnit = computed(() => getWeightUnit()) const fundStore = useFundUserStore() const { assetsSummary, loadWalletAssets } = useWalletAssets() +const cashWalletBalance = computed(() => + getCashWalletBalance(walletStore.walletInfo, userStore.userInfo?.wallets) +) const confirmAction = ref(false) const noCompleteVisible = ref(false) const buyItems = ref([]) @@ -514,7 +517,7 @@ function percentChange(val: number) { const unitGoldCalculator = computed(() => productWalletBalance.value / 100) const unitCashCalculator = computed(() => { - return (walletStore?.walletInfo?.cash ?? 0) / 100 + return cashWalletBalance.value / 100 }) const limitedPrice = computed(() => { diff --git a/src/views/base/home/components/PriceStats.vue b/src/views/base/home/components/PriceStats.vue index 59ffe47..c0094fe 100644 --- a/src/views/base/home/components/PriceStats.vue +++ b/src/views/base/home/components/PriceStats.vue @@ -35,4 +35,4 @@ const props = defineProps<{ const highPrice = computed(() => props.price?.up?.buy ?? getTradeBuyPrice(props.price)) const lowPrice = computed(() => props.price?.up?.sell ?? getTradeSellPrice(props.price)) - \ No newline at end of file + diff --git a/src/views/base/home/composables/usePriceChart.ts b/src/views/base/home/composables/usePriceChart.ts index 9a56a33..c24be2f 100644 --- a/src/views/base/home/composables/usePriceChart.ts +++ b/src/views/base/home/composables/usePriceChart.ts @@ -30,4 +30,4 @@ export function usePriceChart() { } return { priceChartSeries, chartLoading, updateChartData, fetchPrices } -} \ No newline at end of file +} diff --git a/src/views/base/products/components/DealProduct.vue b/src/views/base/products/components/DealProduct.vue index 4a1b940..d41776c 100644 --- a/src/views/base/products/components/DealProduct.vue +++ b/src/views/base/products/components/DealProduct.vue @@ -296,7 +296,7 @@ import { productMinOrderCash } from '@/utils/productOrderLimit' import { useWalletAssets } from '@/composables/useWalletAssets' -import { formatProductWalletBalanceText, getProductInventoryQuantity } from '@/utils/productAssets' +import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets' const typeDeal = computed(() => getProductDealMethodOptions(props?.ProductItem?.group_type, isBuy.value)) @@ -352,16 +352,20 @@ const buyMetalWalletBalanceText = computed(() => : goldWalletBalanceText.value ) -const cashWalletBalanceText = computed(() => - formatCashWalletBalanceText( - usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0), - productGroupType.value - ) -) const infoVisible = ref(false) const walletStore = useWalletStore() const { assetsSummary, loadWalletAssets } = useWalletAssets() const userStore = useUserStore() +const cashWalletBalance = computed(() => + getCashWalletBalance(walletStore.walletInfo, userStore.userInfo?.wallets) +) + +const cashWalletBalanceText = computed(() => + formatCashWalletBalanceText( + usePriceWithoutType(cashWalletBalance.value), + productGroupType.value + ) +) const confirmAction = ref(false) const noCompleteVisible = ref(false) const buyItems = ref([]) @@ -622,7 +626,7 @@ const unitGoldCalculator = computed(() => { }) const unitCashCalculator = computed(() => { - return (walletStore?.walletInfo?.cash ?? 0) / 100 + return cashWalletBalance.value / 100 }) const limitedPrice = computed(() => { diff --git a/src/views/base/products/components/ProductItem.vue b/src/views/base/products/components/ProductItem.vue index db94b2f..8a36820 100644 --- a/src/views/base/products/components/ProductItem.vue +++ b/src/views/base/products/components/ProductItem.vue @@ -11,8 +11,7 @@ -
{{usePrice(goldPriceValue)}}
-
{{usePrice(price)}}
+
{{ usePrice(getProductBuyPrice(props.ProductItem)) }}
@@ -33,7 +32,6 @@ import {usePrice} from '@/utils/usePrice'; import {getFileUrl} from '@/utils/file'; import {computed, ref} from "vue"; import { getProductBuyPrice } from '@/utils/productPrice' -import { isMeltedTradeGroup } from '@/utils/productCategories' interface Prop { ProductItem: Product @@ -68,29 +66,6 @@ const displayImage = computed(() => { if (fileUrl) return fileUrl return defaultImages[props.ProductItem.group_type] ?? defaultImg }) -// const typeOfProduct=(val:string)=>{ -// if (val.includes('گوی')) -// return 'گوی' -// if (val.includes('شمش')) -// return 'شمش' -// if (val.includes('مکعب')) -// return 'مکعب' -// if (val.includes('24 عیار')) -// return '24 عیار' -// -// return 'آب شده' -// } - -const price = computed(()=>{ - if(props.ProductItem.direct_price === 0){ - return ((props.ProductItem.price ?? 0) + (props.ProductItem.cash_fee_buy ?? 0)) * props.ProductItem.amount - } - else { - return ((props.ProductItem.price ?? 0) + (props.ProductItem.cash_fee_buy ?? 0)) - } -}) - -const goldPriceValue = computed(() => getProductBuyPrice(props.ProductItem)) diff --git a/src/views/base/wallet/index.vue b/src/views/base/wallet/index.vue index ba91a48..f583afe 100644 --- a/src/views/base/wallet/index.vue +++ b/src/views/base/wallet/index.vue @@ -48,12 +48,12 @@
حداقل مبلغ برداشتی 100 هزار تومان می باشد.
- {{ formatCashWalletBalanceText(usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0)) }} + {{ formatCashWalletBalanceText(usePriceWithoutType(cashWalletBalance)) }}
import { computed, onMounted, ref } from 'vue' import { formatCashWalletBalanceText } from '@/utils/productDealMethod' +import { getCashWalletBalance } from '@/utils/productAssets' import { usePriceWithoutType } from '@/utils/usePrice' import { loading, loadingMore } from '@/utils' import BasicButton from '@/components/BasicPacks/BasicButton.vue' @@ -413,6 +414,9 @@ import { const isDeposit = ref(true) const walletStore = useWalletStore() const userStore = useUserStore() +const cashWalletBalance = computed(() => + getCashWalletBalance(walletStore.walletInfo, userStore.userInfo?.wallets) +) const showAddCard = ref(false) const chargeAccountModal = ref(false) const showConfirmCode = ref(false) @@ -458,11 +462,11 @@ const cardForm = ref({ const disableButton = computed(() => { if (!loading.value) { - if (walletStore?.walletInfo?.cash && !isDeposit.value) { + if (cashWalletBalance.value && !isDeposit.value) { if (cardItems.value.length > 0) { return ( - walletStore?.walletInfo?.cash <= 0 || - walletStore?.walletInfo?.cash < parseInt(form.value?.value) || + cashWalletBalance.value <= 0 || + cashWalletBalance.value < parseInt(form.value?.value) || isNaN(parseInt(form.value?.value)) || parseInt(form.value?.value) < 1000000 ) @@ -477,7 +481,7 @@ const disableButton = computed(() => { const bganim = ref(null) const unitCalculator = computed(() => { - return (walletStore?.walletInfo?.cash ?? 0) / 100 + return cashWalletBalance.value / 100 }) function copyCode(val: string) { diff --git a/src/views/login/components/Register.vue b/src/views/login/components/Register.vue index 63f6858..676d2ff 100644 --- a/src/views/login/components/Register.vue +++ b/src/views/login/components/Register.vue @@ -170,7 +170,7 @@ import DialogVantOneButton from '@/components/DialogVantOneButton.vue' import { registerCustomer } from '@/api/login' import router from '@/router' import {useConfigStore} from "@/store/configStore"; -import {getProjectLoginLogo, getProjectLoginTaglineLines, hasCustomLoginLogoLayout} from "@/utils/config"; +import {getProjectLoginLogo, getProjectLoginTaglineLines, hasCustomLoginLogoLayout, isBoursecuProject} from "@/utils/config"; const config = useConfigStore() // const stepTwoVerify = ref(false) diff --git a/src/views/login/index.vue b/src/views/login/index.vue index f6635d6..7b19824 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -10,10 +10,10 @@
- + - +