From 689c51c27d02a213af55045ef67d171c7a0ff3e0 Mon Sep 17 00:00:00 2001 From: adonis Date: Tue, 9 Jun 2026 21:04:22 +0330 Subject: [PATCH] widthdraw and deposit --- src/api/wallet.ts | 9 +- src/composables/useProductCatalog.ts | 49 +++ src/composables/useWalletAssets.ts | 46 +++ src/models/login.ts | 2 +- src/models/products.ts | 1 + src/models/wallet.ts | 4 +- src/models/walletAssets.ts | 43 +++ src/store/settingsStore.ts | 3 + src/utils/file.ts | 15 +- src/utils/inputRules.ts | 4 +- src/utils/productAssets.ts | 305 ++++++++++++++++ src/utils/productCategories.ts | 75 ++++ src/utils/productDealMethod.ts | 167 ++++++--- src/utils/productPrice.ts | 36 +- src/utils/weightUnit.ts | 33 ++ src/views/base/copper&silver/index.vue | 4 +- src/views/base/fund/components/Item.vue | 105 ++---- src/views/base/fund/index.vue | 184 ++++------ src/views/base/gold/index.vue | 66 ++-- .../base/home/components/AssetsSection.vue | 80 +++- .../base/home/components/BalanceSheet.vue | 94 +++-- src/views/base/home/index.vue | 2 + .../base/products/components/DealProduct.vue | 51 ++- .../base/products/components/ProductItem.vue | 7 +- src/views/base/products/index.vue | 22 +- yarn.lock | 343 ++++++++++-------- 26 files changed, 1228 insertions(+), 522 deletions(-) create mode 100644 src/composables/useProductCatalog.ts create mode 100644 src/composables/useWalletAssets.ts create mode 100644 src/models/walletAssets.ts create mode 100644 src/utils/productAssets.ts create mode 100644 src/utils/productCategories.ts create mode 100644 src/utils/weightUnit.ts diff --git a/src/api/wallet.ts b/src/api/wallet.ts index b857449..559cb8e 100644 --- a/src/api/wallet.ts +++ b/src/api/wallet.ts @@ -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(`/customer/wallet/me`) +export const getWalletAssets = async () => + await useAxios.get(`/customer/wallet/assets`) + export const withdraw = async (obj: Transaction): Promise => { return await useAxios.post(`/customer/wallet/withdraw`, obj) } @@ -24,5 +27,5 @@ export async function deleteCard(id: number) { export const getActivatedCards = async () => await useAxios.get(`/customer/account/active`) export const confirmCode = async (params: WithdrawConfirm): Promise => { - return await useAxios.post(`/customer/wallet/withdraw/otp` , params) + return await useAxios.post(`/customer/wallet/withdraw/otp`, params) } diff --git a/src/composables/useProductCatalog.ts b/src/composables/useProductCatalog.ts new file mode 100644 index 0000000..eb2f2ce --- /dev/null +++ b/src/composables/useProductCatalog.ts @@ -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([]) +let catalogPromise: Promise | 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, + } +} diff --git a/src/composables/useWalletAssets.ts b/src/composables/useWalletAssets.ts new file mode 100644 index 0000000..08ed987 --- /dev/null +++ b/src/composables/useWalletAssets.ts @@ -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(null) +let assetsPromise: Promise | 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, + } +} diff --git a/src/models/login.ts b/src/models/login.ts index 7e2ba7e..1974c6b 100644 --- a/src/models/login.ts +++ b/src/models/login.ts @@ -48,7 +48,7 @@ export interface User { deleted_at?: any; wallet: Wallet; pwallet:PWallet; - wallets: Wallets + wallets: Wallets[] finger_print: boolean gold: number; diff --git a/src/models/products.ts b/src/models/products.ts index 0781dc3..985d293 100644 --- a/src/models/products.ts +++ b/src/models/products.ts @@ -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 diff --git a/src/models/wallet.ts b/src/models/wallet.ts index b1e8c6a..95aa40e 100644 --- a/src/models/wallet.ts +++ b/src/models/wallet.ts @@ -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 diff --git a/src/models/walletAssets.ts b/src/models/walletAssets.ts new file mode 100644 index 0000000..3d54f55 --- /dev/null +++ b/src/models/walletAssets.ts @@ -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 +} diff --git a/src/store/settingsStore.ts b/src/store/settingsStore.ts index a266b9d..828a20c 100644 --- a/src/store/settingsStore.ts +++ b/src/store/settingsStore.ts @@ -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, } }) diff --git a/src/utils/file.ts b/src/utils/file.ts index e0370dc..28dcbfc 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -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}` } diff --git a/src/utils/inputRules.ts b/src/utils/inputRules.ts index 1e0e1b0..a6c9624 100644 --- a/src/utils/inputRules.ts +++ b/src/utils/inputRules.ts @@ -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 { diff --git a/src/utils/productAssets.ts b/src/utils/productAssets.ts new file mode 100644 index 0000000..4bb070a --- /dev/null +++ b/src/utils/productAssets.ts @@ -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 = { + گوی: 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() + 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( + 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( + 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 | 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 | 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 | null): number { + return Number(walletInfo?.count_cash_total ?? 0) +} + +export function getMetalAssetAmount( + walletInfo: Record | 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 | 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) +} diff --git a/src/utils/productCategories.ts b/src/utils/productCategories.ts new file mode 100644 index 0000000..432c972 --- /dev/null +++ b/src/utils/productCategories.ts @@ -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' +} diff --git a/src/utils/productDealMethod.ts b/src/utils/productDealMethod.ts index 4473f5d..63d3323 100644 --- a/src/utils/productDealMethod.ts +++ b/src/utils/productDealMethod.ts @@ -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() { diff --git a/src/utils/productPrice.ts b/src/utils/productPrice.ts index 4843c67..6feacc9 100644 --- a/src/utils/productPrice.ts +++ b/src/utils/productPrice.ts @@ -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' diff --git a/src/utils/weightUnit.ts b/src/utils/weightUnit.ts new file mode 100644 index 0000000..3309b20 --- /dev/null +++ b/src/utils/weightUnit.ts @@ -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}` +} diff --git a/src/views/base/copper&silver/index.vue b/src/views/base/copper&silver/index.vue index e4e6df0..96b2c0c 100644 --- a/src/views/base/copper&silver/index.vue +++ b/src/views/base/copper&silver/index.vue @@ -164,7 +164,7 @@
مظنه:
-
{{ usePriceWithoutType(((props?.ProductItem?.price_profit) + (props?.ProductItem?.price))) }}
+
{{ usePriceWithoutType(Math.round(basePriceValue ?? 0)) }}
ریال
@@ -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) { diff --git a/src/views/base/fund/components/Item.vue b/src/views/base/fund/components/Item.vue index 8d1c94c..e5c7e33 100644 --- a/src/views/base/fund/components/Item.vue +++ b/src/views/base/fund/components/Item.vue @@ -1,91 +1,54 @@ - - \ No newline at end of file diff --git a/src/views/base/fund/index.vue b/src/views/base/fund/index.vue index f22ed17..91a887f 100644 --- a/src/views/base/fund/index.vue +++ b/src/views/base/fund/index.vue @@ -9,158 +9,116 @@
-
موجودی دارایی ها
-
- محصولات: -
{{ walletStore.walletInfo?.count_product ?? 0}}عدد
+
موجودی دارایی ها
+
+ محصولات: +
{{ countBasedInventory }} عدد
+
+ + +
+ مجموع موجودی: +
{{ countBasedInventory }} عدد
+
+
+ دارایی ریالی: +
{{ usePriceWithoutType(cashWallet) }}ریال
+
+
+ معادل ریالی مجموع دارایی ها: +
{{ usePriceWithoutType(totalRialValue) }}ریال
+
-
+
-
یک گنج جدید بساز!
+
یک گنج جدید بساز!
-
- +
-
\ No newline at end of file + diff --git a/src/views/base/gold/index.vue b/src/views/base/gold/index.vue index cfb842e..52c46fc 100644 --- a/src/views/base/gold/index.vue +++ b/src/views/base/gold/index.vue @@ -6,11 +6,11 @@
- خرید {{ meltedGoldLabel }} {{ props?.ProductItem?.title }} + خرید {{ tradeProductLabel }}
- فروش {{ meltedGoldLabel }} {{ props?.ProductItem?.title }} + فروش {{ tradeProductLabel }}
-
@@ -133,7 +133,7 @@
{{ feeInGrams }}
- گرم + {{ weightUnit }}
@@ -157,13 +157,13 @@
وزن:
{{ form.goldValue }}
-
گرم
+
{{ weightUnit }}
مظنه:
-
{{ usePriceWithoutType(isBuy ? getTradeBuyPrice(lastPrice) : getTradeSellPrice(lastPrice)) }}
+
{{ usePriceWithoutType(Math.round(goldPriceValue)) }}
ریال
@@ -171,7 +171,7 @@
کارمزد:
{{ feeInGrams }}
-
گرم
+
{{ weightUnit }}
(معادل {{ equivalentPrice }} ریال)
@@ -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(false) const noCompleteVisible = ref(false) @@ -267,6 +269,12 @@ interface Prop { const props = withDefaults(defineProps(), {}) const isBuy = ref(true) +const tradeProductLabel = computed(() => { + const title = props.ProductItem?.title?.trim() + return title || meltedGoldLabel.value +}) +const amountFieldLabel = computed(() => `مقدار ${tradeProductLabel.value}`) + const buyPagination = ref({ filters: [{ field: 'type', @@ -288,8 +296,8 @@ const sellPagination = ref({ 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 => 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) { diff --git a/src/views/base/home/components/AssetsSection.vue b/src/views/base/home/components/AssetsSection.vue index b08e411..edb26e3 100644 --- a/src/views/base/home/components/AssetsSection.vue +++ b/src/views/base/home/components/AssetsSection.vue @@ -1,36 +1,82 @@ \ No newline at end of file + +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}` +} + diff --git a/src/views/base/home/components/BalanceSheet.vue b/src/views/base/home/components/BalanceSheet.vue index aafc43d..3215b80 100644 --- a/src/views/base/home/components/BalanceSheet.vue +++ b/src/views/base/home/components/BalanceSheet.vue @@ -5,50 +5,27 @@
موجودی ها
- + + + + - - - - - - - -
@@ -58,13 +35,12 @@ \ No newline at end of file + +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}` +} + diff --git a/src/views/base/home/index.vue b/src/views/base/home/index.vue index 4682baf..2bfa22c 100644 --- a/src/views/base/home/index.vue +++ b/src/views/base/home/index.vue @@ -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() diff --git a/src/views/base/products/components/DealProduct.vue b/src/views/base/products/components/DealProduct.vue index 6732e76..f8f88ad 100644 --- a/src/views/base/products/components/DealProduct.vue +++ b/src/views/base/products/components/DealProduct.vue @@ -54,7 +54,7 @@ :show-search="false" value-name="value" :allow-clear="false" - :placeholder="isBuy?'نحوه خرید را انتخاب کنید':' نحوه فروش را انتخاب کنید'" + :placeholder="getProductDealMethodPlaceholder(isBuy)" size="large" :has-tooltip="false" /> @@ -103,7 +103,9 @@
{{ cashWalletBalanceText }}
-
{{ `موجودی محصول: ${getInventoryById(props?.ProductItem?.id)} ${getProductQuantityUnit(props?.ProductItem)}` }} +
+
{{ `موجودی محصول: ${getInventoryById(props?.ProductItem?.id)} ${getProductQuantityUnit(props?.ProductItem)}` }}
+
{{ sellMetalWalletBalanceText }}
@@ -225,10 +227,15 @@
-
{{ isBuy ? 'قیمت قابل پرداخت:' : 'مبلغ دریافتی:' }}
+
{{ isBuy ? 'قیمت قابل پرداخت:' : (isMetalReceiveDeal ? 'دریافت:' : 'مبلغ دریافتی:') }}
-
{{ usePriceWithoutType(form.goldCash ?? 0) }}
-
ریال
+ +
@@ -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(), {}) +const emit = defineEmits<{ ordered: [] }>() const isBuy = ref(true) const buyTotalPrice = computed(() => { const item = props?.ProductItem @@ -520,7 +546,7 @@ const form = ref({ }) 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 diff --git a/src/views/base/products/components/ProductItem.vue b/src/views/base/products/components/ProductItem.vue index b9fa762..db94b2f 100644 --- a/src/views/base/products/components/ProductItem.vue +++ b/src/views/base/products/components/ProductItem.vue @@ -11,7 +11,7 @@ -
{{usePrice(goldPriceValue)}}
+
{{usePrice(goldPriceValue)}}
{{usePrice(price)}}
@@ -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 = { 'مس': mesImg, 'نقره': noghrehImg, 'سکه پارسیان': parsianImg, + 'کاتد مس': defaultImg, + 'طلا': defaultImg, } const displayImage = computed(() => { @@ -111,7 +114,7 @@ const goldPriceValue = computed(() => getProductBuyPrice(props.ProductItem))
{{ props.ProductItem.title }}

-
{{usePrice(goldPriceValue)}}
+
{{usePrice(goldPriceValue)}}
{{usePrice(price)}}
diff --git a/src/views/base/products/index.vue b/src/views/base/products/index.vue index 235c6e7..63ed6fa 100644 --- a/src/views/base/products/index.vue +++ b/src/views/base/products/index.vue @@ -30,16 +30,16 @@ -
- + - - +
@@ -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() const closeTime = ref('') const openTime = ref('') @@ -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) => diff --git a/yarn.lock b/yarn.lock index 86a52c9..dd3d7ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -71,7 +71,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz" integrity sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.11.1", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.22.10", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": +"@babel/core@^7.11.1", "@babel/core@^7.22.10": version "7.22.10" resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz" integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw== @@ -291,7 +291,7 @@ "@babel/template" "^7.27.1" "@babel/types" "^7.27.1" -"@babel/parser@^7.15.8", "@babel/parser@^7.20.15", "@babel/parser@^7.21.3", "@babel/parser@^7.22.10", "@babel/parser@^7.25.3", "@babel/parser@^7.26.5", "@babel/parser@^7.27.2": +"@babel/parser@^7.20.15", "@babel/parser@^7.21.3", "@babel/parser@^7.22.10", "@babel/parser@^7.25.3", "@babel/parser@^7.26.5", "@babel/parser@^7.27.2": version "7.27.2" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz" integrity sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw== @@ -1006,11 +1006,116 @@ resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz" integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA== +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + "@esbuild/linux-x64@0.18.20": version "0.18.20" resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz" integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -1139,7 +1244,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1243,16 +1348,16 @@ resolved "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.0.tgz" integrity sha512-yhxwIlFVSVcMym3O31HoMnRXpoenmpIxcj4Yoes2DUpe+xCJnA7ECQP1Vw889V0jTt/2nzvpLQ/UuMYCd3JPIg== -"@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== - "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + "@types/json-schema@^7.0.9": version "7.0.12" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" @@ -1263,7 +1368,7 @@ resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz" integrity sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA== -"@types/node@*", "@types/node@^18.17.0", "@types/node@>= 14": +"@types/node@*", "@types/node@^18.17.0": version "18.17.5" resolved "https://registry.npmjs.org/@types/node/-/node-18.17.5.tgz" integrity sha512-xNbS75FxH6P4UXTPUJp/zNPq6/xsfdJKussCWNOnz4aULWIRwMgP1LgaB5RiBnMX1DPCYenuqGZfnIAx5mbFLA== @@ -1306,7 +1411,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.59.1": +"@typescript-eslint/parser@^5.59.1": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz" integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== @@ -1592,7 +1697,7 @@ resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.1.tgz" integrity sha512-tUBEtWcF7wFtII7ayNiLNDTCE1X1afySEo+XNVMNkFXaThENyCowIEX095QqbJZGTgoOcSVDJGlnde2NG4jtbQ== -"@volar/language-core@~2.4.11", "@volar/language-core@2.4.11": +"@volar/language-core@2.4.11", "@volar/language-core@~2.4.11": version "2.4.11" resolved "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.11.tgz" integrity sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg== @@ -1654,14 +1759,6 @@ estree-walker "^2.0.2" source-map-js "^1.2.0" -"@vue/compiler-dom@^3.5.0": - version "3.5.13" - resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz" - integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA== - dependencies: - "@vue/compiler-core" "3.5.13" - "@vue/shared" "3.5.13" - "@vue/compiler-dom@3.3.4": version "3.3.4" resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz" @@ -1670,6 +1767,14 @@ "@vue/compiler-core" "3.3.4" "@vue/shared" "3.3.4" +"@vue/compiler-dom@^3.5.0": + version "3.5.13" + resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz" + integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA== + dependencies: + "@vue/compiler-core" "3.5.13" + "@vue/shared" "3.5.13" + "@vue/compiler-sfc@3.3.4": version "3.3.4" resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz" @@ -1781,12 +1886,12 @@ "@vue/compiler-ssr" "3.3.4" "@vue/shared" "3.3.4" -"@vue/shared@^3.0.0", "@vue/shared@3.3.4": +"@vue/shared@3.3.4", "@vue/shared@^3.0.0": version "3.3.4" resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz" integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ== -"@vue/shared@^3.5.0", "@vue/shared@3.5.13": +"@vue/shared@3.5.13", "@vue/shared@^3.5.0": version "3.5.13" resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz" integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ== @@ -1828,7 +1933,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.8.2, acorn@^8.9.0: version "8.10.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== @@ -1843,7 +1948,7 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.6.0, ajv@>=8: +ajv@^8.6.0: version "8.12.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -1908,7 +2013,7 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -apexcharts@^3.44.0, "apexcharts@> 3.0.0": +apexcharts@^3.44.0: version "3.44.0" resolved "https://registry.npmjs.org/apexcharts/-/apexcharts-3.44.0.tgz" integrity sha512-u7Xzrbcxc2yWznN78Jh5NMCYVAsWDfBjRl5ea++rVzFAqjU2hLz4RgKIFwYOBDRQtW1e/Qz8azJTqIJ1+Vu9Qg== @@ -2063,7 +2168,7 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.21.9, browserslist@^4.22.1, "browserslist@>= 4.21.0": +browserslist@^4.21.9, browserslist@^4.22.1: version "4.22.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz" integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== @@ -2127,7 +2232,7 @@ chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.0.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2135,15 +2240,7 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chokidar@^3.5.3, "chokidar@>=3.0.0 <4.0.0": +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -2172,16 +2269,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + colorette@^2.0.20: version "2.0.20" resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" @@ -2569,7 +2666,7 @@ eslint-plugin-prettier@^5.0.0: prettier-linter-helpers "^1.0.0" synckit "^0.8.5" -eslint-plugin-vue@^9.0.0, eslint-plugin-vue@^9.15.1: +eslint-plugin-vue@^9.15.1: version "9.17.0" resolved "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz" integrity sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ== @@ -2590,15 +2687,7 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.2.2" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-scope@^7.2.2: +eslint-scope@^7.1.1, eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== @@ -2611,7 +2700,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^6.2.0 || ^7.0.0 || ^8.0.0", eslint@^8.45.0, "eslint@>= 8.0.0", eslint@>=6.0.0, eslint@>=7.0.0, eslint@>=8.0.0: +eslint@^8.45.0: version "8.47.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz" integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q== @@ -2682,12 +2771,7 @@ estraverse@^4.1.1: resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estraverse@^5.2.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== @@ -2712,22 +2796,7 @@ eventemitter3@^5.0.1: resolved "https://mirror-npm.runflare.com/eventemitter3/-/eventemitter3-5.0.4.tgz" integrity sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw== -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^5.1.1: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -2873,6 +2942,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" @@ -2926,7 +3000,7 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -2940,13 +3014,6 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - glob@^7.1.3, glob@^7.1.6: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" @@ -3458,7 +3525,7 @@ kolorist@^1.8.0: resolved "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz" integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== -less@*, less@^4.2.0: +less@^4.2.0: version "4.2.0" resolved "https://registry.npmjs.org/less/-/less-4.2.0.tgz" integrity sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA== @@ -3566,14 +3633,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.25.0: - version "0.25.9" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== - dependencies: - sourcemap-codec "^1.4.8" - -magic-string@^0.25.7: +magic-string@^0.25.0, magic-string@^0.25.7: version "0.25.9" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== @@ -3715,7 +3775,7 @@ mrmime@^1.0.0: resolved "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz" integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== -ms@^2.1.1, ms@2.1.2: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -3840,7 +3900,7 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -odometer@^0.4.8, odometer@latest: +odometer@^0.4.8: version "0.4.8" resolved "https://registry.npmjs.org/odometer/-/odometer-0.4.8.tgz" integrity sha512-bfKuAhWE/qMCiX9bwX90c5bTpt7MDVeq1e6YsOHQrYokNhv9jhS5JbR9kg6i+FeWmDgalf3VUtwNx1aVaZ8cgg== @@ -4064,7 +4124,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^3.0.0, "prettier@>= 3.0.0", prettier@>=3.0.0: +prettier@^3.0.0: version "3.0.2" resolved "https://registry.npmjs.org/prettier/-/prettier-3.0.2.tgz" integrity sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ== @@ -4234,14 +4294,14 @@ rollup-plugin-terser@^7.0.0: serialize-javascript "^4.0.0" terser "^5.0.0" -"rollup@^1.20.0 || ^2.0.0", rollup@^1.20.0||^2.0.0, rollup@^2.0.0, rollup@^2.43.1: +rollup@^2.43.1: version "2.79.2" resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz" integrity sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ== optionalDependencies: fsevents "~2.3.2" -rollup@^1.20.0||^2.0.0||^3.0.0, rollup@^3.27.1: +rollup@^3.27.1: version "3.29.5" resolved "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz" integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w== @@ -4291,7 +4351,7 @@ safe-regex-test@^1.0.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass@*, sass@^1.69.4: +sass@^1.69.4: version "1.69.5" resolved "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz" integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ== @@ -4312,12 +4372,7 @@ scroll-into-view-if-needed@^2.2.25: dependencies: compute-scroll-into-view "^1.0.20" -semver@^5.5.0: - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.2" resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== @@ -4327,32 +4382,13 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.6: +semver@^7.3.6, semver@^7.3.7, semver@^7.5.4: version "7.5.4" resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -semver@^7.3.7: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.4: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -"semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz" @@ -4431,7 +4467,7 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0, source-map-js@^1.2.1, "source-map-js@>=0.6.2 <2.0.0": +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -4586,14 +4622,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -4631,7 +4660,7 @@ svg.filter.js@^2.0.2: dependencies: svg.js "^2.2.5" -svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5, svg.js@>=2.3.x: +svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5: version "2.7.1" resolved "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz" integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA== @@ -4693,7 +4722,7 @@ tempy@^0.6.0: type-fest "^0.16.0" unique-string "^2.0.0" -terser@^5.0.0, terser@^5.4.0: +terser@^5.0.0: version "5.24.0" resolved "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz" integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== @@ -4732,6 +4761,11 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tslib@2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" @@ -4742,11 +4776,6 @@ tslib@^2.3.0, tslib@^2.5.0, tslib@^2.6.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz" integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== -tslib@2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" @@ -4810,7 +4839,7 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typescript@*, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=4.4.4, typescript@>=5.0.0, typescript@~5.1.6: +typescript@~5.1.6: version "5.1.6" resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== @@ -4985,7 +5014,7 @@ vite-plugin-pwa@^0.16.7: workbox-build "^7.0.0" workbox-window "^7.0.0" -"vite@^2.9.0 || ^3.0.0-0 || ^4.0.0", "vite@^3.1.0 || ^4.0.0 || ^5.0.0-0", vite@^4.0.0, vite@^4.4.6: +vite@^4.4.6: version "4.5.14" resolved "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz" integrity sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g== @@ -5006,11 +5035,6 @@ vue-content-loader@^2.0.1: resolved "https://registry.npmjs.org/vue-content-loader/-/vue-content-loader-2.0.1.tgz" integrity sha512-pkof4+q2xmzNEdhqelxtJejeP/vQUJtLle4/v2ueG+HURqM9Q/GIGC8GJ2bVVWeLfTDET51jqimwQdmxJTlu0g== -vue-demi@^0.12.5: - version "0.12.5" - resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz" - integrity sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q== - vue-demi@>=0.14.5: version "0.14.5" resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.5.tgz" @@ -5021,6 +5045,11 @@ vue-demi@>=0.14.6: resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz" integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w== +vue-demi@^0.12.5: + version "0.12.5" + resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz" + integrity sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q== + vue-eslint-parser@^9.1.1, vue-eslint-parser@^9.3.1: version "9.3.1" resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz" @@ -5068,17 +5097,6 @@ vue-types@^3.0.0: dependencies: is-plain-object "3.0.1" -"vue@^2.0.0 || >=3.0.0", "vue@^2.6.14 || ^3.3.0", vue@^3, vue@^3.0.*, vue@^3.0.0, "vue@^3.0.0-0 || ^2.6.0", vue@^3.2.0, vue@^3.2.25, vue@^3.3.4, "vue@> 3.0.0", "vue@>= 2.0.0", vue@>=3.0.3, vue@>=3.2.0, "vue@2 || 3", vue@3.3.4, vue@latest: - version "3.3.4" - resolved "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz" - integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw== - dependencies: - "@vue/compiler-dom" "3.3.4" - "@vue/compiler-sfc" "3.3.4" - "@vue/runtime-dom" "3.3.4" - "@vue/server-renderer" "3.3.4" - "@vue/shared" "3.3.4" - vue3-apexcharts@^1.4.4: version "1.4.4" resolved "https://registry.npmjs.org/vue3-apexcharts/-/vue3-apexcharts-1.4.4.tgz" @@ -5104,6 +5122,17 @@ vue3-otp-input@^0.4.1: resolved "https://registry.npmjs.org/vue3-otp-input/-/vue3-otp-input-0.4.1.tgz" integrity sha512-wVl9i3DcWlO0C7fBI9V+RIP3crm/1tY72fuhvb3YM2JfbLoYofB96aPl5AgFhA0Cse5bQEMYtIvOeiqW3rfbAw== +vue@^3.2.25, vue@^3.3.4: + version "3.3.4" + resolved "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz" + integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw== + dependencies: + "@vue/compiler-dom" "3.3.4" + "@vue/compiler-sfc" "3.3.4" + "@vue/runtime-dom" "3.3.4" + "@vue/server-renderer" "3.3.4" + "@vue/shared" "3.3.4" + warning@^4.0.0: version "4.0.3" resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz" @@ -5321,7 +5350,7 @@ workbox-sw@7.0.0: resolved "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.0.0.tgz" integrity sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA== -workbox-window@^7.0.0, workbox-window@7.0.0: +workbox-window@7.0.0, workbox-window@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/workbox-window/-/workbox-window-7.0.0.tgz" integrity sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA==