price calulator changed

This commit is contained in:
2026-07-02 19:53:25 +03:30
parent eb5fda197e
commit 83cce69069
2 changed files with 140 additions and 42 deletions
+77 -10
View File
@@ -6,6 +6,13 @@ export const serviceFeePercentage = ref<number>(0.01)
/** true = مبالغ رند: فروش → ریال دقیق (کارمزد از طلا)؛ خرید → وزن دقیق (کارمزد از ریال) */
export const feeDeductFromGold = ref(false)
/** آخرین فیلدی که کاربر مستقیم ویرایش کرده — مبنای به‌روزرسانی هنگام تغییر قیمت */
export type TradeInputLock = 'gram' | 'rial' | null
function feeRate() {
return Number(serviceFeePercentage.value)
}
export async function loadServiceFeeFromSettings() {
try {
const settings = await getSettings()
@@ -42,6 +49,47 @@ export function calcGoldAmountFromTargetRial(rialAmount: number, unitPriceRial:
return parseFloat((rialAmount / unitPriceRial).toFixed(6))
}
/** وقتی کاربر گرم را قفل کرده — ریال نمایشی/قابل پرداخت از همان گرم */
export function calcRialFromLockedGram(displayGram: number, unitPriceRial: number, isBuy: boolean) {
const grams = Number(displayGram)
const unit = Number(unitPriceRial)
if (!grams || !unit) return 0
const fee = feeRate()
if (isBuy) {
if (feeDeductFromGold.value) {
return Math.round(grams * unit * (1 + fee))
}
return Math.round(grams * unit)
}
if (feeDeductFromGold.value) {
return Math.round(grams * unit)
}
return Math.round(grams * unit * (1 - fee))
}
/** وقتی کاربر ریال را قفل کرده — گرم نمایشی از همان مبلغ */
export function calcGramFromLockedRial(rialAmount: number, unitPriceRial: number, isBuy: boolean) {
const rial = Number(rialAmount)
const unit = Number(unitPriceRial)
if (!rial || !unit) return 0
const fee = feeRate()
if (isBuy) {
if (feeDeductFromGold.value) {
return parseFloat((rial / (unit * (1 + fee))).toFixed(6))
}
const grossGrams = rial / unit
return parseFloat((grossGrams * (1 - fee)).toFixed(6))
}
if (feeDeductFromGold.value) {
return parseFloat((rial / unit).toFixed(6))
}
return parseFloat((rial / (unit * (1 - fee))).toFixed(6))
}
/** مبلغ نهایی قابل پرداخت (خرید) یا دریافت (فروش) به ریال */
export function calcPayablePriceRial(
finalPriceRial: number,
@@ -57,22 +105,35 @@ export function calcPayablePriceRial(
return isBuy ? finalPriceRial : Math.max(0, finalPriceRial - feeInRial)
}
/** وزن ارسالی به سرور — فروش رند: از مبلغ ریالی هدف */
/** وزن ارسالی به سرور */
export function calcOrderGoldAmount(
goldValue?: number | null,
goldCash?: number | null,
unitPriceRial?: number,
isBuy?: boolean
isBuy?: boolean,
inputLock?: TradeInputLock
) {
const gold = Number(goldValue ?? 0)
if (isBuy || !feeDeductFromGold.value) {
return parseFloat(gold.toFixed(6))
}
const targetCash = calcSellTargetCash(goldCash, goldValue, unitPriceRial)
const cash = Number(goldCash ?? 0)
const unit = Number(unitPriceRial ?? 0)
if (targetCash != null && unit > 0) {
return calcGoldAmountFromTargetRial(targetCash, unit)
if (isBuy && inputLock === 'rial' && !feeDeductFromGold.value && cash > 0 && unit > 0) {
return parseFloat((cash / unit).toFixed(6))
}
if (!isBuy && feeDeductFromGold.value) {
if (inputLock === 'rial' && cash > 0 && unit > 0) {
return calcGoldAmountFromTargetRial(cash, unit)
}
if (inputLock !== 'rial') {
return parseFloat(gold.toFixed(6))
}
const targetCash = calcSellTargetCash(goldCash, goldValue, unitPriceRial, inputLock)
if (targetCash != null && unit > 0) {
return calcGoldAmountFromTargetRial(targetCash, unit)
}
}
return parseFloat(gold.toFixed(6))
}
@@ -80,10 +141,16 @@ export function calcOrderGoldAmount(
export function calcSellTargetCash(
goldCash?: number | null,
goldValue?: number | null,
unitPriceRial?: number
unitPriceRial?: number,
inputLock?: TradeInputLock
) {
if (!feeDeductFromGold.value) return undefined
if (inputLock === 'gram') return undefined
const cash = Number(goldCash ?? 0)
if (!feeDeductFromGold.value || cash <= 0) return undefined
if (cash <= 0) return undefined
if (inputLock === 'rial') return Math.round(cash)
const gold = Number(goldValue ?? 0)
const unit = Number(unitPriceRial ?? 0)
if (gold > 0 && unit > 0) {
+63 -32
View File
@@ -330,7 +330,19 @@ import { getLastPrices, getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@
import type { Product } from '@/models/products'
import { useFundUserStore } from '@/store/fundStore'
import {useConfigStore} from "@/store/configStore";
import { calcFeeInGrams, calcOrderGoldAmount, calcPayablePriceRial, calcSellGoldDebit, calcSellTargetCash, feeDeductFromGold, loadServiceFeeFromSettings } from '@/utils/serviceFee'
import {
calcFeeInGrams,
calcGramFromLockedRial,
calcOrderGoldAmount,
calcPayablePriceRial,
calcRialFromLockedGram,
calcSellGoldDebit,
calcSellTargetCash,
feeDeductFromGold,
loadServiceFeeFromSettings,
serviceFeePercentage,
type TradeInputLock,
} from '@/utils/serviceFee'
import { isStoreClosed, getStoreClosedMessage } from '@/utils/storeHours'
import { formatCashWalletBalanceText, getWeightUnit } from '@/utils/productDealMethod'
import { formatProductWalletBalanceText, getCashWalletBalance, getProductInventoryQuantity } from '@/utils/productAssets'
@@ -386,6 +398,7 @@ const contentClass = computed(() => {
return 'mt-5 px-3 pb-4'
})
const isBuy = ref<boolean>(true)
const inputLock = ref<TradeInputLock>(null)
const tradeProductLabel = computed(() => {
const title = props.ProductItem?.title?.trim()
@@ -436,7 +449,13 @@ const unitPrice = computed(() => {
return isBuy.value ? getTradeBuyPrice(lastPrice.value) : getTradeSellPrice(lastPrice.value)
})
const orderGoldAmount = computed(() =>
calcOrderGoldAmount(form.value?.goldValue, form.value?.goldCash, unitPrice.value, isBuy.value)
calcOrderGoldAmount(
form.value?.goldValue,
form.value?.goldCash,
unitPrice.value,
isBuy.value,
inputLock.value
)
)
const feeInGrams = computed(() => calcFeeInGrams(orderGoldAmount.value))
const finalPrice = computed(() => orderGoldAmount.value * unitPrice.value)
@@ -447,7 +466,7 @@ const payablePrice = computed(() =>
finalPrice.value,
feeInRial.value,
isBuy.value,
!isBuy.value ? form.value?.goldCash : undefined
!isBuy.value && inputLock.value === 'rial' ? form.value?.goldCash : undefined
)
)
const sellGoldDebit = computed(() => calcSellGoldDebit(orderGoldAmount.value, feeInGrams.value))
@@ -620,20 +639,18 @@ onMounted(() => {
})
function percentChange(val: number) {
if (val !== 0)
if (val !== 0) {
if (isBuy.value) {
form.value.goldCash = unitCashCalculator.value * val
calculateGold(form.value.goldCash)
calculateCash(form.value.goldValue)
} else {
// console.log((unitGoldCalculator.value * val).toFixed(2))
// form.value.goldValue = parseFloat((unitGoldCalculator.value * val).toFixed(2))
form.value.goldValue = toFixedDownThreeChar(parseFloat(unitGoldCalculator.value * val))
form.value.goldValue = toFixedDownThreeChar(parseFloat(String(unitGoldCalculator.value * val)))
calculateCash(form.value.goldValue)
}
else {
} else {
form.value.goldValue = undefined
form.value.goldCash = undefined
inputLock.value = null
}
}
@@ -643,13 +660,22 @@ 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)) return
if (!unit || Number.isNaN(unit) || !inputLock.value) return
const goldValue = form.value.goldValue
if (goldValue !== undefined && goldValue !== null && goldValue !== '' && !isNaN(Number(goldValue))) {
calculateCash(Number(goldValue))
if (inputLock.value === 'gram') {
const goldValue = form.value.goldValue
if (goldValue !== undefined && goldValue !== null && goldValue !== '' && !isNaN(Number(goldValue))) {
calculateCash(Number(goldValue))
}
return
}
@@ -666,39 +692,37 @@ watch(
}
)
watch([feeDeductFromGold, () => serviceFeePercentage.value], () => {
syncFormWithLatestPrice()
})
function calculateCash(val: number) {
inputLock.value = 'gram'
priceErrorVisible.value = false
const unit = unitPrice.value
if (!unit || Number.isNaN(unit)) return
form.value.goldCash = val ? parseFloat((val * unit).toFixed(0)) : undefined
if (val === undefined || val === null || Number.isNaN(val)) {
form.value.goldCash = undefined
inputLock.value = null
return
}
form.value.goldCash = calcRialFromLockedGram(val, unit, isBuy.value)
}
function calculateGold(val: number) {
inputLock.value = 'rial'
const unit = unitPrice.value
if (!unit || Number.isNaN(unit)) return
if (isBuy.value) {
if (val) {
form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / unit)))
priceErrorVisible.value = parseInt(String(finalPrice.value)) > 0
} else if (val.toString() === '') {
form.value.goldValue = undefined
priceErrorVisible.value = false
} else {
form.value.goldValue = 0
priceErrorVisible.value = false
}
} else if (val) {
if (!isBuy.value && feeDeductFromGold.value) {
form.value.goldValue = parseFloat((val / unit).toFixed(6))
} else {
form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / unit)))
}
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
@@ -725,6 +749,7 @@ function setIsBuy(val: boolean) {
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')
// bganim?.value?.style.transform = `translateX(${val ? '0' : '-100'});`
@@ -778,7 +803,12 @@ async function ok() {
direction: isBuy.value ? 1 : 2,
price: Math.round(unitPrice.value),
amount: orderGoldAmount.value,
target_cash: calcSellTargetCash(form.value.goldCash, form.value.goldValue, unitPrice.value),
target_cash: calcSellTargetCash(
form.value.goldCash,
form.value.goldValue,
unitPrice.value,
inputLock.value
),
abshode_id: props.ProductItem?.id,
})
confirmAction.value = false
@@ -790,6 +820,7 @@ async function ok() {
goldCash: undefined,
percentWallet: undefined
}
inputLock.value = null
message.success('سفارش شما با موفقیت انجام شد')
await fundStore.getMyFund()
} catch (e) {