Refactor FalukantService and SaleSection components: Optimize product and knowledge retrieval by using Promise.all for concurrent database queries, improving performance. Additionally, reorganize the speedLabel method for better readability and maintainability, ensuring accurate localization handling for transport speed values.
This commit is contained in:
@@ -4445,79 +4445,61 @@ class FalukantService extends BaseService {
|
|||||||
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
|
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Produkt abrufen
|
const [product, knowledge, cities, townWorths] = await Promise.all([
|
||||||
const product = await ProductType.findOne({ where: { id: productId } });
|
ProductType.findOne({ where: { id: productId } }),
|
||||||
|
Knowledge.findOne({
|
||||||
|
where: { characterId: character.id, productId: productId }
|
||||||
|
}),
|
||||||
|
RegionData.findAll({
|
||||||
|
attributes: ['id', 'name'],
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: RegionType,
|
||||||
|
as: 'regionType',
|
||||||
|
where: { labelTr: 'city' },
|
||||||
|
attributes: ['labelTr']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: Branch,
|
||||||
|
as: 'branches',
|
||||||
|
where: { falukantUserId: user.id },
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: BranchType,
|
||||||
|
as: 'branchType',
|
||||||
|
attributes: ['labelTr']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
attributes: ['branchTypeId'],
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
TownProductWorth.findAll({
|
||||||
|
where: { productId: productId },
|
||||||
|
attributes: ['regionId', 'worthPercent']
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
throw new Error(`Product not found with id ${productId}`);
|
throw new Error(`Product not found with id ${productId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Knowledge für dieses Produkt abrufen
|
|
||||||
const knowledge = await Knowledge.findOne({
|
|
||||||
where: { characterId: character.id, productId: productId }
|
|
||||||
});
|
|
||||||
const knowledgeFactor = knowledge?.knowledge || 0;
|
const knowledgeFactor = knowledge?.knowledge || 0;
|
||||||
|
|
||||||
// Alle Städte abrufen
|
|
||||||
const cities = await RegionData.findAll({
|
|
||||||
attributes: ['id', 'name'],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: RegionType,
|
|
||||||
as: 'regionType',
|
|
||||||
where: { labelTr: 'city' },
|
|
||||||
attributes: ['labelTr']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
model: Branch,
|
|
||||||
as: 'branches',
|
|
||||||
where: { falukantUserId: user.id },
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
model: BranchType,
|
|
||||||
as: 'branchType',
|
|
||||||
attributes: ['labelTr']
|
|
||||||
}
|
|
||||||
],
|
|
||||||
attributes: ['branchTypeId'],
|
|
||||||
required: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
// TownProductWorth für alle Städte und dieses Produkt einmalig abrufen
|
|
||||||
// (vermeidet N+1 Query Problem)
|
|
||||||
const townWorths = await TownProductWorth.findAll({
|
|
||||||
where: { productId: productId },
|
|
||||||
attributes: ['regionId', 'worthPercent']
|
|
||||||
});
|
|
||||||
const worthMap = new Map(townWorths.map(tw => [tw.regionId, tw.worthPercent]));
|
const worthMap = new Map(townWorths.map(tw => [tw.regionId, tw.worthPercent]));
|
||||||
|
|
||||||
// Berechne den regionalen Preis für die aktuelle Region (falls angegeben)
|
let currentRegionalPrice = currentPrice;
|
||||||
// WICHTIG: Ignoriere den übergebenen currentPrice, da er möglicherweise nicht
|
|
||||||
// den regionalen Faktor berücksichtigt. Berechne stattdessen immer den korrekten
|
|
||||||
// regionalen Preis basierend auf currentRegionId.
|
|
||||||
let currentRegionalPrice = currentPrice; // Fallback auf übergebenen Preis
|
|
||||||
if (currentRegionId) {
|
if (currentRegionId) {
|
||||||
const currentWorthPercent = worthMap.get(currentRegionId) || 50;
|
const currentWorthPercent = worthMap.get(currentRegionId) || 50;
|
||||||
// Verwende calcRegionalSellPrice mit bereits geladenem worthPercent (keine DB-Query)
|
currentRegionalPrice = calcRegionalSellPriceSync(product, knowledgeFactor, currentWorthPercent) ?? currentPrice;
|
||||||
currentRegionalPrice = await calcRegionalSellPrice(product, knowledgeFactor, currentRegionId, currentWorthPercent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Für jede Stadt den Preis berechnen und Branch-Typ bestimmen
|
|
||||||
const results = [];
|
const results = [];
|
||||||
|
const PRICE_TOLERANCE = 0.01;
|
||||||
for (const city of cities) {
|
for (const city of cities) {
|
||||||
// Aktuelle Stadt ausschließen
|
if (currentRegionId && city.id === currentRegionId) continue;
|
||||||
if (currentRegionId && city.id === currentRegionId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const worthPercent = worthMap.get(city.id) || 50;
|
const worthPercent = worthMap.get(city.id) || 50;
|
||||||
// Verwende calcRegionalSellPrice mit bereits geladenem worthPercent (keine DB-Query)
|
const priceInCity = calcRegionalSellPriceSync(product, knowledgeFactor, worthPercent);
|
||||||
const priceInCity = await calcRegionalSellPrice(product, knowledgeFactor, city.id, worthPercent);
|
if (priceInCity == null) continue;
|
||||||
|
|
||||||
// Nur Städte zurückgeben, wo der Preis höher ist
|
|
||||||
// Kleine Toleranz (0.01) für Rundungsfehler bei Gleitkommaberechnungen
|
|
||||||
const PRICE_TOLERANCE = 0.01;
|
|
||||||
if (priceInCity > currentRegionalPrice - PRICE_TOLERANCE) {
|
if (priceInCity > currentRegionalPrice - PRICE_TOLERANCE) {
|
||||||
// Branch-Typ bestimmen
|
// Branch-Typ bestimmen
|
||||||
let branchType = null; // null = kein Branch
|
let branchType = null; // null = kein Branch
|
||||||
|
|||||||
@@ -252,20 +252,6 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
speedLabel(value) {
|
|
||||||
if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—';
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
const k = value.tr ?? value.id ?? 'unknown';
|
|
||||||
const tKey = `falukant.branch.transport.speed.${k}`;
|
|
||||||
const t = this.$t(tKey);
|
|
||||||
return (t && t !== tKey) ? t : String(k);
|
|
||||||
}
|
|
||||||
const key = String(value);
|
|
||||||
const tKey = `falukant.branch.transport.speed.${key}`;
|
|
||||||
const translated = this.$t(tKey);
|
|
||||||
return (!translated || translated === tKey) ? key : translated;
|
|
||||||
},
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
await this.loadInventory();
|
await this.loadInventory();
|
||||||
await this.loadTransports();
|
await this.loadTransports();
|
||||||
@@ -281,6 +267,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
speedLabel(value) {
|
||||||
|
if (value == null) return this.$t('falukant.branch.transport.speed.unknown') || '—';
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
const k = value.tr ?? value.id ?? 'unknown';
|
||||||
|
const tKey = `falukant.branch.transport.speed.${k}`;
|
||||||
|
const t = this.$t(tKey);
|
||||||
|
return (t && t !== tKey) ? t : String(k);
|
||||||
|
}
|
||||||
|
const key = String(value);
|
||||||
|
const tKey = `falukant.branch.transport.speed.${key}`;
|
||||||
|
const translated = this.$t(tKey);
|
||||||
|
return (!translated || translated === tKey) ? key : translated;
|
||||||
|
},
|
||||||
async loadInventory() {
|
async loadInventory() {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get(`/api/falukant/inventory/${this.branchId}`);
|
const response = await apiClient.get(`/api/falukant/inventory/${this.branchId}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user