added pargar

This commit is contained in:
2026-07-05 20:49:01 +03:30
parent e4d92831c2
commit 51e3c3f0cb
7 changed files with 326 additions and 147 deletions
+113 -96
View File
@@ -24,14 +24,9 @@
<img :src="img1" alt="" class="h-[88px] absolute">
<div class="w-full items-center flex flex-col">
<div class="text-gray-700 font-bold">{{ !isBuy ? 'قیمت فروش' : 'قیمت خرید' }}</div>
<div class="flex gap-1 mt-3 text-xs items-center">
<div class="gold-live-price">
<Vue3Odometer
:key="isBuy ? 'buy' : 'sell'"
:value="displayedGoldPrice"
:class="[!isBuy ? 'text-red-700' : 'text-green-700', 'o-text !text-2xl font-bold color-transition']"
style="font-family: iran-sans; direction: ltr"
/>
<div v-if="price" class="flex gap-1 mt-3 text-xs items-center">
<div :class="!isBuy ? 'text-red-700' : 'text-green-700'" class="font-bold text-2xl color-transition">
{{ usePriceWithoutType(goldPriceValue) }}
</div>
ریال
</div>
@@ -61,7 +56,7 @@
<!-- {{walletStore?.walletInfo?.gold}}-->
<Transition mode="out-in" name="fade">
<div v-if="!isBuy" class="font-bold text-xs">
<div> {{ `موجودی کیف طلا: ${walletStore?.walletInfo?.gold ?? 0} گرم` }}</div>
<div> {{ `موجودی کیف طلا: ${formatGoldAmount(walletStore?.walletInfo?.gold ?? 0)} گرم` }}</div>
<!-- <div v-if="walletStore?.walletInfo?.gold_block !== 0">
{{ `موجودی قابل برداشت طلا: ${walletStore?.walletInfo?.gold_block ?? 0} گرم` }}
</div>-->
@@ -83,13 +78,6 @@
@change="percentChange" />
</a-form-item>
</Transition>
<Transition mode="out-in" name="fade">
<div v-if="priceErrorVisible" class="flex gap-1 items-center text-xs mt-[-15px] text-blue-600">
<BasicIcon icon="vuesax-linear:info-circle" />
ارزش کل وارد شده بر حسب گرم طلا محاسبه خواهد شد و قیمت وارد شده معادل {{ usePrice(parseInt(finalPrice.toFixed(0))) }} می
باشد!
</div>
</Transition>
</div>
</div>
<GoldLoading v-model:show="infoVisible" />
@@ -150,14 +138,14 @@
<div class="flex justify-between ">
<div>وزن:</div>
<div class="flex items-center">
<div class="font-bold">{{ form.goldValue }}</div>
<div class="font-bold">{{ displayTradeGoldAmount }}</div>
<div class="text-xs mr-1">گرم</div>
</div>
</div>
<div class="flex justify-between mt-3">
<div>مظنه:</div>
<div class="flex items-center">
<div class="font-bold">{{ usePriceWithoutType(isBuy ? price.buy ?? 0 : price.sell ?? 0) }}</div>
<div class="font-bold">{{ usePriceWithoutType(Math.round(goldPriceValue)) }}</div>
<div class="text-xs mr-1">ریال</div>
</div>
</div>
@@ -172,7 +160,7 @@
<div v-if="isBuy && feeDeductFromGold" class="flex justify-between mt-3">
<div>طلا دریافتی:</div>
<div class="flex items-center">
<div class="font-bold">{{ form.goldValue }}</div>
<div class="font-bold">{{ displayTradeGoldAmount }}</div>
<div class="text-xs mr-1">گرم (دقیق — کارمزد از ریال)</div>
</div>
</div>
@@ -213,10 +201,10 @@
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import img1 from '@/assets/img/home_ly2.svg'
import { usePrice, usePriceWithoutType } from '@/utils/usePrice'
import { usePrice, usePriceWithoutType, formatGoldAmount } 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'
@@ -238,21 +226,27 @@ import type { Transaction } from '@/models/transaction'
import type { TableEngineInput, TableOutput } from '@/models/table'
import { useInfiniteScroll } from '@vueuse/core'
import { getTransactionTable } from '@/api/transaction'
import { getLastPrices, lastPrice, setIntervalGetAllPrice, stopPriceInterval } from '@/utils/price'
import { getLastPrices, getTradeBuyPrice, getTradeSellPrice, lastPrice, setIntervalGetAllPrice, stopPriceInterval } from '@/utils/price'
import { isStoreClosed, getStoreClosedMessage } from '@/utils/storeHours'
import type { Product } from '@/models/products'
import { useFundUserStore } from '@/store/fundStore'
import {
calcFeeInGrams,
calcGramFromLockedRial,
calcOrderGoldAmount,
calcPayablePriceRial,
calcRialFromLockedGram,
calcSellGoldDebit,
calcSellTargetCash,
calcTradeTargetCash,
feeDeductFromGold,
loadServiceFeeFromSettings
formatTradeGramDisplay,
loadServiceFeeFromSettings,
normalizeOrderGoldAmount,
serviceFeePercentage,
type TradeInputLock,
} from '@/utils/serviceFee'
import Bg_main from '@/components/bg_main.vue'
import Vue3Odometer from 'vue3-odometer'
import 'odometer/themes/odometer-theme-default.css'
const infoVisible = ref(false)
const walletStore = useWalletStore()
const userStore = useUserStore()
@@ -261,7 +255,6 @@ const confirmAction = ref<boolean>(false)
const noCompleteVisible = ref<boolean>(false)
const buyItems = ref<Transaction[]>([])
const sellItems = ref<Transaction[]>([])
const priceErrorVisible = ref<boolean>(false)
const buyTableOutput = ref<TableOutput<Transaction> | null>(null)
const sellTableOutput = ref<TableOutput<Transaction> | null>(null)
const el = ref()
@@ -272,6 +265,7 @@ interface Prop {
const props = withDefaults(defineProps<Prop>(), {})
const isBuy = ref<boolean>(true)
const inputLock = ref<TradeInputLock>(null)
const buyPagination = ref<TableEngineInput>({
filters: [{
@@ -293,10 +287,16 @@ const sellPagination = ref<TableEngineInput>({
})
const unitPrice = computed(() =>
isBuy.value ? (price.value?.buy ?? 0) : (price.value?.sell ?? 0)
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)
@@ -307,13 +307,23 @@ const payablePrice = computed(() =>
finalPrice.value,
feeInRial.value,
isBuy.value,
!isBuy.value ? form.value?.goldCash : undefined
inputLock.value === 'rial' ? form.value?.goldCash : undefined
)
)
const sellGoldDebit = computed(() => calcSellGoldDebit(orderGoldAmount.value, feeInGrams.value))
const displayTradeGoldAmount = computed(() =>
formatTradeGramDisplay(orderGoldAmount.value)
)
const priceUnavailable = computed(() => {
const unit = unitPrice.value
return !unit || Number.isNaN(unit) || unit <= 0
})
const disableTransaction = computed(() =>
loading.value ||
isStoreClosed() ||
form.value?.goldValue === undefined ||
form.value?.goldValue === '' ||
form.value?.goldCash === '' ||
@@ -321,7 +331,7 @@ const disableTransaction = computed(() =>
(isBuy.value ? (form.value?.goldCash ?? 0) < 500000 : (form.value?.goldValue ?? 0) < 0.001) ||
(!isBuy.value && sellGoldDebit.value > (walletStore?.walletInfo?.gold ?? 0)) ||
(isBuy.value && payablePrice.value > (walletStore?.walletInfo?.cash ?? 0)) ||
price.value?.buy === undefined)
priceUnavailable.value)
function refreshTable() {
sellItems.value = []
@@ -518,20 +528,18 @@ onUnmounted(() => {
})
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 = formatTradeGramDisplay(parseFloat(String(unitGoldCalculator.value * val)))
calculateCash(form.value.goldValue)
}
else {
} else {
form.value.goldValue = undefined
form.value.goldCash = undefined
inputLock.value = null
}
}
@@ -544,54 +552,61 @@ const unitCashCalculator = computed(() => {
return (walletStore?.walletInfo?.cash ?? 0) / 100
})
function calculateCash(val: number) {
priceErrorVisible.value = false
// console.log(val)
if (price.value) {
if (isBuy.value) {
if (val) form.value.goldCash = parseFloat((val * price?.value?.buy).toFixed(0))
else form.value.goldCash = undefined
} else {
if (val) form.value.goldCash = parseFloat((val * price?.value?.sell).toFixed(0))
else form.value.goldCash = undefined
function syncFormWithLatestPrice() {
const unit = unitPrice.value
if (!unit || Number.isNaN(unit) || !inputLock.value) return
if (inputLock.value === 'gram') {
const goldValue = form.value.goldValue
if (goldValue !== undefined && goldValue !== null && goldValue !== '' && !isNaN(Number(goldValue))) {
calculateCash(Number(goldValue))
}
return
}
const goldCash = form.value.goldCash
if (goldCash !== undefined && goldCash !== null && goldCash !== '' && !isNaN(Number(goldCash))) {
calculateGold(Number(goldCash))
}
}
watch(
() => [unitPrice.value, isBuy.value],
() => {
syncFormWithLatestPrice()
}
)
watch([feeDeductFromGold, () => serviceFeePercentage.value], () => {
syncFormWithLatestPrice()
})
function calculateCash(val: number) {
inputLock.value = 'gram'
const unit = unitPrice.value
if (!unit || Number.isNaN(unit)) return
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) {
// console.log(val)
// form.value.goldCash = usePriceWithoutType(form.value.goldCash)
if (price.value) {
if (isBuy.value) {
if (val) {
form.value.goldValue = toFixedDownThreeChar(parseFloat(val / price?.value?.buy))
if (parseInt(finalPrice.value) > 0) priceErrorVisible.value = true
if (parseInt(finalPrice.value) === 0) priceErrorVisible.value = false
} else if (val.toString() === '') {
form.value.goldValue = undefined
priceErrorVisible.value = false
} else {
form.value.goldValue = 0
priceErrorVisible.value = false
}
} else {
if (val) {
if (feeDeductFromGold.value) {
form.value.goldValue = parseFloat((val / (price?.value?.sell ?? 1)).toFixed(6))
} else {
form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / price?.value?.sell)))
}
if (parseInt(String(finalPrice.value)) > 0) priceErrorVisible.value = true
if (parseInt(String(finalPrice.value)) === 0) priceErrorVisible.value = false
} else if (val.toString() === '') {
// console.log('sasasasasasa')
form.value.goldValue = undefined
priceErrorVisible.value = false
} else {
form.value.goldValue = 0
priceErrorVisible.value = false
}
}
inputLock.value = 'rial'
const unit = unitPrice.value
if (!unit || Number.isNaN(unit)) return
if (val) {
form.value.goldValue = formatTradeGramDisplay(calcGramFromLockedRial(val, unit, isBuy.value))
} else if (val.toString() === '') {
form.value.goldValue = undefined
inputLock.value = null
} else {
form.value.goldValue = 0
}
}
@@ -613,7 +628,7 @@ 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')
// bganim?.value?.style.transform = `translateX(${val ? '0' : '-100'});`
@@ -629,10 +644,7 @@ const formatter = (value: number) => {
const price = computed((): Price => <Price>lastPrice.value ?? 0)
const displayedGoldPrice = computed(() => {
if (!lastPrice.value) return 0
return isBuy.value ? (lastPrice.value.buy ?? 0) : (lastPrice.value.sell ?? 0)
})
const goldPriceValue = computed(() => unitPrice.value)
async function initPrice() {
try {
@@ -648,18 +660,32 @@ async function initPrice() {
}
function okConfirm() {
if (isStoreClosed()) {
message.warning(getStoreClosedMessage())
return
}
confirmAction.value = true
}
async function ok() {
if (isStoreClosed()) {
message.warning(getStoreClosedMessage())
return
}
try {
loading.value = true
infoVisible.value = true
await createOrder({
direction: isBuy.value ? 1 : 2,
price: Math.round(unitPrice.value),
amount: orderGoldAmount.value,
target_cash: calcSellTargetCash(form.value.goldCash, form.value.goldValue, unitPrice.value),
amount: normalizeOrderGoldAmount(orderGoldAmount.value),
target_cash: calcTradeTargetCash(form.value.goldCash, inputLock.value)
?? calcSellTargetCash(
form.value.goldCash,
form.value.goldValue,
unitPrice.value,
inputLock.value
),
})
await walletStore.getMyWallet()
await router.push({ name: 'transactions' })
@@ -668,6 +694,7 @@ async function ok() {
goldCash: undefined,
percentWallet: undefined
}
inputLock.value = null
// refreshTable()
message.success('سفارش شما با موفقیت انجام شد')
await fundStore.getMyFund()
@@ -716,14 +743,4 @@ async function ok() {
right: 100%;
transform: translate(100%, 0);
}
.gold-live-price {
:deep(.odometer) {
line-height: 1;
}
:deep(.odometer-digit) {
overflow: hidden;
}
}
</style>
@@ -160,7 +160,7 @@ import { useUserStore } from '@/store/userStore'
import { useWalletStore } from '@/store/walletStore'
import { useWalletAssets } from '@/composables/useWalletAssets'
import { resolveAssetsRialValue } from '@/utils/productAssets'
import { usePrice, usePriceWithoutType, useTowDecimal } from '@/utils/usePrice'
import { usePrice, usePriceWithoutType, useTowDecimal, formatGoldAmount } from '@/utils/usePrice'
import {
getLastPrices,
getTradeBuyPrice,
@@ -210,10 +210,10 @@ const balanceLabel = computed(() => {
}
const metal = primaryMetalTotal.value
if (metal && Number(metal.total_weight) > 0) {
return `${Number(metal.total_weight).toFixed(3)} ${metal.unit}`
return `${formatGoldAmount(metal.total_weight)} ${metal.unit}`
}
const fallback = walletStore.walletInfo?.gold_sum ?? userStore.userInfo?.wallet?.count_gold ?? 0
return `${Number(fallback).toFixed(3)} گرم`
return `${formatGoldAmount(fallback)} گرم`
})
const totalRialDisplay = computed(() =>
+3 -3
View File
@@ -457,7 +457,7 @@ import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/swiper-bundle.css';
import img2 from '@/assets/img/banner/2.png'
import Icon from '@/components/BasicPacks/BasicIcon.vue'
import { usePrice, usePriceWithoutType, useTowDecimal } from '../../../utils/usePrice'
import { usePrice, usePriceWithoutType, useTowDecimal, formatGoldAmount } from '../../../utils/usePrice'
import {computed, createVNode, onActivated, onMounted, onUnmounted, ref, watch} from 'vue'
import router from '@/router'
import * as echarts from 'echarts'
@@ -526,14 +526,14 @@ const balanceLabel = computed(() => {
const metal = primaryMetalTotal.value
if (metal && Number(metal.total_weight) > 0) {
return `${Number(metal.total_weight).toFixed(3)} ${metal.unit}`
return `${formatGoldAmount(metal.total_weight)} ${metal.unit}`
}
const fallback =
walletStore.walletInfo?.gold_sum ??
userStore.userInfo?.wallet?.count_gold ??
0
return `${Number(fallback).toFixed(3)} گرم`
return `${formatGoldAmount(fallback)} گرم`
})
const totalRialDisplay = computed(() =>