From 212bfb1cc13587302aaad51328f07c8aaac5aec5 Mon Sep 17 00:00:00 2001 From: adonis Date: Sat, 4 Jul 2026 12:06:02 +0330 Subject: [PATCH] fixed amount --- src/utils/productAssets.ts | 6 +++-- src/utils/productDealMethod.ts | 5 ++-- src/utils/serviceFee.ts | 41 +++++++++++++++++++++-------- src/utils/usePrice.ts | 2 +- src/views/base/gold/index.vue | 47 ++++++++++------------------------ 5 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/utils/productAssets.ts b/src/utils/productAssets.ts index 653d9c9..b2ca6b8 100644 --- a/src/utils/productAssets.ts +++ b/src/utils/productAssets.ts @@ -1,5 +1,5 @@ import type { Product } from '@/models/products' -import { formatWeightAmount, usePriceWithoutType } from '@/utils/usePrice' +import { formatGoldAmount, formatWeightAmount, usePriceWithoutType } from '@/utils/usePrice' import type { UserWalletLine } from '@/models/wallet' import type { ProductFile } from '@/utils/file' import type { WalletInventoryCard, WalletMetalTotal } from '@/models/walletAssets' @@ -587,8 +587,10 @@ export function formatProductWalletBalanceText( const quantity = card ? Number(card.quantity ?? 0) : Number(mainWalletGold ?? 0) const unit = card?.unit ?? getProductQuantityUnit(product) const title = product?.title?.trim() || 'محصول' + const formattedQty = + unit === 'عدد' ? usePriceWithoutType(quantity, false) : formatGoldAmount(quantity) - return `موجودی کیف ${title}: ${quantity} ${unit}` + return `موجودی کیف ${title}: ${formattedQty} ${unit}` } export function isSingleMetalCatalog(metalIds: number[]): boolean { diff --git a/src/utils/productDealMethod.ts b/src/utils/productDealMethod.ts index bb4ece3..cf94163 100644 --- a/src/utils/productDealMethod.ts +++ b/src/utils/productDealMethod.ts @@ -13,6 +13,7 @@ import { usesQuantityTrade, } from '@/utils/productCategories' import { formatInventoryCardValue } from '@/utils/productAssets' +import { TRADE_GRAM_DISPLAY_DECIMALS } from '@/utils/serviceFee' import { formatGoldAmount } from '@/utils/usePrice' /** @deprecated از isMeltedTradeGroup استفاده کنید */ @@ -636,8 +637,6 @@ export function resolveTransactionTradeProduct( return item.wallet?.product ?? null } -const MELTED_GOLD_TRANSACTION_DECIMALS = 5 - /** معامله آبشده / کیف طلای اصلی — نه سکه و محصول تعدادی */ export function isMeltedGoldTransaction( item?: (TransactionTradeProductSource & { type?: number | null; title?: string | null }) | null, @@ -685,7 +684,7 @@ export function formatTransactionGoldAmount( item?: (TransactionTradeProductSource & { type?: number | null; title?: string | null }) | null, amount?: number | null, ): string { - const decimals = isMeltedGoldTransaction(item) ? MELTED_GOLD_TRANSACTION_DECIMALS : 3 + const decimals = isMeltedGoldTransaction(item) ? TRADE_GRAM_DISPLAY_DECIMALS : 3 return formatGoldAmount(amount, decimals) } diff --git a/src/utils/serviceFee.ts b/src/utils/serviceFee.ts index b3bd3cf..d5f2d2b 100644 --- a/src/utils/serviceFee.ts +++ b/src/utils/serviceFee.ts @@ -9,6 +9,24 @@ export const feeDeductFromGold = ref(false) /** آخرین فیلدی که کاربر مستقیم ویرایش کرده — مبنای به‌روزرسانی هنگام تغییر قیمت */ export type TradeInputLock = 'gram' | 'rial' | null +/** حداکثر اعشار ذخیره/ارسال به سرور (مطابق orders.amount) */ +export const TRADE_GRAM_STORAGE_DECIMALS = 10 + +/** حداکثر اعشار نمایش به کاربر در اپ */ +export const TRADE_GRAM_DISPLAY_DECIMALS = 5 + +export function normalizeOrderGoldAmount(grams?: number | null): number { + const value = Number(grams ?? 0) + if (!Number.isFinite(value) || value === 0) return 0 + return parseFloat(value.toFixed(TRADE_GRAM_STORAGE_DECIMALS)) +} + +export function formatTradeGramDisplay(grams?: number | null): number { + const value = Number(grams ?? 0) + if (!Number.isFinite(value)) return 0 + return parseFloat(value.toFixed(TRADE_GRAM_DISPLAY_DECIMALS)) +} + function feeRate() { return Number(serviceFeePercentage.value) } @@ -46,7 +64,7 @@ export function calcFeeInGrams(goldValue?: number | null) { /** گرم معادل برای دریافت دقیق مبلغ ریالی در فروش */ export function calcGoldAmountFromTargetRial(rialAmount: number, unitPriceRial: number) { if (!rialAmount || !unitPriceRial) return 0 - return parseFloat((rialAmount / unitPriceRial).toFixed(6)) + return normalizeOrderGoldAmount(rialAmount / unitPriceRial) } /** وقتی کاربر گرم را قفل کرده — ریال نمایشی/قابل پرداخت از همان گرم */ @@ -78,16 +96,15 @@ export function calcGramFromLockedRial(rialAmount: number, unitPriceRial: number if (isBuy) { if (feeDeductFromGold.value) { - return parseFloat((rial / (unit * (1 + fee))).toFixed(6)) + return rial / (unit * (1 + fee)) } - const grossGrams = rial / unit - return parseFloat((grossGrams * (1 - fee)).toFixed(6)) + return (rial / unit) * (1 - fee) } if (feeDeductFromGold.value) { - return parseFloat((rial / unit).toFixed(6)) + return rial / unit } - return parseFloat((rial / (unit * (1 - fee))).toFixed(6)) + return rial / (unit * (1 - fee)) } /** مبلغ ریالی قفل‌شده توسط کاربر — برای ارسال به سرور */ @@ -131,8 +148,12 @@ export function calcOrderGoldAmount( const cash = Number(goldCash ?? 0) const unit = Number(unitPriceRial ?? 0) - if (isBuy && inputLock === 'rial' && !feeDeductFromGold.value && cash > 0 && unit > 0) { - return parseFloat((cash / unit).toFixed(6)) + if (isBuy && inputLock === 'rial' && cash > 0 && unit > 0) { + if (feeDeductFromGold.value) { + const fee = feeRate() + return normalizeOrderGoldAmount(cash / (unit * (1 + fee))) + } + return normalizeOrderGoldAmount(cash / unit) } if (!isBuy && feeDeductFromGold.value) { @@ -140,7 +161,7 @@ export function calcOrderGoldAmount( return calcGoldAmountFromTargetRial(cash, unit) } if (inputLock !== 'rial') { - return parseFloat(gold.toFixed(6)) + return normalizeOrderGoldAmount(gold) } const targetCash = calcSellTargetCash(goldCash, goldValue, unitPriceRial, inputLock) if (targetCash != null && unit > 0) { @@ -148,7 +169,7 @@ export function calcOrderGoldAmount( } } - return parseFloat(gold.toFixed(6)) + return normalizeOrderGoldAmount(gold) } /** مبلغ ریالی دقیق دریافتی در فروش (فقط وقتی کاربر با ریال وارد کرده) */ diff --git a/src/utils/usePrice.ts b/src/utils/usePrice.ts index 3670f25..59de100 100644 --- a/src/utils/usePrice.ts +++ b/src/utils/usePrice.ts @@ -143,7 +143,7 @@ export function getTransactionGoldAmount(item: TransactionPriceSource): number { return gold } -export function formatGoldAmount(amount?: number | null, decimals = 3): string { +export function formatGoldAmount(amount?: number | null, decimals = 5): string { const num = Number(amount) if (!Number.isFinite(num)) return '0' return formatGroupedPrice(Number(num.toFixed(decimals)), false) diff --git a/src/views/base/gold/index.vue b/src/views/base/gold/index.vue index af86fcf..ba2802a 100644 --- a/src/views/base/gold/index.vue +++ b/src/views/base/gold/index.vue @@ -102,20 +102,6 @@ @change="percentChange" /> - - -
- - ارزش کل وارد شده بر حسب گرم طلا محاسبه خواهد شد و قیمت وارد شده معادل {{ usePrice(parseInt(finalPrice.toFixed(0))) }} می - باشد! -
-
@@ -173,7 +159,7 @@
وزن:
-
{{ form.goldValue }}
+
{{ displayTradeGoldAmount }}
{{ weightUnit }}
@@ -195,7 +181,7 @@
طلا دریافتی:
-
{{ form.goldValue }}
+
{{ displayTradeGoldAmount }}
{{ weightUnit }} (دقیق — کارمزد از ریال)
@@ -235,7 +221,7 @@
وزن:
-
{{ form.goldValue }}
+
{{ displayTradeGoldAmount }}
{{ weightUnit }}
@@ -257,7 +243,7 @@
طلا دریافتی:
-
{{ form.goldValue }}
+
{{ displayTradeGoldAmount }}
{{ weightUnit }} (دقیق — کارمزد از ریال)
@@ -306,7 +292,7 @@ import img1 from '@/assets/img/home_ly2.svg' import { usePrice, usePriceWithoutType } from '@/utils/usePrice' import BasicInput from '@/components/BasicPacks/BasicInput.vue' import type { Gold } from '@/models/gold' -import { isIphone, loading, loadingMore, toFixedDownThreeChar } from '@/utils' +import { isIphone, loading, loadingMore } from '@/utils' import BasicButton from '@/components/BasicPacks/BasicButton.vue' import router from '@/router' import { useWalletStore } from '@/store/walletStore' @@ -347,7 +333,9 @@ import { calcSellTargetCash, calcTradeTargetCash, feeDeductFromGold, + formatTradeGramDisplay, loadServiceFeeFromSettings, + normalizeOrderGoldAmount, serviceFeePercentage, type TradeInputLock, } from '@/utils/serviceFee' @@ -380,7 +368,6 @@ const confirmAction = ref(false) const noCompleteVisible = ref(false) const buyItems = ref([]) const sellItems = ref([]) -const priceErrorVisible = ref(false) const buyTableOutput = ref | null>(null) const sellTableOutput = ref | null>(null) const el = ref() @@ -480,6 +467,10 @@ const payablePrice = computed(() => ) const sellGoldDebit = computed(() => calcSellGoldDebit(orderGoldAmount.value, feeInGrams.value)) +const displayTradeGoldAmount = computed(() => + formatTradeGramDisplay(orderGoldAmount.value) +) + const minOrderCash = computed(() => productMinOrderCash(props.ProductItem, isBuy.value)) const maxOrderCash = computed(() => productMaxOrderCash(props.ProductItem)) const cashValidationMessage = computed(() => @@ -653,7 +644,7 @@ function percentChange(val: number) { form.value.goldCash = unitCashCalculator.value * val calculateGold(form.value.goldCash) } else { - form.value.goldValue = toFixedDownThreeChar(parseFloat(String(unitGoldCalculator.value * val))) + form.value.goldValue = formatTradeGramDisplay(parseFloat(String(unitGoldCalculator.value * val))) calculateCash(form.value.goldValue) } } else { @@ -669,13 +660,6 @@ const unitCashCalculator = computed(() => { return cashWalletBalance.value / 100 }) -function formatTradeGramDisplay(grams: number) { - if (Number(serviceFeePercentage.value) > 0) { - return parseFloat(grams.toFixed(6)) - } - return toFixedDownThreeChar(grams) -} - function syncFormWithLatestPrice() { const unit = unitPrice.value if (!unit || Number.isNaN(unit) || !inputLock.value) return @@ -707,7 +691,6 @@ watch([feeDeductFromGold, () => serviceFeePercentage.value], () => { function calculateCash(val: number) { inputLock.value = 'gram' - priceErrorVisible.value = false const unit = unitPrice.value if (!unit || Number.isNaN(unit)) return @@ -727,14 +710,11 @@ function calculateGold(val: number) { if (val) { form.value.goldValue = formatTradeGramDisplay(calcGramFromLockedRial(val, unit, isBuy.value)) - priceErrorVisible.value = parseInt(String(finalPrice.value)) > 0 } else if (val.toString() === '') { form.value.goldValue = undefined - priceErrorVisible.value = false inputLock.value = null } else { form.value.goldValue = 0 - priceErrorVisible.value = false } } @@ -757,7 +737,6 @@ function setIsBuy(val: boolean) { form.value.goldValue = undefined form.value.goldCash = undefined form.value.percentWallet = 0 - priceErrorVisible.value = false inputLock.value = null // console.log(bganim.value.classList) // bganim?.value?.classList.add(val?'right':'left') @@ -814,7 +793,7 @@ async function ok() { await createOrder({ direction: isBuy.value ? 1 : 2, price: Math.round(unitPrice.value), - amount: orderGoldAmount.value, + amount: normalizeOrderGoldAmount(orderGoldAmount.value), target_cash: calcTradeTargetCash(form.value.goldCash, inputLock.value) ?? calcSellTargetCash( form.value.goldCash,