widthdraw and deposit
This commit is contained in:
+6
-3
@@ -1,10 +1,13 @@
|
||||
import useAxios from '@/utils/useAxios'
|
||||
import type { Card, Wallet, WithdrawConfirm } from '@/models/wallet'
|
||||
import type {Transaction} from '@/models/transaction'
|
||||
import type {Address} from "@/models/address";
|
||||
import type { WalletAssetsSummary } from '@/models/walletAssets'
|
||||
import type { Transaction } from '@/models/transaction'
|
||||
|
||||
export const getWallet = async () => await useAxios.get<Wallet>(`/customer/wallet/me`)
|
||||
|
||||
export const getWalletAssets = async () =>
|
||||
await useAxios.get<WalletAssetsSummary>(`/customer/wallet/assets`)
|
||||
|
||||
export const withdraw = async (obj: Transaction): Promise<any> => {
|
||||
return await useAxios.post<Transaction>(`/customer/wallet/withdraw`, obj)
|
||||
}
|
||||
@@ -24,5 +27,5 @@ export async function deleteCard(id: number) {
|
||||
export const getActivatedCards = async () => await useAxios.get<Card[]>(`/customer/account/active`)
|
||||
|
||||
export const confirmCode = async (params: WithdrawConfirm): Promise<any> => {
|
||||
return await useAxios.post(`/customer/wallet/withdraw/otp` , params)
|
||||
return await useAxios.post(`/customer/wallet/withdraw/otp`, params)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { computed, ref } from 'vue'
|
||||
import { getProducts } from '@/api/products'
|
||||
import type { Product } from '@/models/products'
|
||||
import {
|
||||
catalogHasCountBasedProducts,
|
||||
catalogHasMeltedProducts,
|
||||
getCatalogMetalIds,
|
||||
isSingleMetalCatalog,
|
||||
} from '@/utils/productAssets'
|
||||
|
||||
const catalogProducts = ref<Product[]>([])
|
||||
let catalogPromise: Promise<Product[]> | null = null
|
||||
|
||||
export function useProductCatalog() {
|
||||
async function loadCatalog(force = false) {
|
||||
if (!force && catalogProducts.value.length) {
|
||||
return catalogProducts.value
|
||||
}
|
||||
|
||||
if (!force && catalogPromise) {
|
||||
return catalogPromise
|
||||
}
|
||||
|
||||
catalogPromise = getProducts()
|
||||
.then((products) => {
|
||||
catalogProducts.value = products ?? []
|
||||
return catalogProducts.value
|
||||
})
|
||||
.finally(() => {
|
||||
catalogPromise = null
|
||||
})
|
||||
|
||||
return catalogPromise
|
||||
}
|
||||
|
||||
const catalogMetalIds = computed(() => getCatalogMetalIds(catalogProducts.value))
|
||||
const hasCountBasedProducts = computed(() => catalogHasCountBasedProducts(catalogProducts.value))
|
||||
const hasMeltedProducts = computed(() => catalogHasMeltedProducts(catalogProducts.value))
|
||||
const isSingleMetal = computed(() => isSingleMetalCatalog(catalogMetalIds.value))
|
||||
|
||||
return {
|
||||
catalogProducts,
|
||||
catalogMetalIds,
|
||||
hasCountBasedProducts,
|
||||
hasMeltedProducts,
|
||||
isSingleMetal,
|
||||
loadCatalog,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { ref } from 'vue'
|
||||
import { getWalletAssets } from '@/api/wallet'
|
||||
import { getProducts } from '@/api/products'
|
||||
import type { WalletAssetsSummary } from '@/models/walletAssets'
|
||||
import { enrichInventoryCardsWithCatalog } from '@/utils/productAssets'
|
||||
|
||||
const assetsSummary = ref<WalletAssetsSummary | null>(null)
|
||||
let assetsPromise: Promise<WalletAssetsSummary> | null = null
|
||||
|
||||
export function useWalletAssets() {
|
||||
async function loadWalletAssets(force = false) {
|
||||
if (!force && assetsSummary.value) {
|
||||
return assetsSummary.value
|
||||
}
|
||||
|
||||
if (!force && assetsPromise) {
|
||||
return assetsPromise
|
||||
}
|
||||
|
||||
assetsPromise = Promise.all([getWalletAssets(), getProducts()])
|
||||
.then(([data, catalog]) => {
|
||||
assetsSummary.value = {
|
||||
...data,
|
||||
inventory_cards: enrichInventoryCardsWithCatalog(data.inventory_cards ?? [], catalog ?? []),
|
||||
count_products: enrichInventoryCardsWithCatalog(data.count_products ?? [], catalog ?? []),
|
||||
}
|
||||
return assetsSummary.value
|
||||
})
|
||||
.finally(() => {
|
||||
assetsPromise = null
|
||||
})
|
||||
|
||||
return assetsPromise
|
||||
}
|
||||
|
||||
function clearWalletAssets() {
|
||||
assetsSummary.value = null
|
||||
assetsPromise = null
|
||||
}
|
||||
|
||||
return {
|
||||
assetsSummary,
|
||||
loadWalletAssets,
|
||||
clearWalletAssets,
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -48,7 +48,7 @@ export interface User {
|
||||
deleted_at?: any;
|
||||
wallet: Wallet;
|
||||
pwallet:PWallet;
|
||||
wallets: Wallets
|
||||
wallets: Wallets[]
|
||||
|
||||
finger_print: boolean
|
||||
gold: number;
|
||||
|
||||
@@ -23,6 +23,7 @@ export interface Product {
|
||||
min_order_cash?: number | null
|
||||
max_order_cash?: number | null
|
||||
direct_price: number | undefined
|
||||
price_offset_percent?: number | null
|
||||
reading_method: any
|
||||
created_at: any
|
||||
updated_at: any
|
||||
|
||||
@@ -50,11 +50,13 @@ export interface Wallets {
|
||||
number : number
|
||||
owner : number
|
||||
owner_type : number
|
||||
product : null
|
||||
product : Product | null
|
||||
product_id : null | number
|
||||
updated_at : string
|
||||
}
|
||||
|
||||
export type UserWalletLine = Wallets
|
||||
|
||||
export interface PWallet {
|
||||
id: number
|
||||
owner_type: number
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { ProductFile } from '@/utils/file'
|
||||
|
||||
export interface WalletAssetsMeta {
|
||||
metal_ids: number[]
|
||||
metal_count: number
|
||||
has_count_based_products: boolean
|
||||
has_weight_based_products: boolean
|
||||
weight_unit: string
|
||||
single_metal: boolean
|
||||
}
|
||||
|
||||
export interface WalletInventoryCard {
|
||||
product_id: number
|
||||
title: string
|
||||
group_type: string
|
||||
metal_id: number
|
||||
quantity: number
|
||||
unit: string
|
||||
display_type: 'count' | 'weight'
|
||||
unit_weight?: string | null
|
||||
show_in_assets: boolean
|
||||
file?: ProductFile | null
|
||||
}
|
||||
|
||||
export interface WalletMetalTotal {
|
||||
metal_id: number
|
||||
metal_label: string
|
||||
label: string
|
||||
product_weight: number
|
||||
melted_weight: number
|
||||
total_weight: number
|
||||
unit: string
|
||||
}
|
||||
|
||||
export interface WalletAssetsSummary {
|
||||
meta: WalletAssetsMeta
|
||||
cash_wallet: number
|
||||
inventory_cards: WalletInventoryCard[]
|
||||
count_products: WalletInventoryCard[]
|
||||
metal_totals: WalletMetalTotal[]
|
||||
assets_rial_value: number
|
||||
total_rial_value: number
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { computed, ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { getSettings } from '@/api/configuration'
|
||||
import { resolveMeltedGoldLabel, resolveMetalTypeLabel } from '@/utils/metalLabels'
|
||||
import { resolveTradeWeightUnit } from '@/utils/weightUnit'
|
||||
|
||||
export interface AppSetting {
|
||||
id?: number
|
||||
@@ -60,6 +61,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
const metalTypeSettingValue = computed(() => getSettingByKey('metal_type'))
|
||||
const metalTypeLabel = computed(() => resolveMetalTypeLabel(metalTypeSettingValue.value))
|
||||
const meltedGoldLabel = computed(() => resolveMeltedGoldLabel(metalTypeSettingValue.value))
|
||||
const tradeWeightUnit = computed(() => resolveTradeWeightUnit(getSettingByKey('unit')))
|
||||
|
||||
return {
|
||||
settings,
|
||||
@@ -70,5 +72,6 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
metalTypeSettingValue,
|
||||
metalTypeLabel,
|
||||
meltedGoldLabel,
|
||||
tradeWeightUnit,
|
||||
}
|
||||
})
|
||||
|
||||
+10
-5
@@ -10,12 +10,17 @@ export interface ProductFile {
|
||||
|
||||
export function getFileUrl(file?: ProductFile | null): string | null {
|
||||
if (!file) return null
|
||||
if (file.full_src) return file.full_src
|
||||
if (file.url) return file.url
|
||||
if (!file.src) return null
|
||||
if (/^https?:\/\//i.test(file.src)) return file.src
|
||||
|
||||
for (const value of [file.full_src, file.url, file.src]) {
|
||||
if (!value) continue
|
||||
if (/^https?:\/\//i.test(value)) return value
|
||||
}
|
||||
|
||||
const relative = file.src || file.full_src
|
||||
if (!relative) return null
|
||||
|
||||
const base = baseURL.replace(/\/$/, '')
|
||||
const path = file.src.replace(/^\//, '')
|
||||
const path = String(relative).replace(/^\//, '')
|
||||
return `${base}/${path}`
|
||||
}
|
||||
|
||||
|
||||
@@ -164,12 +164,12 @@ if (isBuyP){
|
||||
return Promise.reject(getInsufficientCashWalletMessage(groupTypeP))
|
||||
}
|
||||
if (!walletCash?.walletInfo?.gold && isMainMetalWalletDealMethod(methodP)){
|
||||
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP))
|
||||
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP))
|
||||
}
|
||||
if (priceP * value > walletCash?.walletInfo?.cash && isCashLikeDealMethod(methodP))
|
||||
return Promise.reject(getInsufficientCashWalletMessage(groupTypeP))
|
||||
if (amountP * value > walletCash?.walletInfo?.gold && isMainMetalWalletDealMethod(methodP))
|
||||
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP))
|
||||
return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP))
|
||||
else
|
||||
return Promise.resolve();
|
||||
}else {
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
import type { Product } from '@/models/products'
|
||||
import type { UserWalletLine } from '@/models/wallet'
|
||||
import type { ProductFile } from '@/utils/file'
|
||||
import { getFileUrl } from '@/utils/file'
|
||||
import { isCountBasedProduct, type ProductUnitSource } from '@/utils/productDealMethod'
|
||||
import { isMeltedTradeGroup, normalizeProductGroupType, LEGACY_GROUP_KATOD } from '@/utils/productCategories'
|
||||
import defaultImg from '@/assets/img/defaultAbshodeh.svg'
|
||||
import goyImg from '@/assets/img/goyImg.svg'
|
||||
import mokaabImg from '@/assets/img/mokaabImg.svg'
|
||||
import sekkeImg from '@/assets/img/sekkeImg.svg'
|
||||
import mesImg from '@/assets/img/mesImg.jpg'
|
||||
import noghrehImg from '@/assets/img/noghrehImg.webp'
|
||||
import parsianImg from '@/assets/img/parsianImg.svg'
|
||||
|
||||
export const METAL_GOLD = 1
|
||||
export const METAL_SILVER = 2
|
||||
export const METAL_COPPER = 3
|
||||
|
||||
const GROUP_DEFAULT_IMAGES: Record<string, string> = {
|
||||
گوی: goyImg,
|
||||
مکعب: mokaabImg,
|
||||
سکه: sekkeImg,
|
||||
مس: mesImg,
|
||||
[LEGACY_GROUP_KATOD]: mesImg,
|
||||
نقره: noghrehImg,
|
||||
'سکه پارسیان': parsianImg,
|
||||
طلا: defaultImg,
|
||||
آبشده: defaultImg,
|
||||
}
|
||||
|
||||
export function getMetalLabel(metalId: number): string {
|
||||
switch (metalId) {
|
||||
case METAL_GOLD:
|
||||
return 'طلا'
|
||||
case METAL_SILVER:
|
||||
return 'نقره'
|
||||
case METAL_COPPER:
|
||||
return 'مس'
|
||||
default:
|
||||
return 'فلز'
|
||||
}
|
||||
}
|
||||
|
||||
export function getTotalMetalLabel(metalId: number): string {
|
||||
return `کل دارایی ${getMetalLabel(metalId)}`
|
||||
}
|
||||
|
||||
export function isSingleMetalCatalog(metalIds: number[]): boolean {
|
||||
return metalIds.length === 1
|
||||
}
|
||||
|
||||
export function getCatalogMetalIds(products?: Product[] | null): number[] {
|
||||
const ids = new Set<number>()
|
||||
for (const product of products ?? []) {
|
||||
const metalId = Number(product.metal_id)
|
||||
if (metalId > 0) {
|
||||
ids.add(metalId)
|
||||
}
|
||||
}
|
||||
return Array.from(ids).sort((a, b) => a - b)
|
||||
}
|
||||
|
||||
export function catalogHasCountBasedProducts(products?: Product[] | null): boolean {
|
||||
return (products ?? []).some((product) => isCountBasedProduct(product))
|
||||
}
|
||||
|
||||
export function catalogHasMeltedProducts(products?: Product[] | null): boolean {
|
||||
return (products ?? []).some((product) => isMeltedTradeGroup(product.group_type))
|
||||
}
|
||||
|
||||
export function enrichInventoryCardsWithCatalog<T extends { product_id?: number; file?: ProductFile | null }>(
|
||||
cards: T[],
|
||||
catalog: Product[]
|
||||
): T[] {
|
||||
return cards.map((card) => {
|
||||
const fromCatalog = catalog.find((product) => product.id === card.product_id)
|
||||
if (!fromCatalog) {
|
||||
return card
|
||||
}
|
||||
|
||||
return {
|
||||
...card,
|
||||
file: card.file ?? fromCatalog.file ?? null,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function enrichInventoryWithCatalog<T extends { id?: number }>(
|
||||
items: T[],
|
||||
catalog: Product[]
|
||||
): T[] {
|
||||
return items.map((item) => {
|
||||
const fromCatalog = catalog.find((product) => product.id === item.id)
|
||||
if (!fromCatalog) {
|
||||
return item
|
||||
}
|
||||
|
||||
const current = item as T & Product
|
||||
return {
|
||||
...fromCatalog,
|
||||
...current,
|
||||
wallet: current.wallet ?? fromCatalog.wallet,
|
||||
file: current.file ?? fromCatalog.file,
|
||||
metal_id: current.metal_id ?? fromCatalog.metal_id,
|
||||
group_type: current.group_type ?? fromCatalog.group_type,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function getProductDisplayImage(product?: {
|
||||
group_type?: string | null
|
||||
title?: string | null
|
||||
file?: ProductFile | null
|
||||
img?: string | null
|
||||
} | null): string {
|
||||
const fileUrl = getFileUrl(product?.file)
|
||||
if (fileUrl) {
|
||||
return fileUrl
|
||||
}
|
||||
|
||||
if (product?.img && /^https?:\/\//i.test(product.img)) {
|
||||
return product.img
|
||||
}
|
||||
|
||||
const group = normalizeProductGroupType(product?.group_type)
|
||||
if (group && GROUP_DEFAULT_IMAGES[group]) {
|
||||
return GROUP_DEFAULT_IMAGES[group]
|
||||
}
|
||||
|
||||
return defaultImg
|
||||
}
|
||||
|
||||
type InventoryProduct = ProductUnitSource & {
|
||||
metal_id?: number | null
|
||||
title?: string | null
|
||||
wallet?: { gold?: number | null } | null
|
||||
}
|
||||
|
||||
export function sumCountBasedInventory(products?: InventoryProduct[] | null): number {
|
||||
return (products ?? [])
|
||||
.filter((product) => product.title !== 'آبشده نقدی' && isCountBasedProduct(product))
|
||||
.reduce((sum, product) => sum + Number(product.wallet?.gold ?? 0), 0)
|
||||
}
|
||||
|
||||
export function sumProductWalletByMetal(
|
||||
products: InventoryProduct[] | null | undefined,
|
||||
metalId: number
|
||||
): number {
|
||||
return (products ?? [])
|
||||
.filter((product) => Number(product.metal_id) === metalId)
|
||||
.reduce((sum, product) => sum + Number(product.wallet?.gold ?? 0), 0)
|
||||
}
|
||||
|
||||
export function getMainWalletLine(wallets?: UserWalletLine[] | null): UserWalletLine | undefined {
|
||||
return wallets?.find((line) => line.product_id == null)
|
||||
}
|
||||
|
||||
export function getMainWalletGold(wallets?: UserWalletLine[] | null): number {
|
||||
return Number(getMainWalletLine(wallets)?.gold ?? 0)
|
||||
}
|
||||
|
||||
export function getMainWalletCash(wallets?: UserWalletLine[] | null): number {
|
||||
return Number(getMainWalletLine(wallets)?.cash ?? 0)
|
||||
}
|
||||
|
||||
export function sumWalletsGold(
|
||||
wallets?: UserWalletLine[] | null,
|
||||
metalId?: number | null
|
||||
): number {
|
||||
if (!wallets?.length) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return wallets.reduce((sum, line) => {
|
||||
const weight = Number(line.gold ?? 0)
|
||||
if (metalId == null) {
|
||||
return sum + weight
|
||||
}
|
||||
|
||||
if (line.product_id == null) {
|
||||
return metalId === METAL_GOLD ? sum + weight : sum
|
||||
}
|
||||
|
||||
return Number(line.product?.metal_id) === metalId ? sum + weight : sum
|
||||
}, 0)
|
||||
}
|
||||
|
||||
export function sumProductWalletsGold(
|
||||
wallets?: UserWalletLine[] | null,
|
||||
metalId?: number | null
|
||||
): number {
|
||||
return (wallets ?? [])
|
||||
.filter((line) => line.product_id != null)
|
||||
.reduce((sum, line) => {
|
||||
const weight = Number(line.gold ?? 0)
|
||||
if (metalId == null) {
|
||||
return sum + weight
|
||||
}
|
||||
|
||||
return Number(line.product?.metal_id) === metalId ? sum + weight : sum
|
||||
}, 0)
|
||||
}
|
||||
|
||||
export function sumInventoryMetalWeight(products?: InventoryProduct[] | null): number {
|
||||
return (products ?? [])
|
||||
.filter((product) => product.title !== 'آبشده نقدی')
|
||||
.reduce((sum, product) => sum + Number(product.wallet?.gold ?? 0), 0)
|
||||
}
|
||||
|
||||
export function getTotalMetalWeight(
|
||||
walletInfo?: Record<string, unknown> | null,
|
||||
wallets?: UserWalletLine[] | null,
|
||||
inventoryProducts?: InventoryProduct[] | null
|
||||
): number {
|
||||
const fromInventory = sumInventoryMetalWeight(inventoryProducts)
|
||||
if (fromInventory > 0) {
|
||||
return fromInventory
|
||||
}
|
||||
|
||||
const fromProductWallets = sumProductWalletsGold(wallets)
|
||||
if (fromProductWallets > 0) {
|
||||
return fromProductWallets
|
||||
}
|
||||
|
||||
if (wallets?.length) {
|
||||
return getMainWalletGold(wallets)
|
||||
}
|
||||
|
||||
return Number(walletInfo?.treasure ?? walletInfo?.gold_sum ?? walletInfo?.count_gold ?? 0)
|
||||
}
|
||||
|
||||
/** فقط موجودی نقدی کیف اصلی — فیلد gold (مثل 0.3 کیلوگرم) جزو دارایی ریالی نیست */
|
||||
export function getRialCashAmount(
|
||||
walletInfo?: Record<string, unknown> | null,
|
||||
wallets?: UserWalletLine[] | null
|
||||
): number {
|
||||
const mainCash = getMainWalletCash(wallets)
|
||||
if (mainCash > 0) {
|
||||
return mainCash
|
||||
}
|
||||
|
||||
return Number(walletInfo?.count_cash ?? walletInfo?.cash ?? 0)
|
||||
}
|
||||
|
||||
export function getTotalRialEquivalent(walletInfo?: Record<string, unknown> | null): number {
|
||||
return Number(walletInfo?.count_cash_total ?? 0)
|
||||
}
|
||||
|
||||
export function getMetalAssetAmount(
|
||||
walletInfo: Record<string, unknown> | null | undefined,
|
||||
metalId: number,
|
||||
inventoryProducts?: InventoryProduct[] | null
|
||||
): number {
|
||||
if (inventoryProducts?.length) {
|
||||
const fromProducts = sumProductWalletByMetal(inventoryProducts, metalId)
|
||||
if (fromProducts > 0 || inventoryProducts.some((product) => Number(product.metal_id) === metalId)) {
|
||||
return fromProducts
|
||||
}
|
||||
}
|
||||
|
||||
if (!walletInfo) {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch (metalId) {
|
||||
case METAL_GOLD:
|
||||
return Number(walletInfo.count_gold_wallets ?? walletInfo.count_gold ?? 0)
|
||||
case METAL_SILVER:
|
||||
return Number(walletInfo.count_silver ?? 0)
|
||||
case METAL_COPPER:
|
||||
return Number(walletInfo.count_copper ?? 0)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
export function getMetalAssetAmountForDisplay(
|
||||
walletInfo: Record<string, unknown> | null | undefined,
|
||||
metalId: number,
|
||||
catalogMetalIds: number[],
|
||||
inventoryProducts?: InventoryProduct[] | null,
|
||||
wallets?: UserWalletLine[] | null
|
||||
): number {
|
||||
if (isSingleMetalCatalog(catalogMetalIds)) {
|
||||
return getTotalMetalWeight(walletInfo, wallets, inventoryProducts)
|
||||
}
|
||||
|
||||
const productWeight = sumProductWalletByMetal(inventoryProducts, metalId)
|
||||
const mainWalletWeight = wallets?.length
|
||||
? getMainWalletGold(wallets)
|
||||
: Number(walletInfo?.count_gold_wallet ?? 0)
|
||||
|
||||
if (catalogHasMeltedProducts(inventoryProducts as Product[] | null | undefined) && metalId === catalogMetalIds[0]) {
|
||||
return productWeight + mainWalletWeight
|
||||
}
|
||||
|
||||
if (wallets?.length) {
|
||||
const walletWeight = sumWalletsGold(wallets, metalId)
|
||||
if (walletWeight > 0) {
|
||||
return walletWeight
|
||||
}
|
||||
}
|
||||
|
||||
return productWeight || getMetalAssetAmount(walletInfo, metalId, inventoryProducts)
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/** دستهبندی یکسان محصول در همه اپهای ماژولار */
|
||||
export const PRODUCT_CATEGORY_ABSHODE = 'آبشده'
|
||||
|
||||
export const UNIFIED_PRODUCT_CATEGORIES = [
|
||||
PRODUCT_CATEGORY_ABSHODE,
|
||||
'مکعب',
|
||||
'گوی',
|
||||
'سکه',
|
||||
'سکه پارسیان',
|
||||
'مس',
|
||||
'نقره',
|
||||
] as const
|
||||
|
||||
/** دستههای قدیمی بورس مس — سازگاری با داده موجود */
|
||||
export const LEGACY_GROUP_KATOD = 'کاتد مس'
|
||||
export const LEGACY_GROUP_MAFTOL = 'مفتول مس'
|
||||
export const LEGACY_GROUP_GOLD = 'طلا'
|
||||
|
||||
/** دستههای قدیمی که UI آبشدهای دارند — «طلا» عمداً نیست (گاروسی با DealProduct میماند) */
|
||||
export const LEGACY_MELTED_GROUP_TYPES = [LEGACY_GROUP_KATOD] as const
|
||||
|
||||
export function normalizeProductGroupType(groupType?: string | null) {
|
||||
return (groupType ?? '').trim()
|
||||
}
|
||||
|
||||
/** محصول آبشدهای — UI گرم/کیلوگرم مثل indexGold */
|
||||
export function isMeltedTradeGroup(groupType?: string | null) {
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
return group === PRODUCT_CATEGORY_ABSHODE || LEGACY_MELTED_GROUP_TYPES.includes(group as typeof LEGACY_MELTED_GROUP_TYPES[number])
|
||||
}
|
||||
|
||||
export function isMetalCommodityGroup(groupType?: string | null) {
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
return group === 'مس' || group === 'نقره'
|
||||
}
|
||||
|
||||
export function isLegacyMaftolGroup(groupType?: string | null) {
|
||||
return normalizeProductGroupType(groupType) === LEGACY_GROUP_MAFTOL
|
||||
}
|
||||
|
||||
/** نگاشت دسته قدیمی به دسته یکسان */
|
||||
export function normalizeToUnifiedCategory(groupType?: string | null) {
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
if (group === LEGACY_GROUP_KATOD || group === LEGACY_GROUP_GOLD) {
|
||||
return PRODUCT_CATEGORY_ABSHODE
|
||||
}
|
||||
if (group === LEGACY_GROUP_MAFTOL) {
|
||||
return 'مس'
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
export type MeltedPriceSource = 'app' | 'fixed' | 'reference'
|
||||
|
||||
export function resolveMeltedPriceSource(product?: {
|
||||
reading_method?: string | null
|
||||
direct_price?: number | null
|
||||
} | null): MeltedPriceSource {
|
||||
if (product?.reading_method) {
|
||||
return 'reference'
|
||||
}
|
||||
if (Number(product?.direct_price) === 1) {
|
||||
return 'fixed'
|
||||
}
|
||||
return 'app'
|
||||
}
|
||||
|
||||
export function isMeltedProductUsingAppPrice(product?: {
|
||||
group_type?: string | null
|
||||
reading_method?: string | null
|
||||
direct_price?: number | null
|
||||
} | null) {
|
||||
return isMeltedTradeGroup(product?.group_type)
|
||||
&& resolveMeltedPriceSource(product) === 'app'
|
||||
}
|
||||
+121
-46
@@ -1,18 +1,22 @@
|
||||
import type { SelectItem } from '@/models/SelectItem'
|
||||
import { isBoursecuProject } from '@/utils/config'
|
||||
import { useSettingsStore } from '@/store/settingsStore'
|
||||
import {
|
||||
isLegacyMaftolGroup,
|
||||
isMeltedTradeGroup,
|
||||
LEGACY_GROUP_KATOD,
|
||||
LEGACY_GROUP_MAFTOL,
|
||||
normalizeProductGroupType,
|
||||
PRODUCT_CATEGORY_ABSHODE,
|
||||
} from '@/utils/productCategories'
|
||||
|
||||
/** شناسه group_type محصول در دیتابیس — نه برچسب نمایشی */
|
||||
export const BOURSECU_GROUP_MAFTOL = 'مفتول مس'
|
||||
export const BOURSECU_GROUP_KATOD = 'کاتد مس'
|
||||
export const BOURSECU_GROUP_ABSHODE = 'آبشده'
|
||||
/** @deprecated از isMeltedTradeGroup استفاده کنید */
|
||||
export const BOURSECU_GROUP_ABSHODE = PRODUCT_CATEGORY_ABSHODE
|
||||
export const BOURSECU_GROUP_KATOD = LEGACY_GROUP_KATOD
|
||||
export const BOURSECU_GROUP_MAFTOL = LEGACY_GROUP_MAFTOL
|
||||
|
||||
export const BOURSECU_WALLET_LABEL_GENERIC = 'موجودی کیف'
|
||||
|
||||
export function normalizeProductGroupType(groupType?: string | null) {
|
||||
return (groupType ?? '').trim()
|
||||
}
|
||||
|
||||
export function isBoursecuDealProductGroup(groupType?: string | null) {
|
||||
if (!isBoursecuProject()) {
|
||||
return false
|
||||
@@ -22,10 +26,12 @@ export function isBoursecuDealProductGroup(groupType?: string | null) {
|
||||
return group === BOURSECU_GROUP_MAFTOL
|
||||
|| group === BOURSECU_GROUP_KATOD
|
||||
|| group === BOURSECU_GROUP_ABSHODE
|
||||
|| group === 'مس'
|
||||
}
|
||||
|
||||
export function isMaftolMesGroup(groupType?: string | null) {
|
||||
return normalizeProductGroupType(groupType) === BOURSECU_GROUP_MAFTOL
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
return group === BOURSECU_GROUP_MAFTOL || (isBoursecuProject() && group === 'مس')
|
||||
}
|
||||
|
||||
export function isKatodMesGroup(groupType?: string | null) {
|
||||
@@ -33,7 +39,7 @@ export function isKatodMesGroup(groupType?: string | null) {
|
||||
}
|
||||
|
||||
export function isGoldOnlyDealGroup(groupType?: string | null) {
|
||||
return normalizeProductGroupType(groupType) === BOURSECU_GROUP_ABSHODE
|
||||
return isMeltedTradeGroup(groupType)
|
||||
}
|
||||
|
||||
export interface ProductUnitSource {
|
||||
@@ -43,6 +49,11 @@ export interface ProductUnitSource {
|
||||
amount?: number | null
|
||||
}
|
||||
|
||||
export function isWeightBasedProductUnit(unit?: string | null) {
|
||||
const value = (unit ?? '').trim()
|
||||
return value === 'کیلوگرم' || value === 'گرم'
|
||||
}
|
||||
|
||||
const COUNT_BASED_GROUP_TYPES = ['سکه', 'گوی', 'مکعب', 'شمش', 'سکه پارسیان']
|
||||
|
||||
/** مطابق ادمین: وزن «دارد» یعنی amount مقدار واقعی است؛ «ندارد» یعنی amount = 1 */
|
||||
@@ -52,14 +63,19 @@ export function hasProductUnitWeight(product?: ProductUnitSource | null) {
|
||||
}
|
||||
|
||||
export function getProductWeightUnit(product?: ProductUnitSource | null) {
|
||||
const unit = product?.unit?.trim()
|
||||
if (unit && isWeightBasedProductUnit(unit)) {
|
||||
return unit
|
||||
}
|
||||
|
||||
if (isBoursecuProject()) {
|
||||
const group = normalizeProductGroupType(product?.group_type)
|
||||
if (group === BOURSECU_GROUP_MAFTOL || group === BOURSECU_GROUP_KATOD || group === BOURSECU_GROUP_ABSHODE) {
|
||||
if (group === BOURSECU_GROUP_MAFTOL || group === BOURSECU_GROUP_KATOD || group === BOURSECU_GROUP_ABSHODE || group === 'مس' || isMeltedTradeGroup(group)) {
|
||||
return getWeightUnit()
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCountBasedProduct(product) || isGoldOnlyDealGroup(product?.group_type)) {
|
||||
if (!isCountBasedProduct(product) || isMeltedTradeGroup(product?.group_type)) {
|
||||
return getWeightUnit()
|
||||
}
|
||||
|
||||
@@ -124,12 +140,16 @@ export function isCountBasedProduct(product?: ProductUnitSource | null) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (isWeightBasedProductUnit(product.unit)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (product.direct_price != null && product.direct_price !== 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
const group = normalizeProductGroupType(product.group_type)
|
||||
if (group === BOURSECU_GROUP_MAFTOL || group === BOURSECU_GROUP_KATOD) {
|
||||
if (group === BOURSECU_GROUP_MAFTOL || isLegacyMaftolGroup(group) || (isBoursecuProject() && group === 'مس')) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -137,15 +157,15 @@ export function isCountBasedProduct(product?: ProductUnitSource | null) {
|
||||
}
|
||||
|
||||
export function getProductQuantityUnit(product?: ProductUnitSource | null) {
|
||||
if (isCountBasedProduct(product)) {
|
||||
return 'عدد'
|
||||
}
|
||||
|
||||
const unit = product?.unit?.trim()
|
||||
if (unit) {
|
||||
return unit
|
||||
}
|
||||
|
||||
if (isCountBasedProduct(product)) {
|
||||
return 'عدد'
|
||||
}
|
||||
|
||||
return getWeightUnit()
|
||||
}
|
||||
|
||||
@@ -157,17 +177,34 @@ function getDefaultTypeDealOptions(): SelectItem[] {
|
||||
]
|
||||
}
|
||||
|
||||
export function getProductDealMethodOptions(groupType?: string | null): SelectItem[] {
|
||||
export function getProductDealMethodOptions(groupType?: string | null, isBuy = true): SelectItem[] {
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
if (!isBoursecuProject()) {
|
||||
return getDefaultTypeDealOptions()
|
||||
if (isBuy) {
|
||||
return [
|
||||
{ value: 'نقدی', key: 'cash' },
|
||||
{ value: settingsStore.metalTypeLabel, key: 'gold' },
|
||||
]
|
||||
}
|
||||
|
||||
return [
|
||||
{ value: 'نقدی', key: 'cash' },
|
||||
{ value: `دریافت ${settingsStore.metalTypeLabel}`, key: 'gold' },
|
||||
]
|
||||
}
|
||||
|
||||
if (isMaftolMesGroup(groupType)) {
|
||||
if (isBuy) {
|
||||
return [
|
||||
{ value: `پرداخت با ${settingsStore.metalTypeLabel}`, key: 'katod' },
|
||||
{ value: 'نقدی', key: 'cash' },
|
||||
]
|
||||
}
|
||||
|
||||
return [
|
||||
{ value: settingsStore.metalTypeLabel, key: 'katod' },
|
||||
{ value: 'نقدی', key: 'cash' },
|
||||
{ value: `دریافت ${settingsStore.metalTypeLabel}`, key: 'katod' },
|
||||
]
|
||||
}
|
||||
|
||||
@@ -175,15 +212,38 @@ export function getProductDealMethodOptions(groupType?: string | null): SelectIt
|
||||
return [{ value: 'نقدی', key: 'cash' }]
|
||||
}
|
||||
|
||||
if (isGoldOnlyDealGroup(groupType)) {
|
||||
if (isMeltedTradeGroup(groupType)) {
|
||||
return [{ value: settingsStore.meltedGoldLabel, key: 'gold' }]
|
||||
}
|
||||
|
||||
return getDefaultTypeDealOptions()
|
||||
}
|
||||
|
||||
export function getDefaultProductDealMethod(groupType?: string | null) {
|
||||
return getProductDealMethodOptions(groupType)[0]?.key ?? 'cash'
|
||||
export function getDefaultProductDealMethod(groupType?: string | null, isBuy = true) {
|
||||
return getProductDealMethodOptions(groupType, isBuy)[0]?.key ?? 'cash'
|
||||
}
|
||||
|
||||
export function getProductDealMethodPlaceholder(isBuy = true) {
|
||||
return isBuy ? 'نحوه خرید را انتخاب کنید' : 'نحوه دریافت را انتخاب کنید'
|
||||
}
|
||||
|
||||
export function formatMainMetalReceiveText(weight?: number | null) {
|
||||
return `${useSettingsStore().metalTypeLabel}: ${weight ?? 0}${getWeightUnit()}`
|
||||
}
|
||||
|
||||
export function calcSellReceivedMetalWeight(
|
||||
count?: number | null,
|
||||
product?: ProductUnitSource & { percent_fee_sell?: number | null } | null,
|
||||
) {
|
||||
const quantity = Number(count ?? 0)
|
||||
const unitAmount = Number(product?.amount ?? 0)
|
||||
if (!quantity || !unitAmount) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const grossAmount = quantity * unitAmount
|
||||
const feeRate = Number(product?.percent_fee_sell ?? 0)
|
||||
return grossAmount - feeRate * grossAmount
|
||||
}
|
||||
|
||||
export function isCashLikeDealMethod(method?: string | null) {
|
||||
@@ -204,36 +264,42 @@ export function getMeltedGoldWalletLabel() {
|
||||
return `موجودی کیف ${useSettingsStore().meltedGoldLabel}`
|
||||
}
|
||||
|
||||
export function getGoldWalletLabel(groupType?: string | null) {
|
||||
const settingsStore = useSettingsStore()
|
||||
export function getBoursecuMetalWalletLabel(groupType?: string | null) {
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
if (group === BOURSECU_GROUP_MAFTOL) {
|
||||
return BOURSECU_GROUP_MAFTOL
|
||||
}
|
||||
if (group === BOURSECU_GROUP_KATOD) {
|
||||
return BOURSECU_GROUP_KATOD
|
||||
}
|
||||
if (group === BOURSECU_GROUP_ABSHODE) {
|
||||
return useSettingsStore().meltedGoldLabel
|
||||
}
|
||||
|
||||
return useSettingsStore().metalTypeLabel
|
||||
}
|
||||
|
||||
export function getGoldWalletLabel(groupType?: string | null) {
|
||||
if (!isBoursecuProject()) {
|
||||
return getMainMetalWalletLabel()
|
||||
}
|
||||
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
if (group === BOURSECU_GROUP_MAFTOL) {
|
||||
return `موجودی کیف ${BOURSECU_GROUP_MAFTOL}`
|
||||
if (group === BOURSECU_GROUP_MAFTOL
|
||||
|| group === BOURSECU_GROUP_KATOD
|
||||
|| group === BOURSECU_GROUP_ABSHODE) {
|
||||
return `موجودی کیف ${getBoursecuMetalWalletLabel(groupType)}`
|
||||
}
|
||||
if (group === BOURSECU_GROUP_KATOD || group === BOURSECU_GROUP_ABSHODE || !group) {
|
||||
return group === BOURSECU_GROUP_ABSHODE
|
||||
? getMeltedGoldWalletLabel()
|
||||
: getMainMetalWalletLabel()
|
||||
|
||||
if (!group) {
|
||||
return getMainMetalWalletLabel()
|
||||
}
|
||||
|
||||
return BOURSECU_WALLET_LABEL_GENERIC
|
||||
}
|
||||
|
||||
export function getCashWalletLabel(groupType?: string | null) {
|
||||
if (!isBoursecuProject()) {
|
||||
return 'موجودی کیف پول'
|
||||
}
|
||||
|
||||
const group = normalizeProductGroupType(groupType)
|
||||
if (group === BOURSECU_GROUP_MAFTOL) {
|
||||
return `موجودی کیف ${BOURSECU_GROUP_MAFTOL}`
|
||||
}
|
||||
|
||||
/** پرداخت نقدی همیشه از کیف پول ریالی — مستقل از نوع محصول */
|
||||
export function getCashWalletLabel(_groupType?: string | null) {
|
||||
return 'موجودی کیف پول'
|
||||
}
|
||||
|
||||
@@ -250,7 +316,7 @@ export function getMaftolAssetLabel() {
|
||||
}
|
||||
|
||||
export function getWeightUnit() {
|
||||
return isBoursecuProject() ? 'کیلوگرم' : 'گرم'
|
||||
return useSettingsStore().tradeWeightUnit
|
||||
}
|
||||
|
||||
export function formatBoursecuAssetAmount(amount?: number | null) {
|
||||
@@ -269,12 +335,21 @@ export function formatCashWalletBalanceText(cashFormatted: string | number, grou
|
||||
return `${getCashWalletLabel(groupType)}: ${cashFormatted} ریال`
|
||||
}
|
||||
|
||||
export function getInsufficientGoldWalletMessage(groupType?: string | null) {
|
||||
return `${getGoldWalletLabel(groupType)} ناکافی است`
|
||||
/** برچسب کیف فلزی متناسب با نحوه پرداخت (مثلاً کاتد مس برای خرید مفتول با کیف کاتد) */
|
||||
export function getMetalWalletLabelForDealMethod(method?: string | null, groupType?: string | null) {
|
||||
if (!isBoursecuProject() || method === 'katod') {
|
||||
return getMainMetalWalletLabel()
|
||||
}
|
||||
|
||||
return getGoldWalletLabel(groupType)
|
||||
}
|
||||
|
||||
export function getInsufficientCashWalletMessage(groupType?: string | null) {
|
||||
return `${getCashWalletLabel(groupType)} ناکافی است`
|
||||
export function getInsufficientGoldWalletMessage(groupType?: string | null, method?: string | null) {
|
||||
return `${getMetalWalletLabelForDealMethod(method, groupType)} ناکافی است`
|
||||
}
|
||||
|
||||
export function getInsufficientCashWalletMessage(_groupType?: string | null) {
|
||||
return `${getCashWalletLabel()} ناکافی است`
|
||||
}
|
||||
|
||||
export function getInsufficientMainMetalWalletMessage() {
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
import type { Product } from '@/models/products'
|
||||
import { getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@/utils/price'
|
||||
import { isMetalCommodityGroup, isMeltedProductUsingAppPrice, isMeltedTradeGroup } from '@/utils/productCategories'
|
||||
|
||||
function applyPriceOffsetPercent(basePrice: number, offsetPercent?: number | null) {
|
||||
const offset = Number(offsetPercent ?? 0)
|
||||
if (!offset) {
|
||||
return basePrice
|
||||
}
|
||||
|
||||
return Math.round(basePrice * (1 + offset / 100))
|
||||
}
|
||||
|
||||
/** قیمت خرید نمایشی محصول (همان مقداری که در لیست و اکشنشیت نشان داده میشود) */
|
||||
export function getProductBuyPrice(product: Product): number {
|
||||
if (product.group_type === 'آبشده') {
|
||||
return getTradeBuyPrice(lastPrice.value) + (product.cash_fee_buy ?? 0)
|
||||
if (isMeltedProductUsingAppPrice(product)) {
|
||||
const base = applyPriceOffsetPercent(getTradeBuyPrice(lastPrice.value), product.price_offset_percent)
|
||||
return base + (product.cash_fee_buy ?? 0)
|
||||
}
|
||||
|
||||
if (['مس', 'نقره'].includes(product.group_type)) {
|
||||
if (isMeltedTradeGroup(product.group_type)) {
|
||||
return (product.price ?? 0) + (product.cash_fee_buy ?? 0)
|
||||
}
|
||||
|
||||
if (isMetalCommodityGroup(product.group_type)) {
|
||||
const base = (product.price_profit ?? 0) + (product.price ?? 0)
|
||||
return base + (product.cash_fee_buy ?? 0)
|
||||
}
|
||||
@@ -18,14 +33,23 @@ export function getProductBuyPrice(product: Product): number {
|
||||
: basePrice
|
||||
}
|
||||
|
||||
/** قیمت فروش نمایشی آبشده — فقط cash_fee_sell محصول اختلاف ایجاد میکند */
|
||||
/** قیمت فروش نمایشی محصول آبشدهای */
|
||||
export function getProductSellPrice(product: Product): number {
|
||||
if (product.group_type === 'آبشده') {
|
||||
return getTradeSellPrice(lastPrice.value) - (product.cash_fee_sell ?? 0)
|
||||
if (isMeltedProductUsingAppPrice(product)) {
|
||||
const base = applyPriceOffsetPercent(getTradeSellPrice(lastPrice.value), product.price_offset_percent)
|
||||
return base - (product.cash_fee_sell ?? 0)
|
||||
}
|
||||
|
||||
if (isMeltedTradeGroup(product.group_type)) {
|
||||
const base = (product.price_profit ?? product.price ?? 0)
|
||||
return base - (product.cash_fee_sell ?? 0)
|
||||
}
|
||||
|
||||
return getTradeSellPrice(lastPrice.value)
|
||||
}
|
||||
|
||||
export function isProductPriceInactive(product: Product): boolean {
|
||||
return getProductBuyPrice(product) <= 0
|
||||
}
|
||||
|
||||
export { isMeltedTradeGroup, isMeltedProductUsingAppPrice } from '@/utils/productCategories'
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
export const TRADE_WEIGHT_UNIT_GRAM = 'گرم'
|
||||
export const TRADE_WEIGHT_UNIT_KILOGRAM = 'کیلوگرم'
|
||||
|
||||
export function isKilogramUnit(unit?: string | null) {
|
||||
const value = (unit ?? '').trim()
|
||||
return value === TRADE_WEIGHT_UNIT_KILOGRAM || value === 'kilogram' || value === 'kg'
|
||||
}
|
||||
|
||||
/** واحد نمایش از ستینگ — خالی یا نامعتبر = گرم */
|
||||
export function resolveTradeWeightUnit(settingValue?: string | number | null) {
|
||||
return isKilogramUnit(settingValue?.toString()) ? TRADE_WEIGHT_UNIT_KILOGRAM : TRADE_WEIGHT_UNIT_GRAM
|
||||
}
|
||||
|
||||
export function weightToGrams(value: number, fromUnit?: string | null) {
|
||||
return isKilogramUnit(fromUnit) ? value * 1000 : value
|
||||
}
|
||||
|
||||
export function gramsToTradeUnit(grams: number, displayUnit?: string | null) {
|
||||
return isKilogramUnit(displayUnit ?? resolveTradeWeightUnit(null)) ? grams / 1000 : grams
|
||||
}
|
||||
|
||||
export function convertWeightToDisplayUnit(
|
||||
value: number,
|
||||
fromUnit?: string | null,
|
||||
displayUnit?: string | null
|
||||
) {
|
||||
return gramsToTradeUnit(weightToGrams(value, fromUnit), displayUnit)
|
||||
}
|
||||
|
||||
export function formatTradeWeight(value: number, displayUnit?: string | null) {
|
||||
const unit = resolveTradeWeightUnit(displayUnit)
|
||||
return `${value} ${unit}`
|
||||
}
|
||||
@@ -164,7 +164,7 @@
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>مظنه:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ usePriceWithoutType(((props?.ProductItem?.price_profit) + (props?.ProductItem?.price))) }}</div>
|
||||
<div class="font-bold">{{ usePriceWithoutType(Math.round(basePriceValue ?? 0)) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -656,6 +656,7 @@ async function ok() {
|
||||
method: "cash",
|
||||
number: form.value.goldValue ?? 0
|
||||
})
|
||||
confirmAction.value = false
|
||||
await walletStore.getMyWallet()
|
||||
await router.push({ name: 'transactions' })
|
||||
form.value = {
|
||||
@@ -664,7 +665,6 @@ async function ok() {
|
||||
percentWallet: undefined,
|
||||
method: 'cash'
|
||||
}
|
||||
// refreshTable()
|
||||
await fundStore.getMyFund()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,91 +1,54 @@
|
||||
<template>
|
||||
<div v-if="item" class="bg-white flex flex-col items-center p-3 rounded-xl">
|
||||
<!-- <img v-lazy="{ src: itemImg, loading: logo,error: logo}" alt="" class="w-[87px] ">-->
|
||||
<img v-if="props.item.group_type=='گوی'" :src="goyImg">
|
||||
<img v-if="props.item.group_type=='مکعب'" :src="mokaabImg">
|
||||
<img v-if="props.item.group_type=='سکه'" :src="sekkeImg">
|
||||
<img v-if="props.item.group_type=='مس'" :src="mesImg">
|
||||
<img v-if="props.item.group_type=='نقره'" :src="noghrehImg">
|
||||
<!-- <img :src="props.item.img" alt="image">-->
|
||||
<img v-if="props.item.group_type=='طلا'|| props.item.group_type=='آبشده'|| props.item.group_type== null" :src="defaultImg">
|
||||
<div class="mt-3">{{props.item?.title?? '-'}}</div>
|
||||
<img :src="displayImage" class="w-[87px] h-[87px] object-contain" alt="" @error="onImageError">
|
||||
<div class="mt-3">{{ item.title ?? '-' }}</div>
|
||||
<div class="mt-1 flex flex-col items-center gap-0.5 text-center">
|
||||
<div class="flex gap-1">
|
||||
<div class="font-bold">{{ props.item?.wallet?.gold ?? '-' }}</div>
|
||||
{{ getProductQuantityUnit(props.item) }}
|
||||
<div class="font-bold">{{ item.quantity ?? '-' }}</div>
|
||||
{{ item.unit }}
|
||||
</div>
|
||||
<div v-if="getProductUnitWeightLabel(props.item)" class="text-xs text-gray-500">
|
||||
هر عدد {{ getProductUnitWeightLabel(props.item) }}
|
||||
<div v-if="item.unit_weight" class="text-xs text-gray-500">
|
||||
هر عدد {{ item.unit_weight }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- {{props.item?.wallet[0]?.cash}}-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import homeImg from '@/assets/img/cash_home.svg'
|
||||
import giftImg from '@/assets/img/cash_gift.svg'
|
||||
import circulationImg from '@/assets/img/cash_circulation.svg'
|
||||
import loveImg from '@/assets/img/cash_love.svg'
|
||||
import repairsImg from '@/assets/img/cash_repairs.svg'
|
||||
import savingImg from '@/assets/img/cash_saving.svg'
|
||||
import {computed} from "vue"
|
||||
import type {Fund} from "@/models/fund"
|
||||
import defaultImg from "@/assets/img/defaultAbshodeh.svg"
|
||||
import goyImg from "@/assets/img/goyImg.svg"
|
||||
import mokaabImg from "@/assets/img/mokaabImg.svg"
|
||||
import sekkeImg from "@/assets/img/sekkeImg.svg"
|
||||
import type { Product } from '@/models/products'
|
||||
import mesImg from "@/assets/img/mesImg.jpg";
|
||||
import noghrehImg from "@/assets/img/noghrehImg.webp";
|
||||
import { getProductQuantityUnit, getProductUnitWeightLabel } from '@/utils/productDealMethod'
|
||||
/*function itemImg() {
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import type { WalletInventoryCard } from '@/models/walletAssets'
|
||||
import { getProductDisplayImage } from '@/utils/productAssets'
|
||||
|
||||
}*/
|
||||
interface Prop {
|
||||
item: Product
|
||||
item: WalletInventoryCard
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>()
|
||||
const imageSrc = ref('')
|
||||
|
||||
const itemImg = computed(() => {
|
||||
switch (props.item?.title) {
|
||||
case 'خرید لوازم منزل':
|
||||
return homeImg
|
||||
case 'هدیه':
|
||||
return giftImg
|
||||
case 'گردش':
|
||||
return circulationImg
|
||||
case 'ازدواج':
|
||||
return loveImg
|
||||
case 'تعمیرات':
|
||||
return repairsImg
|
||||
case 'پس انداز':
|
||||
return savingImg
|
||||
default: return savingImg
|
||||
}
|
||||
})
|
||||
const displayImage = computed(() => imageSrc.value || resolveImage())
|
||||
|
||||
/*const itemName = computed(() => {
|
||||
switch (props.type) {
|
||||
case 'home':
|
||||
return 'خرید لوازم منزل'
|
||||
case 'gift':
|
||||
return 'هدیه'
|
||||
case 'circulation':
|
||||
return 'گردش'
|
||||
case 'love':
|
||||
return 'ازدواج'
|
||||
case 'repairs':
|
||||
return 'تعمیرات'
|
||||
case 'saving':
|
||||
return 'پس انداز'
|
||||
default: return null
|
||||
}
|
||||
})*/
|
||||
watch(
|
||||
() => props.item,
|
||||
() => {
|
||||
imageSrc.value = resolveImage()
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
function resolveImage() {
|
||||
return getProductDisplayImage({
|
||||
title: props.item.title,
|
||||
group_type: props.item.group_type,
|
||||
file: props.item.file,
|
||||
})
|
||||
}
|
||||
|
||||
function onImageError() {
|
||||
imageSrc.value = getProductDisplayImage({
|
||||
title: props.item.title,
|
||||
group_type: props.item.group_type,
|
||||
file: null,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
+71
-113
@@ -9,158 +9,116 @@
|
||||
<div class="text-tertiary bg-primary w-screen md:w-full h-[70vh] fixed md:absolute overflow-hidden">
|
||||
<img :src="img" alt="" class="w-full absolute bottom-0 left-0 opacity-5 pointer-events-none z-0" />
|
||||
<div class="pt-15 flex flex-col relative z-10">
|
||||
<div class="text-tertiary font-bold mr-5 z-20">موجودی دارایی ها</div>
|
||||
<div class="flex mt-4 justify-center mt-2 w-full z-20">
|
||||
محصولات:
|
||||
<div class="text-l mr-4 font-bold">{{ walletStore.walletInfo?.count_product ?? 0}}عدد</div>
|
||||
<div class="text-tertiary font-bold mr-5 z-20">موجودی دارایی ها</div>
|
||||
<div v-if="meta?.has_count_based_products" class="flex mt-4 justify-center mt-2 w-full z-20">
|
||||
محصولات:
|
||||
<div class="text-l mr-4 font-bold">{{ countBasedInventory }} عدد</div>
|
||||
</div>
|
||||
<template v-if="meta?.single_metal && primaryMetalTotal">
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
{{ primaryMetalTotal.label }}:
|
||||
<div class="text-l mr-4 font-bold">{{ formatMetalTotal(primaryMetalTotal) }}</div>
|
||||
</div>
|
||||
<div v-if="nameProject === 'goldsun'" class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی نقره:
|
||||
<div class="text-l mr-4 font-bold">{{ walletStore.walletInfo?.count_silver ?? 0}}گرم</div>
|
||||
</div>
|
||||
<div v-if="nameProject === 'goldsun'" class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی مس:
|
||||
<div class="text-l mr-4 font-bold">{{ walletStore.walletInfo?.count_copper ?? 0}}گرم</div>
|
||||
</div>
|
||||
<div v-if="isBoursecuProject()" class="flex justify-center mt-2 w-full z-20">
|
||||
مجموع موجودی:
|
||||
<div class="text-l mr-4 font-bold">{{ inventory }} عدد</div>
|
||||
</div>
|
||||
<div v-if="!isBoursecuProject()" class="flex justify-center mt-2 w-full z-20">
|
||||
{{ metalAssetLabel }}:
|
||||
<div class="text-l mr-4 font-bold">{{ walletStore.walletInfo?.count_gold ?? 0 }}{{ getWeightUnit() }}</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی ریالی:
|
||||
<div class="text-l mr-4 font-bold">{{ usePriceWithoutType(walletStore.walletInfo?.count_cash ?? 0) }}ریال</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
معادل ریالی مجموع دارایی ها:
|
||||
<div class="text-l mr-4 font-bold">{{ usePriceWithoutType(walletStore.walletInfo?.count_cash_total ?? 0) }}ریال</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="metal in metalTotals"
|
||||
:key="`metal-${metal.metal_id}`"
|
||||
class="flex justify-center mt-2 w-full z-20"
|
||||
>
|
||||
{{ metal.label }}:
|
||||
<div class="text-l mr-4 font-bold">{{ formatMetalTotal(metal) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="meta?.has_count_based_products" class="flex justify-center mt-2 w-full z-20">
|
||||
مجموع موجودی:
|
||||
<div class="text-l mr-4 font-bold">{{ countBasedInventory }} عدد</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
دارایی ریالی:
|
||||
<div class="text-l mr-4 font-bold">{{ usePriceWithoutType(cashWallet) }}ریال</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 w-full z-20">
|
||||
معادل ریالی مجموع دارایی ها:
|
||||
<div class="text-l mr-4 font-bold">{{ usePriceWithoutType(totalRialValue) }}ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-[20rem] ">
|
||||
<div class="bg-gray-100 w-screen md:w-full z-20 relative rounded-t-3xl h-[calc(100vh-20rem-70px)] overflow-y-auto pb-15"
|
||||
style="box-shadow: 0px -2px 4px -2px #0000001A;">
|
||||
|
||||
<div v-if="items.length === 0 && !loading" class="w-full h-full flex justify-center items-center">
|
||||
<div v-if="inventoryCards.length === 0 && !loading" class="w-full h-full flex justify-center items-center">
|
||||
<div>
|
||||
<img :src="empty" alt="" class="w-70 ">
|
||||
<div v-if="nameProject !== 'abaeigold' " class="text-center text-lg">یک گنج جدید بساز!</div>
|
||||
<div v-if="nameProject !== 'abaeigold'" class="text-center text-lg">یک گنج جدید بساز!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-spin :spinning="loading">
|
||||
<div :class="loading? 'h-[40vh]':''" class="grid grid-cols-2 gap-3 p-5">
|
||||
<Item v-for="item in items.filter(x => x.title !== 'آبشده نقدی')" :item="item"
|
||||
@click="router.push({name: 'fund_info', params:{id:item.id}})"
|
||||
<div :class="loading ? 'h-[40vh]' : ''" class="grid grid-cols-2 gap-3 p-5">
|
||||
<Item
|
||||
v-for="item in inventoryCards"
|
||||
:key="item.product_id"
|
||||
:item="item"
|
||||
@click="router.push({ name: 'fund_info', params: { id: item.product_id } })"
|
||||
/>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="fixed w-full flex justify-center bottom-23 z-200 md:right-0">
|
||||
<div class="rounded-3xl bg-[#0A1B37] text-white px-5 py-2" @click="router.push({name: 'fund_add'})">افزودن گنج
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
import router from "@/router";
|
||||
import BasicIcon from "@/components/BasicPacks/BasicIcon.vue";
|
||||
import BasicModal from "@/components/BasicPacks/BasicModal.vue";
|
||||
import router from '@/router'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import img from '@/assets/img/user_ly1.svg'
|
||||
import empty from '@/assets/img/cash_empty.svg'
|
||||
import Item from './components/Item.vue'
|
||||
import { onMounted, ref, computed } from "vue";
|
||||
import {loading} from "@/utils";
|
||||
import type {TableOutput} from "@/models/table";
|
||||
import type {Fund} from "@/models/fund";
|
||||
import {useFundUserStore} from "@/store/fundStore";
|
||||
import { getMe } from '@/api/me'
|
||||
import type { User } from '@/models/login'
|
||||
import {usePriceWithoutType} from "../../../utils/usePrice";
|
||||
import {useWalletStore} from "@/store/walletStore";
|
||||
import {useConfigStore} from "@/store/configStore";
|
||||
import { isBoursecuProject } from '@/utils/config'
|
||||
import { formatBoursecuAssetAmount, getMetalAssetLabel, getWeightUnit } from '@/utils/productDealMethod'
|
||||
import { onMounted, computed } from 'vue'
|
||||
import { loading } from '@/utils'
|
||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
||||
import { useConfigStore } from '@/store/configStore'
|
||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
||||
|
||||
const nameProject = useConfigStore().config.name
|
||||
const metalAssetLabel = computed(() => getMetalAssetLabel())
|
||||
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
||||
|
||||
const items = ref<Fund[]>([])
|
||||
const tableOutput = ref<TableOutput<Fund> | null>(null)
|
||||
const fundStore = useFundUserStore()
|
||||
const walletStore = useWalletStore()
|
||||
const userInfo = ref<User>()
|
||||
const weight = ref<number>(0)
|
||||
const total = ref<number>(0)
|
||||
|
||||
const inventory = computed(() =>
|
||||
items.value
|
||||
.filter(x => x.title !== 'آبشده نقدی')
|
||||
.reduce((sum, x) => sum + (x?.wallet?.gold ?? 0), 0)
|
||||
const meta = computed(() => assetsSummary.value?.meta)
|
||||
const inventoryCards = computed(() => assetsSummary.value?.inventory_cards ?? [])
|
||||
const metalTotals = computed(() => assetsSummary.value?.metal_totals ?? [])
|
||||
const primaryMetalTotal = computed(() => metalTotals.value[0])
|
||||
const cashWallet = computed(() => assetsSummary.value?.cash_wallet ?? 0)
|
||||
const totalRialValue = computed(() => assetsSummary.value?.total_rial_value ?? 0)
|
||||
const countBasedInventory = computed(() =>
|
||||
(assetsSummary.value?.count_products ?? []).reduce((sum, item) => sum + Number(item.quantity ?? 0), 0)
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
initTable()
|
||||
})
|
||||
|
||||
async function initTable() {
|
||||
onMounted(async () => {
|
||||
try {
|
||||
userInfo.value = await getMe()
|
||||
loading.value = true
|
||||
tableOutput.value = fundStore.myFunds ?? await fundStore.getMyFund() ?? null
|
||||
console.log(tableOutput.value)
|
||||
items.value.push(...tableOutput.value?.rows ?? [])
|
||||
items.value.forEach(x => {
|
||||
total.value += ((x?.wallet?.gold) ?? 0) * ((x?.price) ?? 0)
|
||||
if (x.title !== 'آبشده نقدی' && x.title !== 'سکه')
|
||||
weight.value += ((x?.wallet?.gold) ?? 0) * ((x?.amount) ?? 0)
|
||||
})
|
||||
await loadWalletAssets(true)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
|
||||
function summaryMetalWeight(metal: WalletMetalTotal) {
|
||||
if (inventoryCards.value.length > 0) {
|
||||
return metal.product_weight
|
||||
}
|
||||
|
||||
return metal.total_weight
|
||||
}
|
||||
|
||||
/*watch(()=> router.currentRoute.value.name, () =>{
|
||||
console.log('salammmmmmmmmmmmmmmmmmmmmmmmmmm')
|
||||
})*/
|
||||
/*
|
||||
const items = [
|
||||
{
|
||||
type: 'home',
|
||||
amount: 2.7
|
||||
},
|
||||
{
|
||||
type: 'gift',
|
||||
amount: 13.1
|
||||
},
|
||||
{
|
||||
type: 'saving',
|
||||
amount: 6.4
|
||||
},
|
||||
{
|
||||
type: 'repairs',
|
||||
amount: 16.6
|
||||
},
|
||||
{
|
||||
type: 'circulation',
|
||||
amount: 5.4
|
||||
},
|
||||
{
|
||||
type: 'love',
|
||||
amount: 3.7
|
||||
},
|
||||
]
|
||||
*/
|
||||
|
||||
function formatMetalTotal(metal: WalletMetalTotal) {
|
||||
return `${summaryMetalWeight(metal)}${metal.unit}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
<div class="flex justify-evenly w-full px-2 h-11 items-center bg-gray-50 relative rounded ">
|
||||
<div :class="isBuy?'text-tertiary':'text-gray-400'" class="w-full text-center z-2"
|
||||
@click.stop="setIsBuy(true) ">
|
||||
خرید {{ meltedGoldLabel }} {{ props?.ProductItem?.title }}
|
||||
خرید {{ tradeProductLabel }}
|
||||
</div>
|
||||
<div :class="!isBuy?'text-tertiary':'text-gray-400'" class="w-full text-center z-2"
|
||||
@click.stop="setIsBuy(false) ">
|
||||
فروش {{ meltedGoldLabel }} {{ props?.ProductItem?.title }}
|
||||
فروش {{ tradeProductLabel }}
|
||||
</div>
|
||||
<!-- <div ref="bganim" class="absolute bg-white h-8 w-1/2 rounded-lg " :style="`transform: translateX(${isbuy? '0':'-100%'}); left: ${isbuy? '0':'100%'}`"></div>-->
|
||||
<div ref="bganim" :style="useStyle()"
|
||||
@@ -53,9 +53,9 @@
|
||||
type="price" @onchange="calculateGold" />
|
||||
</a-form-item>
|
||||
<a-form-item :rules="[justNumber()]">
|
||||
<BasicInput v-model:value="form.goldValue" addon-before="گرم" :addon-bg-color="useConfigStore().config.color"
|
||||
<BasicInput v-model:value="form.goldValue" :addon-before="weightUnit" :addon-bg-color="useConfigStore().config.color"
|
||||
addon-text-color="white"
|
||||
place-holder="مقدار طلا"
|
||||
:place-holder="amountFieldLabel"
|
||||
size="large" type="text" inputmode="decimal" @onchange="calculateCash" />
|
||||
</a-form-item>
|
||||
<div v-if="cashValidationMessage" class="text-red-700 text-xs font-bold mt-2">
|
||||
@@ -133,7 +133,7 @@
|
||||
<div class="flex gap-2 items-center">
|
||||
<div class="">{{ feeInGrams }}</div>
|
||||
<div>
|
||||
گرم
|
||||
{{ weightUnit }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -157,13 +157,13 @@
|
||||
<div>وزن:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ form.goldValue }}</div>
|
||||
<div class="text-xs mr-1">گرم</div>
|
||||
<div class="text-xs mr-1">{{ weightUnit }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>مظنه:</div>
|
||||
<div class="flex items-center">
|
||||
<div class="font-bold">{{ usePriceWithoutType(isBuy ? getTradeBuyPrice(lastPrice) : getTradeSellPrice(lastPrice)) }}</div>
|
||||
<div class="font-bold">{{ usePriceWithoutType(Math.round(goldPriceValue)) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -171,7 +171,7 @@
|
||||
<div>کارمزد:</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="font-bold text-xl">{{ feeInGrams }}</div>
|
||||
<div class="text-xs mr-1">گرم</div>
|
||||
<div class="text-xs mr-1">{{ weightUnit }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div >(معادل {{ equivalentPrice }} ریال)</div>
|
||||
@@ -236,7 +236,8 @@ import type { Product } from '@/models/products'
|
||||
import { useFundUserStore } from '@/store/fundStore'
|
||||
import {useConfigStore} from "@/store/configStore";
|
||||
import { calcFeeInGrams, loadServiceFeeFromSettings } from '@/utils/serviceFee'
|
||||
import { formatCashWalletBalanceText, formatGoldWalletBalanceText } from '@/utils/productDealMethod'
|
||||
import { formatCashWalletBalanceText, formatGoldWalletBalanceText, getWeightUnit } from '@/utils/productDealMethod'
|
||||
import { isMeltedTradeGroup } from '@/utils/productCategories'
|
||||
import { useSettingsStore } from '@/store/settingsStore'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import {
|
||||
@@ -250,6 +251,7 @@ const walletStore = useWalletStore()
|
||||
const userStore = useUserStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const { meltedGoldLabel } = storeToRefs(settingsStore)
|
||||
const weightUnit = computed(() => getWeightUnit())
|
||||
const fundStore = useFundUserStore()
|
||||
const confirmAction = ref<boolean>(false)
|
||||
const noCompleteVisible = ref<boolean>(false)
|
||||
@@ -267,6 +269,12 @@ interface Prop {
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const isBuy = ref<boolean>(true)
|
||||
|
||||
const tradeProductLabel = computed(() => {
|
||||
const title = props.ProductItem?.title?.trim()
|
||||
return title || meltedGoldLabel.value
|
||||
})
|
||||
const amountFieldLabel = computed(() => `مقدار ${tradeProductLabel.value}`)
|
||||
|
||||
const buyPagination = ref<TableEngineInput>({
|
||||
filters: [{
|
||||
field: 'type',
|
||||
@@ -288,8 +296,8 @@ const sellPagination = ref<TableEngineInput>({
|
||||
|
||||
const unitPrice = computed(() => {
|
||||
const product = props.ProductItem
|
||||
if (product?.group_type === 'آبشده') {
|
||||
return isBuy.value ? getProductBuyPrice(product) : getProductSellPrice(product)
|
||||
if (isMeltedTradeGroup(product?.group_type)) {
|
||||
return isBuy.value ? getProductBuyPrice(product!) : getProductSellPrice(product!)
|
||||
}
|
||||
return isBuy.value ? getTradeBuyPrice(lastPrice.value) : getTradeSellPrice(lastPrice.value)
|
||||
})
|
||||
@@ -307,6 +315,11 @@ const cashValidationMessage = computed(() =>
|
||||
productCashValidationMessage(props.ProductItem, form.value?.goldCash, isBuy.value, usePriceWithoutType)
|
||||
)
|
||||
|
||||
const priceUnavailable = computed(() => {
|
||||
const unit = unitPrice.value
|
||||
return !unit || Number.isNaN(unit) || unit <= 0
|
||||
})
|
||||
|
||||
const disableTransaction = computed(() =>
|
||||
loading.value ||
|
||||
form.value?.goldValue === undefined ||
|
||||
@@ -321,8 +334,7 @@ const disableTransaction = computed(() =>
|
||||
(maxOrderCash.value != null && (form.value?.goldCash ?? 0) > maxOrderCash.value) ||
|
||||
cashValidationMessage.value !== '' ||
|
||||
(!isBuy.value && form.value.goldValue > walletStore?.walletInfo?.gold) ||
|
||||
!lastPrice.value ||
|
||||
(isBuy.value ? getTradeBuyPrice(lastPrice.value) <= 0 : getTradeSellPrice(lastPrice.value) <= 0))
|
||||
priceUnavailable.value)
|
||||
|
||||
function refreshTable() {
|
||||
sellItems.value = []
|
||||
@@ -498,7 +510,8 @@ const limitedPrice = computed(() => {
|
||||
})
|
||||
|
||||
function syncFormWithLatestPrice() {
|
||||
if (!lastPrice.value) return
|
||||
const unit = unitPrice.value
|
||||
if (!unit || Number.isNaN(unit)) return
|
||||
|
||||
const goldValue = form.value.goldValue
|
||||
if (goldValue !== undefined && goldValue !== null && goldValue !== '' && !isNaN(Number(goldValue))) {
|
||||
@@ -513,7 +526,7 @@ function syncFormWithLatestPrice() {
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [getTradeBuyPrice(lastPrice.value), getTradeSellPrice(lastPrice.value), isBuy.value],
|
||||
() => [unitPrice.value, isBuy.value, props.ProductItem?.id],
|
||||
() => {
|
||||
syncFormWithLatestPrice()
|
||||
}
|
||||
@@ -521,20 +534,20 @@ watch(
|
||||
|
||||
function calculateCash(val: number) {
|
||||
priceErrorVisible.value = false
|
||||
if (!lastPrice.value) return
|
||||
const unit = unitPrice.value
|
||||
if (!unit || Number.isNaN(unit)) return
|
||||
|
||||
const unit = isBuy.value ? getTradeBuyPrice(lastPrice.value) : getTradeSellPrice(lastPrice.value)
|
||||
form.value.goldCash = val ? parseFloat((val * unit).toFixed(0)) : undefined
|
||||
}
|
||||
|
||||
function calculateGold(val: number) {
|
||||
if (!lastPrice.value) return
|
||||
const unit = unitPrice.value
|
||||
if (!unit || Number.isNaN(unit)) return
|
||||
|
||||
const unit = isBuy.value ? getTradeBuyPrice(lastPrice.value) : getTradeSellPrice(lastPrice.value)
|
||||
if (isBuy.value) {
|
||||
if (val) {
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / unit)))
|
||||
priceErrorVisible.value = parseInt(finalPrice.value) > 0
|
||||
priceErrorVisible.value = parseInt(String(finalPrice.value)) > 0
|
||||
} else if (val.toString() === '') {
|
||||
form.value.goldValue = undefined
|
||||
priceErrorVisible.value = false
|
||||
@@ -544,7 +557,7 @@ function calculateGold(val: number) {
|
||||
}
|
||||
} else if (val) {
|
||||
form.value.goldValue = toFixedDownThreeChar(parseFloat(String(val / unit)))
|
||||
priceErrorVisible.value = parseInt(finalPrice.value) > 0
|
||||
priceErrorVisible.value = parseInt(String(finalPrice.value)) > 0
|
||||
} else if (val.toString() === '') {
|
||||
form.value.goldValue = undefined
|
||||
priceErrorVisible.value = false
|
||||
@@ -590,12 +603,7 @@ const formatter = (value: number) => {
|
||||
|
||||
const price = computed((): Price => <Price>lastPrice.value ?? 0)
|
||||
|
||||
const goldPriceValue = computed(() => {
|
||||
if (!lastPrice.value?.price) return 0
|
||||
return isBuy.value
|
||||
? getTradeBuyPrice(lastPrice.value)
|
||||
: getTradeSellPrice(lastPrice.value)
|
||||
})
|
||||
const goldPriceValue = computed(() => unitPrice.value)
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
@@ -625,10 +633,11 @@ async function ok() {
|
||||
infoVisible.value = true
|
||||
await createOrder({
|
||||
direction: isBuy.value ? 1 : 2,
|
||||
price: isBuy.value ? getTradeBuyPrice(lastPrice.value) : getTradeSellPrice(lastPrice.value),
|
||||
price: Math.round(unitPrice.value),
|
||||
amount: form.value.goldValue ?? 0,
|
||||
abshode_id: props.ProductItem?.id,
|
||||
})
|
||||
confirmAction.value = false
|
||||
await walletStore.getMyWallet()
|
||||
await router.push({ name: 'transactions' })
|
||||
form.value = {
|
||||
@@ -636,7 +645,6 @@ async function ok() {
|
||||
goldCash: undefined,
|
||||
percentWallet: undefined
|
||||
}
|
||||
// refreshTable()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
await fundStore.getMyFund()
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,36 +1,82 @@
|
||||
<template>
|
||||
<div class="bg-primary rounded-lg p-2 py-3 mt-2">
|
||||
<div class="flex justify-center text-tertiary w-full z-20">
|
||||
<div v-if="meta?.has_count_based_products" class="flex justify-center text-tertiary w-full z-20">
|
||||
محصولات:
|
||||
<div class="text-l mr-2 font-bold">{{ userStore?.userInfo?.wallet?.count_product ?? 0 }} عدد</div>
|
||||
</div>
|
||||
<div v-if="!isBoursecuProject()" class="flex mt-2 justify-center text-tertiary w-full z-20">
|
||||
{{ metalAssetLabel }}:
|
||||
<div class="text-l mr-2 font-bold">{{ (userStore?.userInfo?.wallet?.count_gold ?? 0).toFixed(3) }} {{ weightUnit }}</div>
|
||||
<BasicIcon @click="$emit('openGoldModal')" icon="vuesax-linear:info-circle" size="18" color="tertiary" />
|
||||
<div class="text-l mr-2 font-bold">{{ countBasedInventory }} عدد</div>
|
||||
</div>
|
||||
<template v-if="meta?.single_metal && primaryMetalTotal">
|
||||
<div class="flex mt-2 justify-center text-tertiary w-full z-20">
|
||||
{{ primaryMetalTotal.label }}:
|
||||
<div class="text-l mr-2 font-bold">{{ formatMetalTotal(primaryMetalTotal) }}</div>
|
||||
<BasicIcon
|
||||
icon="vuesax-linear:info-circle"
|
||||
size="18"
|
||||
color="tertiary"
|
||||
@click="$emit('openGoldModal')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="metal in metalTotals"
|
||||
:key="metal.metal_id"
|
||||
class="flex mt-2 justify-center text-tertiary w-full z-20"
|
||||
>
|
||||
{{ metal.label }}:
|
||||
<div class="text-l mr-2 font-bold">{{ formatMetalTotal(metal) }}</div>
|
||||
<BasicIcon
|
||||
v-if="metal.metal_id === metalTotals[0]?.metal_id"
|
||||
icon="vuesax-linear:info-circle"
|
||||
size="18"
|
||||
color="tertiary"
|
||||
@click="$emit('openGoldModal')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex mt-2 justify-center text-tertiary w-full z-20">
|
||||
دارایی ریالی:
|
||||
<div class="text-l mr-2 font-bold">{{ usePriceWithoutType(userStore?.userInfo?.wallet?.count_cash ?? 0) }} ریال</div>
|
||||
<div class="text-l mr-2 font-bold">{{ usePriceWithoutType(cashWallet) }} ریال</div>
|
||||
<BasicIcon @click="$emit('openRialModal')" icon="vuesax-linear:info-circle" size="18" color="tertiary" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { computed, onMounted } from 'vue'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import {usePriceWithoutType} from "../../../../utils/usePrice";
|
||||
import { isBoursecuProject } from '@/utils/config'
|
||||
import { getMetalAssetLabel, getWeightUnit } from '@/utils/productDealMethod'
|
||||
import { usePriceWithoutType } from '@/utils/usePrice'
|
||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const metalAssetLabel = computed(() => getMetalAssetLabel())
|
||||
const weightUnit = computed(() => getWeightUnit())
|
||||
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
||||
|
||||
defineEmits<{
|
||||
openGoldModal: []
|
||||
openRialModal: []
|
||||
}>()
|
||||
</script>
|
||||
|
||||
const meta = computed(() => assetsSummary.value?.meta)
|
||||
const metalTotals = computed(() => assetsSummary.value?.metal_totals ?? [])
|
||||
const primaryMetalTotal = computed(() => metalTotals.value[0])
|
||||
const cashWallet = computed(() => assetsSummary.value?.cash_wallet ?? 0)
|
||||
const inventoryCards = computed(() => assetsSummary.value?.inventory_cards ?? [])
|
||||
const countBasedInventory = computed(() =>
|
||||
(assetsSummary.value?.count_products ?? []).reduce((sum, item) => sum + Number(item.quantity ?? 0), 0)
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
void loadWalletAssets()
|
||||
})
|
||||
|
||||
function summaryMetalWeight(metal: WalletMetalTotal) {
|
||||
if (inventoryCards.value.length > 0) {
|
||||
return metal.product_weight
|
||||
}
|
||||
|
||||
return metal.total_weight
|
||||
}
|
||||
|
||||
function formatMetalTotal(metal: WalletMetalTotal) {
|
||||
return `${summaryMetalWeight(metal)}${metal.unit}`
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,50 +5,27 @@
|
||||
<div class="w-full text-center font-bold">موجودی ها</div>
|
||||
<div class="h-30vh overflow-y-auto">
|
||||
<div class="mt-5">
|
||||
<BasicInfoItem
|
||||
<template v-for="metal in metalTotals" :key="metal.metal_id">
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
:title="`مجموعه کل دارایی ${settingsStore.metalTypeLabel}`"
|
||||
:title="metal.label"
|
||||
is-line
|
||||
:info="`در این قسمت مجموع کل وزن ${settingsStore.metalTypeLabel} آبشده (${(walletInfo?.gold ?? 0)?.toFixed(3)}) + ارزش دارایی ها (${(walletInfo?.treasure_sum ?? 0)?.toFixed(3)} ) را مشاهده میفرمایید.`"
|
||||
:infoHead="`مجموع کل دارایی ${settingsStore.metalTypeLabel}`"
|
||||
:value="parseFloat((walletInfo?.gold_sum ?? 0).toFixed(2)) + ' ' + weightUnit"
|
||||
:value="formatMetalTotal(metal)"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
</template>
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول ریالی"
|
||||
is-line
|
||||
:value="usePrice(cashWallet)"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول ریالی"
|
||||
is-line
|
||||
:value="usePrice(walletInfo?.cash ?? 0)"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
:title="`دارایی کیف پول ${settingsStore.metalTypeLabel}`"
|
||||
is-line
|
||||
:value="(walletInfo?.count_gold_wallet ?? 0) + ' ' + weightUnit"
|
||||
/>
|
||||
<a-divider v-if="nameProject === 'goldsun'" class="!my-1" />
|
||||
<BasicInfoItem
|
||||
v-if="nameProject === 'goldsun'"
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول نقره"
|
||||
is-line
|
||||
:value="(walletInfo?.count_silver ?? 0) + ' گرم'"
|
||||
/>
|
||||
<a-divider v-if="nameProject === 'goldsun'" class="!my-1" />
|
||||
<BasicInfoItem
|
||||
v-if="nameProject === 'goldsun'"
|
||||
class="flex justify-between"
|
||||
title="دارایی کیف پول مس"
|
||||
is-line
|
||||
:value="(walletInfo?.count_copper ?? 0) + ' گرم'"
|
||||
/>
|
||||
<a-divider class="!my-1" />
|
||||
<BasicInfoItem
|
||||
class="flex justify-between"
|
||||
title="معادل ریالی مجموع دارایی ها"
|
||||
is-line
|
||||
:value="usePrice(walletInfo?.count_cash_total ?? 0)"
|
||||
class="flex justify-between"
|
||||
title="معادل ریالی مجموع دارایی ها"
|
||||
is-line
|
||||
:value="usePrice(totalRialValue)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,13 +35,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { computed, onMounted, watch } from 'vue'
|
||||
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
|
||||
import BasicInfoItem from '@/components/BasicPacks/BasicInfoItem.vue'
|
||||
import { useConfigStore } from '@/store/configStore'
|
||||
import { useSettingsStore } from '@/store/settingsStore'
|
||||
import { getWeightUnit } from '@/utils/productDealMethod'
|
||||
import {usePrice} from "@/utils/usePrice";
|
||||
import { usePrice } from '@/utils/usePrice'
|
||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||
import type { WalletMetalTotal } from '@/models/walletAssets'
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
@@ -76,13 +52,31 @@ const emit = defineEmits<{
|
||||
'update:show': [value: boolean]
|
||||
}>()
|
||||
|
||||
const config = useConfigStore()
|
||||
const nameProject = config.config.name
|
||||
const settingsStore = useSettingsStore()
|
||||
const weightUnit = computed(() => getWeightUnit())
|
||||
const { assetsSummary, loadWalletAssets } = useWalletAssets()
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.show,
|
||||
set: (val) => emit('update:show', val)
|
||||
set: (val) => emit('update:show', val),
|
||||
})
|
||||
</script>
|
||||
|
||||
const metalTotals = computed(() => assetsSummary.value?.metal_totals ?? [])
|
||||
const cashWallet = computed(() => assetsSummary.value?.cash_wallet ?? 0)
|
||||
const totalRialValue = computed(() => assetsSummary.value?.total_rial_value ?? 0)
|
||||
|
||||
onMounted(() => {
|
||||
void loadWalletAssets()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
(open) => {
|
||||
if (open) {
|
||||
void loadWalletAssets(true)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
function formatMetalTotal(metal: WalletMetalTotal) {
|
||||
return `${metal.total_weight} ${metal.unit}`
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -82,6 +82,7 @@ import {useWindowScroll} from '@vueuse/core'
|
||||
import {loading, removeToken} from '@/utils'
|
||||
import {useUserStore} from '@/store/userStore'
|
||||
import {useWalletStore} from '@/store/walletStore'
|
||||
import { useWalletAssets } from '@/composables/useWalletAssets'
|
||||
import {useConfigStore} from '@/store/configStore'
|
||||
import {useFundUserStore} from '@/store/fundStore'
|
||||
import {usePrice, usePriceWithoutType} from '../../../utils/usePrice'
|
||||
@@ -204,6 +205,7 @@ function copyCode() {
|
||||
async function logout() {
|
||||
userStore.userInfo = undefined
|
||||
walletStore.walletInfo = undefined
|
||||
useWalletAssets().clearWalletAssets()
|
||||
removeToken()
|
||||
await router.push({name: 'login'})
|
||||
window.location.reload()
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
:show-search="false"
|
||||
value-name="value"
|
||||
:allow-clear="false"
|
||||
:placeholder="isBuy?'نحوه خرید را انتخاب کنید':' نحوه فروش را انتخاب کنید'"
|
||||
:placeholder="getProductDealMethodPlaceholder(isBuy)"
|
||||
size="large"
|
||||
:has-tooltip="false" />
|
||||
</a-form-item>
|
||||
@@ -103,7 +103,9 @@
|
||||
<div v-else-if="isBuy && form.method === 'cash'" class="font-bold text-xs">
|
||||
{{ cashWalletBalanceText }}
|
||||
</div>
|
||||
<div class="font-bold text-xs" v-else>{{ `موجودی محصول: ${getInventoryById(props?.ProductItem?.id)} ${getProductQuantityUnit(props?.ProductItem)}` }}
|
||||
<div class="font-bold text-xs" v-else>
|
||||
<div>{{ `موجودی محصول: ${getInventoryById(props?.ProductItem?.id)} ${getProductQuantityUnit(props?.ProductItem)}` }}</div>
|
||||
<div v-if="isMetalReceiveDeal" class="mt-1">{{ sellMetalWalletBalanceText }}</div>
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition mode="out-in" name="fade">
|
||||
@@ -225,10 +227,15 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>{{ isBuy ? 'قیمت قابل پرداخت:' : 'مبلغ دریافتی:' }}</div>
|
||||
<div>{{ isBuy ? 'قیمت قابل پرداخت:' : (isMetalReceiveDeal ? 'دریافت:' : 'مبلغ دریافتی:') }}</div>
|
||||
<div class="flex items-center">
|
||||
<div>{{ usePriceWithoutType(form.goldCash ?? 0) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
<template v-if="!isBuy && isMetalReceiveDeal">
|
||||
<div>{{ sellReceivedMetalText }}</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>{{ usePriceWithoutType(form.goldCash ?? 0) }}</div>
|
||||
<div class="text-xs mr-1">ریال</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -269,9 +276,13 @@ import { useFundUserStore } from '@/store/fundStore'
|
||||
import {
|
||||
getDefaultProductDealMethod,
|
||||
getProductDealMethodOptions,
|
||||
getProductDealMethodPlaceholder,
|
||||
formatCashWalletBalanceText,
|
||||
formatGoldWalletBalanceText,
|
||||
formatMainMetalWalletBalanceText,
|
||||
formatMainMetalReceiveText,
|
||||
calcSellReceivedMetalWeight,
|
||||
isMainMetalWalletDealMethod,
|
||||
formatProductWeightAmount,
|
||||
getProductQuantityUnit,
|
||||
getProductTotalWeightLabel,
|
||||
@@ -286,7 +297,17 @@ import {
|
||||
productMinOrderCash
|
||||
} from '@/utils/productOrderLimit'
|
||||
|
||||
const typeDeal = computed(() => getProductDealMethodOptions(props?.ProductItem?.group_type))
|
||||
const typeDeal = computed(() => getProductDealMethodOptions(props?.ProductItem?.group_type, isBuy.value))
|
||||
|
||||
const isMetalReceiveDeal = computed(() =>
|
||||
!isBuy.value && isMainMetalWalletDealMethod(form.value.method)
|
||||
)
|
||||
|
||||
const sellReceivedMetalText = computed(() =>
|
||||
formatMainMetalReceiveText(
|
||||
calcSellReceivedMetalWeight(form.value.goldValue, props?.ProductItem)
|
||||
)
|
||||
)
|
||||
|
||||
const productGroupType = computed(() => props?.ProductItem?.group_type)
|
||||
const isCountBasedProductItem = computed(() => isCountBasedProduct(props?.ProductItem))
|
||||
@@ -314,6 +335,10 @@ const buyMetalWalletBalanceText = computed(() =>
|
||||
: goldWalletBalanceText.value
|
||||
)
|
||||
|
||||
const sellMetalWalletBalanceText = computed(() =>
|
||||
formatMainMetalWalletBalanceText(walletStore?.walletInfo?.gold ?? 0)
|
||||
)
|
||||
|
||||
const cashWalletBalanceText = computed(() =>
|
||||
formatCashWalletBalanceText(
|
||||
usePriceWithoutType(walletStore?.walletInfo?.cash ?? 0),
|
||||
@@ -339,6 +364,7 @@ interface Prop {
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Prop>(), {})
|
||||
const emit = defineEmits<{ ordered: [] }>()
|
||||
const isBuy = ref<boolean>(true)
|
||||
const buyTotalPrice = computed(() => {
|
||||
const item = props?.ProductItem
|
||||
@@ -520,7 +546,7 @@ const form = ref<Gold>({
|
||||
})
|
||||
|
||||
function resetDealMethod() {
|
||||
form.value.method = getDefaultProductDealMethod(props?.ProductItem?.group_type)
|
||||
form.value.method = getDefaultProductDealMethod(props?.ProductItem?.group_type, isBuy.value)
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -772,20 +798,21 @@ async function ok() {
|
||||
method: form.value.method,
|
||||
number: form.value.goldValue ?? 0
|
||||
})
|
||||
confirmAction.value = false
|
||||
emit('ordered')
|
||||
await userStore.getMyInfo()
|
||||
await walletStore.getMyWallet()
|
||||
await fundStore.getMyFund()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
await router.push({ name: 'transactions' })
|
||||
form.value = {
|
||||
goldValue: undefined,
|
||||
goldCash: undefined,
|
||||
percentWallet: undefined,
|
||||
method: getDefaultProductDealMethod(props?.ProductItem?.group_type)
|
||||
method: getDefaultProductDealMethod(props?.ProductItem?.group_type, isBuy.value)
|
||||
}
|
||||
// refreshTable()
|
||||
await fundStore.getMyFund()
|
||||
message.success('سفارش شما با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
// console.log(e)
|
||||
// await initPrice()
|
||||
} finally {
|
||||
loading.value = false
|
||||
infoVisible.value = false
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-secondary font-500">{{ props.ProductItem.amount }}گرم</div>-->
|
||||
<!-- <div v-else class="text-secondary font-500">حداقل خرید یک گرم</div>-->
|
||||
<!-- <div>{{usePrice((props.ProductItem.price ?? 0) + (props.ProductItem.cash_fee_buy ?? 0))}}</div>-->
|
||||
<div v-if="props.ProductItem.group_type=='آبشده'">{{usePrice(goldPriceValue)}}</div>
|
||||
<div v-if="isMeltedTradeGroup(props.ProductItem.group_type)">{{usePrice(goldPriceValue)}}</div>
|
||||
<div v-else>{{usePrice(price)}}</div>
|
||||
<!-- <div v-if="props.ProductItem.group_type!='آبشده'" class="text-xs text-gray-400">شامل 33 هزار تومان اجرت</div>-->
|
||||
<!-- <div v-else class="text-xs text-gray-400">محاسبه بر اساس قیمت روز</div>-->
|
||||
@@ -33,6 +33,7 @@ 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
|
||||
@@ -58,6 +59,8 @@ const defaultImages: Record<string, string> = {
|
||||
'مس': mesImg,
|
||||
'نقره': noghrehImg,
|
||||
'سکه پارسیان': parsianImg,
|
||||
'کاتد مس': defaultImg,
|
||||
'طلا': defaultImg,
|
||||
}
|
||||
|
||||
const displayImage = computed(() => {
|
||||
@@ -111,7 +114,7 @@ const goldPriceValue = computed(() => getProductBuyPrice(props.ProductItem))
|
||||
<div class="m-1 flex flex-col gap-1 justify-center">
|
||||
<div class="text-base font-500">{{ props.ProductItem.title }}</div>
|
||||
<br>
|
||||
<div v-if="props.ProductItem.group_type=='آبشده'">{{usePrice(goldPriceValue)}}</div>
|
||||
<div v-if="isMeltedTradeGroup(props.ProductItem.group_type)">{{usePrice(goldPriceValue)}}</div>
|
||||
<div v-else>{{usePrice(price)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,16 +30,16 @@
|
||||
<!-- </BasicActionSheet>-->
|
||||
|
||||
<BasicActionSheet placement="bottom" v-model:show="showFilter">
|
||||
<div class="">
|
||||
<indexGold v-if="['آبشده'].includes(selectedProduct?.group_type) && !isBoursecuProject()"
|
||||
<div v-if="showFilter" :key="orderSheetKey">
|
||||
<indexGold v-if="isMeltedTradeGroup(selectedProduct?.group_type)"
|
||||
:ProductItem="selectedProduct"
|
||||
>
|
||||
</indexGold>
|
||||
<CopperSilver v-else-if="['مس','نقره'].includes(selectedProduct?.group_type) && !isBoursecuDealProductGroup(selectedProduct?.group_type)"
|
||||
<CopperSilver v-else-if="isMetalCommodityGroup(selectedProduct?.group_type) && !isBoursecuDealProductGroup(selectedProduct?.group_type)"
|
||||
:ProductItem="selectedProduct"
|
||||
>
|
||||
</CopperSilver>
|
||||
<DealProduct v-else :ProductItem="selectedProduct"></DealProduct>
|
||||
<DealProduct v-else :ProductItem="selectedProduct" @ordered="onProductOrdered"></DealProduct>
|
||||
</div>
|
||||
</BasicActionSheet>
|
||||
|
||||
@@ -105,12 +105,13 @@ import { cloneDeep } from 'lodash'
|
||||
import img from "@/assets/img/user_ly1.svg";
|
||||
import BasicModal from "@/components/BasicPacks/BasicModal.vue";
|
||||
import { isProductPriceInactive } from '@/utils/productPrice'
|
||||
import { isBoursecuProject } from '@/utils/config'
|
||||
import { isMetalCommodityGroup, isMeltedTradeGroup } from '@/utils/productCategories'
|
||||
import { isBoursecuDealProductGroup } from '@/utils/productDealMethod'
|
||||
import { loadServiceFeeFromSettings } from '@/utils/serviceFee'
|
||||
|
||||
const activekey = ref('طلا' ||'آبشده')
|
||||
const showFilter = ref(false)
|
||||
const orderSheetKey = ref(0)
|
||||
const selectedProduct = ref<Product>()
|
||||
const closeTime = ref<string>('')
|
||||
const openTime = ref<string>('')
|
||||
@@ -137,10 +138,21 @@ function clickProduct(item?: Product) {
|
||||
return
|
||||
}
|
||||
|
||||
orderSheetKey.value += 1
|
||||
selectedProduct.value = cloneDeep(item)
|
||||
showFilter.value = true
|
||||
}
|
||||
|
||||
function onProductOrdered() {
|
||||
showFilter.value = false
|
||||
}
|
||||
|
||||
watch(showFilter, (open) => {
|
||||
if (!open) {
|
||||
orderSheetKey.value += 1
|
||||
}
|
||||
})
|
||||
|
||||
function changeTab() {
|
||||
if (activekey.value != 'همه') {
|
||||
items.value = firstItems.value?.filter((val) =>
|
||||
|
||||
Reference in New Issue
Block a user