change prices in chart

This commit is contained in:
2026-07-21 15:39:03 +02:00
parent f45e9dad15
commit d5ff262493
+24 -103
View File
@@ -1,15 +1,22 @@
import { computed, ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import { getAllPrices } from '@/api/home' import { getAllPrices } from '@/api/home'
import type { Product } from '@/models/products'
import { getProductsCatalog, getProductsCatalogRef } from '@/composables/useProductsCatalog' import { getProductsCatalog, getProductsCatalogRef } from '@/composables/useProductsCatalog'
import { getProductBuyPrice, resolvePriceOffsetRatio } from '@/utils/productPrice' import { getTradeBuyPrice, getTradeSellPrice } from '@/utils/price'
import { isKatodMesGroup, isMaftolMesGroup, isShamshMesGroup } from '@/utils/productDealMethod'
import { getTradeBuyPrice, getTradeSellPrice, lastPrice } from '@/utils/price'
export type ChartMetalType = 'katod' | 'maftol' | 'shamsh' export type ChartMetalType = 'katod' | 'maftol' | 'shamsh'
type ChartPoint = [number, number] type ChartPoint = [number, number]
/**
* مارک‌آپ ثابت روی قیمت بورس کالا برای نمودار:
* کاتد +۳٪ ، مفتول +۶٪ ، شمش +۱۲٪
*/
export const CHART_METAL_MARKUP_RATIO: Record<ChartMetalType, number> = {
katod: 0.03,
maftol: 0.06,
shamsh: 0.12,
}
/** Module-level chart state — one dataset shared by mobile and desktop PriceChart instances. */ /** Module-level chart state — one dataset shared by mobile and desktop PriceChart instances. */
const priceChartSeries = ref<{ name: string; data: ChartPoint[] }[]>([ const priceChartSeries = ref<{ name: string; data: ChartPoint[] }[]>([
{ name: 'قیمت', data: [] }, { name: 'قیمت', data: [] },
@@ -20,65 +27,18 @@ const chartLoading = ref(false)
const selectedChartMetal = ref<ChartMetalType>('katod') const selectedChartMetal = ref<ChartMetalType>('katod')
const catalogProducts = getProductsCatalogRef() const catalogProducts = getProductsCatalogRef()
function resolveChartProducts(products: Product[]) { const maftolChartRatio = computed(() => CHART_METAL_MARKUP_RATIO.maftol)
return { const shamshChartRatio = computed(() => CHART_METAL_MARKUP_RATIO.shamsh)
katod: findKatodProduct(products),
maftol: findMaftolProduct(products),
shamsh: findShamshProduct(products),
}
}
/** نسبت مفتول به کاتد — reactive به قیمت لحظه‌ای و کاتالوگ محصولات */ const selectedMetalChartRatio = computed(
const maftolChartRatio = computed(() => { () => CHART_METAL_MARKUP_RATIO[selectedChartMetal.value],
void lastPrice.value?.price_last )
const { katod, maftol } = resolveChartProducts(catalogProducts.value)
return deriveMetalChartRatio(maftol, katod)
})
/** نسبت شمش مس به کاتد */
const shamshChartRatio = computed(() => {
void lastPrice.value?.price_last
const { katod, shamsh } = resolveChartProducts(catalogProducts.value)
return deriveMetalChartRatio(shamsh, katod)
})
const selectedMetalChartRatio = computed(() => {
if (selectedChartMetal.value === 'maftol') {
return maftolChartRatio.value
}
if (selectedChartMetal.value === 'shamsh') {
return shamshChartRatio.value
}
return 0
})
let chartFetchPromise: Promise<void> | null = null let chartFetchPromise: Promise<void> | null = null
let chartInitialized = false let chartInitialized = false
let metalOffsetPromise: Promise<void> | null = null let metalOffsetPromise: Promise<void> | null = null
let metalOffsetLoaded = false let metalOffsetLoaded = false
function findKatodProduct(products: Product[]) {
return (
products.find((product) => isKatodMesGroup(product.group_type))
?? products.find((product) => (product.title ?? '').includes('کاتد'))
)
}
function findMaftolProduct(products: Product[]) {
return (
products.find((product) => isMaftolMesGroup(product.group_type))
?? products.find((product) => (product.title ?? '').includes('مفتول'))
)
}
function findShamshProduct(products: Product[]) {
return products.find((product) =>
isShamshMesGroup(product.group_type, product.title)
)
}
function applyChartRatio(basePrice: number, ratio: number) { function applyChartRatio(basePrice: number, ratio: number) {
if (!ratio) { if (!ratio) {
return basePrice return basePrice
@@ -87,7 +47,7 @@ function applyChartRatio(basePrice: number, ratio: number) {
return Math.round(basePrice + basePrice * ratio) return Math.round(basePrice + basePrice * ratio)
} }
/** بالاترین/پایین‌ترین امروز — برای boursecu با نسبت مفتول/شمش نسبت به کاتد */ /** بالاترین/پایین‌ترین امروز — همان مارک‌آپ ثابت فلز روی قیمت بورس کالا */
export function resolveMetalDayRangePrices(options: { export function resolveMetalDayRangePrices(options: {
price: { up?: { buy?: number; sell?: number }; buy?: number; sell?: number; price_last?: number } | null | undefined price: { up?: { buy?: number; sell?: number }; buy?: number; sell?: number; price_last?: number } | null | undefined
metal: ChartMetalType metal: ChartMetalType
@@ -95,44 +55,14 @@ export function resolveMetalDayRangePrices(options: {
}) { }) {
const baseHigh = options.price?.up?.buy ?? getTradeBuyPrice(options.price as Parameters<typeof getTradeBuyPrice>[0]) const baseHigh = options.price?.up?.buy ?? getTradeBuyPrice(options.price as Parameters<typeof getTradeBuyPrice>[0])
const baseLow = options.price?.up?.sell ?? getTradeSellPrice(options.price as Parameters<typeof getTradeSellPrice>[0]) const baseLow = options.price?.up?.sell ?? getTradeSellPrice(options.price as Parameters<typeof getTradeSellPrice>[0])
const ratio = options.metalRatio || CHART_METAL_MARKUP_RATIO[options.metal]
if (options.metal === 'katod') {
return { high: baseHigh, low: baseLow }
}
return { return {
high: applyChartRatio(baseHigh, options.metalRatio), high: applyChartRatio(baseHigh, ratio),
low: applyChartRatio(baseLow, options.metalRatio), low: applyChartRatio(baseLow, ratio),
} }
} }
function deriveMetalChartRatio(metalProduct?: Product, katodProduct?: Product) {
const metalOffset = resolvePriceOffsetRatio(metalProduct?.price_offset_percent)
if (metalOffset) {
return metalOffset
}
if (!metalProduct) {
return 0
}
const liveBuy = getTradeBuyPrice(lastPrice.value)
const katodLive = katodProduct ? getProductBuyPrice(katodProduct) : liveBuy
const metalLive = getProductBuyPrice(metalProduct)
const katodStatic = Number(katodProduct?.price ?? 0) + Number(katodProduct?.price_profit ?? 0)
const metalStatic = Number(metalProduct.price ?? 0) + Number(metalProduct.price_profit ?? 0)
const referencePrice = katodLive || liveBuy || katodStatic
const derivedMetalPrice = metalLive || metalStatic
if (!referencePrice || !derivedMetalPrice || referencePrice === derivedMetalPrice) {
return 0
}
return (derivedMetalPrice - referencePrice) / referencePrice
}
function normalizeChartTimestamp(timestamp: number) { function normalizeChartTimestamp(timestamp: number) {
return timestamp < 1_000_000_000_000 ? timestamp * 1000 : timestamp return timestamp < 1_000_000_000_000 ? timestamp * 1000 : timestamp
} }
@@ -165,15 +95,9 @@ function buildChartPoints(items: Array<{ timestamp: number; value: number }>): C
function syncChartSeries() { function syncChartSeries() {
const ratio = selectedMetalChartRatio.value const ratio = selectedMetalChartRatio.value
const data = priceChartSeries.value[0].data = rawChartPoints.value.map(
selectedChartMetal.value !== 'katod' ([timestamp, value]) => [timestamp, applyChartRatio(value, ratio)] as ChartPoint,
? rawChartPoints.value.map( )
([timestamp, value]) =>
[timestamp, applyChartRatio(value, ratio)] as ChartPoint
)
: rawChartPoints.value
priceChartSeries.value[0].data = data
} }
watch([selectedChartMetal, maftolChartRatio, shamshChartRatio], () => { watch([selectedChartMetal, maftolChartRatio, shamshChartRatio], () => {
@@ -242,10 +166,7 @@ function updateChartData(timeline: string) {
function setChartMetal(metal: ChartMetalType) { function setChartMetal(metal: ChartMetalType) {
selectedChartMetal.value = metal selectedChartMetal.value = metal
syncChartSeries()
if (metal !== 'katod' && !catalogProducts.value.length) {
void loadMetalChartOffsets(true)
}
} }
export function usePriceChart() { export function usePriceChart() {