Add synchronous price calculation method: Introduce calcRegionalSellPriceSync for improved performance in price calculations when worthPercent is known. Refactor getAllProductPricesInRegion to utilize this new method, enhancing efficiency by reducing database calls. Update BranchView to manage product prices cache with regionId for better data handling.
This commit is contained in:
@@ -98,6 +98,15 @@ function calcSellPrice(product, knowledgeFactor = 0) {
|
|||||||
return min + (max - min) * (knowledgeFactor / 100);
|
return min + (max - min) * (knowledgeFactor / 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Synchrone Preisberechnung, wenn worthPercent bereits bekannt ist (kein DB-Zugriff). */
|
||||||
|
function calcRegionalSellPriceSync(product, knowledgeFactor, worthPercent) {
|
||||||
|
if (product.sellCost === null || product.sellCost === undefined) return null;
|
||||||
|
const basePrice = product.sellCost * (worthPercent / 100);
|
||||||
|
const min = basePrice * 0.6;
|
||||||
|
const max = basePrice;
|
||||||
|
return min + (max - min) * (knowledgeFactor / 100);
|
||||||
|
}
|
||||||
|
|
||||||
async function calcRegionalSellPrice(product, knowledgeFactor, regionId, worthPercent = null) {
|
async function calcRegionalSellPrice(product, knowledgeFactor, regionId, worthPercent = null) {
|
||||||
// Wenn worthPercent nicht übergeben wurde, hole es aus der Datenbank
|
// Wenn worthPercent nicht übergeben wurde, hole es aus der Datenbank
|
||||||
if (worthPercent === null) {
|
if (worthPercent === null) {
|
||||||
@@ -4394,66 +4403,34 @@ class FalukantService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getAllProductPricesInRegion(hashedUserId, regionId) {
|
async getAllProductPricesInRegion(hashedUserId, regionId) {
|
||||||
const startTime = Date.now();
|
|
||||||
console.log(`[getAllProductPricesInRegion] Start für userId: ${hashedUserId}, regionId: ${regionId}`);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||||
const userTime = Date.now();
|
|
||||||
console.log(`[getAllProductPricesInRegion] User geladen in ${userTime - startTime}ms`);
|
|
||||||
|
|
||||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||||
if (!character) {
|
if (!character) {
|
||||||
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
|
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
|
||||||
}
|
}
|
||||||
const characterTime = Date.now();
|
const [products, knowledges, townWorths] = await Promise.all([
|
||||||
console.log(`[getAllProductPricesInRegion] Character geladen in ${characterTime - userTime}ms`);
|
ProductType.findAll({ attributes: ['id', 'sellCost'] }),
|
||||||
|
Knowledge.findAll({
|
||||||
// Lade alle Produkte auf einmal
|
|
||||||
const products = await ProductType.findAll({
|
|
||||||
attributes: ['id', 'sellCost']
|
|
||||||
});
|
|
||||||
const productsTime = Date.now();
|
|
||||||
console.log(`[getAllProductPricesInRegion] ${products.length} Produkte geladen in ${productsTime - characterTime}ms`);
|
|
||||||
|
|
||||||
// Lade alle Knowledge-Werte für diesen Character auf einmal
|
|
||||||
const knowledges = await Knowledge.findAll({
|
|
||||||
where: { characterId: character.id },
|
where: { characterId: character.id },
|
||||||
attributes: ['productId', 'knowledge']
|
attributes: ['productId', 'knowledge']
|
||||||
});
|
}),
|
||||||
const knowledgeMap = new Map(knowledges.map(k => [k.productId, k.knowledge || 0]));
|
TownProductWorth.findAll({
|
||||||
const knowledgeTime = Date.now();
|
|
||||||
console.log(`[getAllProductPricesInRegion] ${knowledges.length} Knowledge-Werte geladen in ${knowledgeTime - productsTime}ms`);
|
|
||||||
|
|
||||||
// Lade alle TownProductWorth-Werte für diese Region auf einmal
|
|
||||||
const townWorths = await TownProductWorth.findAll({
|
|
||||||
where: { regionId: regionId },
|
where: { regionId: regionId },
|
||||||
attributes: ['productId', 'worthPercent']
|
attributes: ['productId', 'worthPercent']
|
||||||
});
|
})
|
||||||
const worthMap = new Map(townWorths.map(tw => [tw.productId, tw.worthPercent || 50]));
|
]);
|
||||||
const worthTime = Date.now();
|
|
||||||
console.log(`[getAllProductPricesInRegion] ${townWorths.length} Worth-Werte geladen in ${worthTime - knowledgeTime}ms`);
|
const knowledgeMap = new Map(knowledges.map(k => [k.productId, k.knowledge || 0]));
|
||||||
|
const worthMap = new Map(townWorths.map(tw => [tw.productId, tw.worthPercent || 50]));
|
||||||
|
|
||||||
// Berechne Preise für alle Produkte
|
|
||||||
const prices = {};
|
const prices = {};
|
||||||
for (const product of products) {
|
for (const product of products) {
|
||||||
if (product.sellCost === null || product.sellCost === undefined) {
|
const worthPercent = worthMap.get(product.id) ?? 50;
|
||||||
continue; // Überspringe Produkte ohne sellCost
|
|
||||||
}
|
|
||||||
|
|
||||||
const knowledgeFactor = knowledgeMap.get(product.id) || 0;
|
const knowledgeFactor = knowledgeMap.get(product.id) || 0;
|
||||||
const worthPercent = worthMap.get(product.id) || 50;
|
const price = calcRegionalSellPriceSync(product, knowledgeFactor, worthPercent);
|
||||||
|
if (price !== null) prices[product.id] = price;
|
||||||
// Verwende calcRegionalSellPrice mit bereits geladenem worthPercent
|
|
||||||
const price = await calcRegionalSellPrice(product, knowledgeFactor, regionId, worthPercent);
|
|
||||||
prices[product.id] = price;
|
|
||||||
}
|
}
|
||||||
const calcTime = Date.now();
|
|
||||||
console.log(`[getAllProductPricesInRegion] Preise berechnet in ${calcTime - worthTime}ms`);
|
|
||||||
|
|
||||||
const totalTime = Date.now() - startTime;
|
|
||||||
console.log(`[getAllProductPricesInRegion] Gesamtzeit: ${totalTime}ms für ${Object.keys(prices).length} Produkte`);
|
|
||||||
|
|
||||||
return { prices };
|
return { prices };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[getAllProductPricesInRegion] Error for regionId=${regionId}:`, error);
|
console.error(`[getAllProductPricesInRegion] Error for regionId=${regionId}:`, error);
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleDropdown() {
|
toggleDropdown() {
|
||||||
console.log("toggleDropdown", 'clicked');
|
|
||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
this.isOpen = !this.isOpen;
|
this.isOpen = !this.isOpen;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -360,6 +360,7 @@ export default {
|
|||||||
vehicles: [],
|
vehicles: [],
|
||||||
activeTab: 'production',
|
activeTab: 'production',
|
||||||
productPricesCache: {}, // Cache für regionale Preise: { productId: price }
|
productPricesCache: {}, // Cache für regionale Preise: { productId: price }
|
||||||
|
productPricesCacheRegionId: null, // regionId, für die der Cache gültig ist
|
||||||
tabs: [
|
tabs: [
|
||||||
{ value: 'production', label: 'falukant.branch.tabs.production' },
|
{ value: 'production', label: 'falukant.branch.tabs.production' },
|
||||||
{ value: 'inventory', label: 'falukant.branch.tabs.inventory' },
|
{ value: 'inventory', label: 'falukant.branch.tabs.inventory' },
|
||||||
@@ -569,20 +570,20 @@ export default {
|
|||||||
async loadProductPricesForCurrentBranch() {
|
async loadProductPricesForCurrentBranch() {
|
||||||
if (!this.selectedBranch || !this.selectedBranch.regionId) {
|
if (!this.selectedBranch || !this.selectedBranch.regionId) {
|
||||||
this.productPricesCache = {};
|
this.productPricesCache = {};
|
||||||
|
this.productPricesCacheRegionId = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.productPricesCacheRegionId === this.selectedBranch.regionId && Object.keys(this.productPricesCache).length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lade alle Preise für die Region auf einmal (Bulk-Request)
|
|
||||||
try {
|
try {
|
||||||
const startTime = performance.now();
|
|
||||||
const { data } = await apiClient.get('/api/falukant/products/prices-in-region', {
|
const { data } = await apiClient.get('/api/falukant/products/prices-in-region', {
|
||||||
params: {
|
params: {
|
||||||
regionId: this.selectedBranch.regionId
|
regionId: this.selectedBranch.regionId
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const loadTime = performance.now() - startTime;
|
|
||||||
console.log(`[BranchView] Product prices loaded in ${loadTime.toFixed(2)}ms`);
|
|
||||||
this.productPricesCache = data.prices || {};
|
this.productPricesCache = data.prices || {};
|
||||||
|
this.productPricesCacheRegionId = this.selectedBranch.regionId;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error loading product prices for region ${this.selectedBranch.regionId}:`, error);
|
console.error(`Error loading product prices for region ${this.selectedBranch.regionId}:`, error);
|
||||||
// Fallback: Lade Preise einzeln (alte Methode)
|
// Fallback: Lade Preise einzeln (alte Methode)
|
||||||
@@ -607,6 +608,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.productPricesCache = prices;
|
this.productPricesCache = prices;
|
||||||
|
this.productPricesCacheRegionId = this.selectedBranch?.regionId ?? null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user