diff --git a/src/utils/serviceFee.ts b/src/utils/serviceFee.ts index 48f7c07..6b1a7c7 100644 --- a/src/utils/serviceFee.ts +++ b/src/utils/serviceFee.ts @@ -65,6 +65,44 @@ export function formatTradeGramInputValue(grams?: number | null): string | undef return value.toFixed(TRADE_GRAM_INPUT_DECIMALS) } +/** متن اینپوت گرم — فقط نمایش سه‌رقمی؛ منبع حقیقت همان گرم دقیق است */ +export function tradeGramInputDisplay(exactGrams?: number | string | null): string { + if (exactGrams === undefined || exactGrams === null || exactGrams === '') return '' + const n = Number(exactGrams) + if (!Number.isFinite(n) || n <= 0) return '' + return formatTradeGramInputValue(n) ?? '' +} + +/** گرم دقیق از درصد کیف — بدون رند نمایشی اینپوت */ +export function exactGoldFromWalletPercent(balance: number, percent: number): number { + if (!(Number(percent) > 0) || !(Number(balance) > 0)) return 0 + return normalizeOrderGoldAmount((Number(balance) * Number(percent)) / 100) +} + +/** + * اگر متن اینپوت همان نمایش سه‌رقمی مقدار دقیق فعلی باشد، دقیق را نگه می‌دارد. + * در غیر این صورت عدد تایپ‌شده منبع حقیقت می‌شود. + */ +export function goldFromGramInputDisplay( + raw: unknown, + exactGrams?: number | string | null +): number | undefined { + if (raw === '' || raw == null) return undefined + const text = String(raw).trim() + if (text === '') return undefined + const typed = Number(text) + if (!Number.isFinite(typed) || typed <= 0) return undefined + + const exact = Number(exactGrams) + if (Number.isFinite(exact) && exact > 0) { + const shown = formatTradeGramInputValue(exact) + if (shown != null && text === shown) { + return normalizeOrderGoldAmount(exact) + } + } + return normalizeOrderGoldAmount(typed) +} + function feeRate() { return Number(serviceFeePercentage.value) } diff --git a/src/views/base/gold/index.vue b/src/views/base/gold/index.vue index 182d9a8..175c478 100644 --- a/src/views/base/gold/index.vue +++ b/src/views/base/gold/index.vue @@ -81,10 +81,10 @@ type="price" @onchange="calculateGold" /> - + size="large" type="text" inputmode="decimal" />
{{ cashValidationMessage }} @@ -289,7 +289,9 @@ import { calcTradeTargetCash, buildTradeConfirmBreakdown, formatTradeGramDisplay, - formatTradeGramInputValue, + tradeGramInputDisplay, + exactGoldFromWalletPercent, + goldFromGramInputDisplay, loadServiceFeeFromSettings, normalizeOrderGoldAmount, serviceFeePercentage, @@ -306,7 +308,7 @@ import { resolveProductTradeIsBuy, } from '@/utils/productTradeOpen' import { formatCashWalletBalanceText, getWeightUnit } from '@/utils/productDealMethod' -import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets' +import { formatProductWalletBalanceText, getCashWalletBalance } from '@/utils/productAssets' import { useWalletAssets } from '@/composables/useWalletAssets' import { usesQuantityTrade } from '@/utils/productCategories' import { useSettingsStore } from '@/store/settingsStore' @@ -367,11 +369,7 @@ const tradeProductLabel = computed(() => { const amountFieldLabel = computed(() => `مقدار ${tradeProductLabel.value}`) const productWalletBalance = computed(() => - getProductInventoryQuantity( - assetsSummary.value?.inventory_cards ?? [], - props.ProductItem?.id, - walletStore?.walletInfo?.gold - ) + Number(walletStore?.walletInfo?.gold ?? 0) ) const productWalletBalanceText = computed(() => @@ -443,6 +441,24 @@ const displayTradeGoldAmount = computed(() => formatTradeGramDisplay(orderGoldAmount.value) ) +const goldValueInput = computed({ + get() { + const display = tradeGramInputDisplay(form.value.goldValue) + return display === '' ? undefined : display + }, + set(raw: string | number | null | undefined) { + const next = goldFromGramInputDisplay(raw, form.value.goldValue) + form.value.goldValue = next + if (next == null) { + form.value.goldCash = undefined + form.value.percentWallet = 0 + inputLock.value = null + return + } + calculateCash(next) + }, +}) + const feeFormHint = computed(() => buildTradeConfirmBreakdown({ isBuy: isBuy.value, @@ -634,9 +650,10 @@ function percentChange(val: number) { form.value.goldCash = unitCashCalculator.value * val calculateGold(form.value.goldCash) } else { - form.value.goldValue = formatTradeGramInputValue(parseFloat(String(unitGoldCalculator.value * val))) - if (form.value.goldValue != null) { - calculateCash(Number(form.value.goldValue)) + const grams = exactGoldFromWalletPercent(productWalletBalance.value, val) + form.value.goldValue = grams > 0 ? grams : undefined + if (grams > 0) { + calculateCash(grams) } } } else { @@ -646,8 +663,6 @@ function percentChange(val: number) { } } -const unitGoldCalculator = computed(() => productWalletBalance.value / 100) - const unitCashCalculator = computed(() => { return cashWalletBalance.value / 100 }) @@ -701,7 +716,8 @@ function calculateGold(val: number) { if (!unit || Number.isNaN(unit)) return if (val) { - form.value.goldValue = formatTradeGramInputValue(calcGramFromLockedRial(val, unit, isBuy.value)) + const grams = calcGramFromLockedRial(val, unit, isBuy.value) + form.value.goldValue = grams > 0 ? grams : undefined } else if (val.toString() === '') { form.value.goldValue = undefined inputLock.value = null