Add batch price retrieval for products in region

- Implemented a new endpoint to fetch prices for multiple products in a specified region in a single request, improving efficiency.
- Added validation for input parameters to ensure proper data handling.
- Updated the FalukantService to calculate prices based on knowledge factors and worth percentages for each product.
- Modified the frontend to utilize the new batch endpoint, optimizing the loading of product prices.
This commit is contained in:
Torsten Schulz (local)
2026-01-12 08:58:28 +01:00
parent 64baebfaaa
commit 5e26422e9c
4 changed files with 106 additions and 20 deletions

View File

@@ -162,6 +162,18 @@ class FalukantController {
}
return this.service.getProductPriceInRegion(userId, productId, regionId);
});
this.getProductPricesInRegionBatch = this._wrapWithUser((userId, req) => {
const productIds = req.query.productIds;
const regionId = parseInt(req.query.regionId, 10);
if (!productIds || Number.isNaN(regionId)) {
throw new Error('productIds (comma-separated) and regionId are required');
}
const productIdArray = productIds.split(',').map(id => parseInt(id.trim(), 10)).filter(id => !Number.isNaN(id));
if (productIdArray.length === 0) {
throw new Error('At least one valid productId is required');
}
return this.service.getProductPricesInRegionBatch(userId, productIdArray, regionId);
});
this.getProductPricesInCities = this._wrapWithUser((userId, req) => {
const productId = parseInt(req.query.productId, 10);
const currentPrice = parseFloat(req.query.currentPrice);

View File

@@ -76,6 +76,7 @@ router.get('/politics/open', falukantController.getOpenPolitics);
router.post('/politics/open', falukantController.applyForElections);
router.get('/cities', falukantController.getRegions);
router.get('/products/price-in-region', falukantController.getProductPriceInRegion);
router.get('/products/prices-in-region-batch', falukantController.getProductPricesInRegionBatch);
router.get('/products/prices-in-cities', falukantController.getProductPricesInCities);
router.get('/branches/:branchId/taxes', falukantController.getBranchTaxes);
router.get('/vehicles/types', falukantController.getVehicleTypes);

View File

@@ -5133,6 +5133,57 @@ class FalukantService extends BaseService {
return regions;
}
async getProductPricesInRegionBatch(hashedUserId, productIds, regionId) {
const user = await this.getFalukantUserByHashedId(hashedUserId);
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
if (!character) {
throw new Error(`No FalukantCharacter found for user with id ${user.id}`);
}
if (!Array.isArray(productIds) || productIds.length === 0) {
return {};
}
// Hole alle Produkte auf einmal
const products = await ProductType.findAll({
where: { id: { [Op.in]: productIds } }
});
// Hole alle Knowledge-Werte auf einmal
const knowledges = await Knowledge.findAll({
where: {
characterId: character.id,
productId: { [Op.in]: productIds }
}
});
const knowledgeMap = new Map(knowledges.map(k => [k.productId, k.knowledge]));
// Hole alle TownProductWorth-Werte auf einmal
const townWorths = await TownProductWorth.findAll({
where: {
productId: { [Op.in]: productIds },
regionId: regionId
}
});
const worthMap = new Map(townWorths.map(tw => [tw.productId, tw.worthPercent]));
// Berechne Preise für alle Produkte
const prices = {};
for (const product of products) {
const knowledgeFactor = knowledgeMap.get(product.id) || 0;
const worthPercent = worthMap.get(product.id) || 50;
const basePrice = product.sellCost * (worthPercent / 100);
const min = basePrice * 0.6;
const max = basePrice;
const price = min + (max - min) * (knowledgeFactor / 100);
prices[product.id] = Math.round(price * 100) / 100; // Auf 2 Dezimalstellen runden
}
return prices;
}
async getProductPriceInRegion(hashedUserId, productId, regionId) {
const user = await this.getFalukantUserByHashedId(hashedUserId);
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });