feat(FalukantService, OverviewView): enhance church office information retrieval and UI display
All checks were successful
Deploy to production / deploy (push) Successful in 1m51s
All checks were successful
Deploy to production / deploy (push) Successful in 1m51s
- Refactored the `getHighestChurchOfficeInfo` method to utilize a new approach for retrieving the highest church office, improving accuracy and performance. - Updated the `OverviewView` to format and display the highest political and church office names instead of raw rank values, enhancing user experience and clarity. - Introduced a new method `formatCertificateHighestOffice` for better localization and presentation of office titles in the UI.
This commit is contained in:
@@ -2946,27 +2946,24 @@ class FalukantService extends BaseService {
|
|||||||
return parseFloat(averageKnowledge[0]?.avgKnowledge || 0);
|
return parseFloat(averageKnowledge[0]?.avgKnowledge || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Höchstes kirchliches Amt (Stufe + Typ-Name), inkl. Karrierehöchstwert:
|
||||||
|
* aktuelle `church_office`-Zeilen plus genehmigte Bewerbungen (wie `getChurchCareerInfo`),
|
||||||
|
* nicht nur die aktuelle Besetzung — analog zu Politik mit `PoliticalOfficeHistory`.
|
||||||
|
*/
|
||||||
async getHighestChurchOfficeInfo(userId) {
|
async getHighestChurchOfficeInfo(userId) {
|
||||||
const character = await FalukantCharacter.findOne({
|
const characterId = await this.resolveCharacterIdForOfficeChecks(userId);
|
||||||
where: { userId },
|
if (!characterId) return { rank: 0, name: null };
|
||||||
attributes: ['id']
|
|
||||||
});
|
|
||||||
if (!character) return { rank: 0, name: null };
|
|
||||||
|
|
||||||
const churchOffices = await ChurchOffice.findAll({
|
const career = await this.getChurchCareerInfo(characterId);
|
||||||
where: { characterId: character.id },
|
const highest = career?.highestEverOffice;
|
||||||
include: [{ model: ChurchOfficeType, as: 'type', attributes: ['name', 'hierarchyLevel'] }],
|
if (!highest?.name) {
|
||||||
attributes: ['officeTypeId']
|
return { rank: 0, name: null };
|
||||||
});
|
}
|
||||||
|
return {
|
||||||
const candidates = churchOffices
|
rank: Number(highest.hierarchyLevel ?? 0),
|
||||||
.map((office) => ({
|
name: highest.name
|
||||||
rank: Number(office.type?.hierarchyLevel || 0),
|
};
|
||||||
name: office.type?.name || null,
|
|
||||||
}))
|
|
||||||
.sort((a, b) => b.rank - a.rank);
|
|
||||||
|
|
||||||
return candidates[0] || { rank: 0, name: null };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3055,6 +3052,9 @@ class FalukantService extends BaseService {
|
|||||||
completedProductions,
|
completedProductions,
|
||||||
highestPoliticalOfficeRank,
|
highestPoliticalOfficeRank,
|
||||||
highestChurchOfficeRank,
|
highestChurchOfficeRank,
|
||||||
|
/** Technischer Schlüssel (z. B. assessor, lay-preacher) für UI-Übersetzung */
|
||||||
|
highestPoliticalOfficeName: highestPoliticalOffice?.name ?? null,
|
||||||
|
highestChurchOfficeName: highestChurchOffice?.name ?? null,
|
||||||
highestOfficeRank,
|
highestOfficeRank,
|
||||||
nobilityLevel,
|
nobilityLevel,
|
||||||
reputation,
|
reputation,
|
||||||
@@ -3686,17 +3686,19 @@ class FalukantService extends BaseService {
|
|||||||
lover.politicalFreeMaintenance = idx < politicalFreeLoverSlots;
|
lover.politicalFreeMaintenance = idx < politicalFreeLoverSlots;
|
||||||
lover.monthlyCost = lover.politicalFreeMaintenance ? 0 : base;
|
lover.monthlyCost = lover.politicalFreeMaintenance ? 0 : base;
|
||||||
});
|
});
|
||||||
const derivedHouseholdTension = this.calculateHouseholdTension({
|
const tensionRefresh = await this.refreshHouseholdTensionState(user, character);
|
||||||
|
const baseTension = tensionRefresh
|
||||||
|
|| this.calculateHouseholdTension({
|
||||||
lovers,
|
lovers,
|
||||||
marriageSatisfaction,
|
marriageSatisfaction,
|
||||||
userHouse,
|
userHouse,
|
||||||
children
|
children
|
||||||
});
|
});
|
||||||
const householdTension = {
|
const householdTension = {
|
||||||
score: Number(userHouse?.householdTensionScore ?? derivedHouseholdTension.score),
|
score: baseTension.score,
|
||||||
reasons: Array.isArray(userHouse?.householdTensionReasonsJson) ? userHouse.householdTensionReasonsJson : derivedHouseholdTension.reasons
|
reasons: baseTension.reasons,
|
||||||
|
label: baseTension.label
|
||||||
};
|
};
|
||||||
householdTension.label = this.getHouseholdTensionLabel(householdTension.score);
|
|
||||||
const family = {
|
const family = {
|
||||||
relationships: activeRelationships.map((r) => ({
|
relationships: activeRelationships.map((r) => ({
|
||||||
...r,
|
...r,
|
||||||
@@ -6158,7 +6160,7 @@ class FalukantService extends BaseService {
|
|||||||
const characterId = await this.resolveCharacterIdForOfficeChecks(userId);
|
const characterId = await this.resolveCharacterIdForOfficeChecks(userId);
|
||||||
if (!characterId) return { rank: 0, name: null, source: null };
|
if (!characterId) return { rank: 0, name: null, source: null };
|
||||||
|
|
||||||
const [politicalOffices, politicalHistories, churchOffices] = await Promise.all([
|
const [politicalOffices, politicalHistories, churchCareer] = await Promise.all([
|
||||||
PoliticalOffice.findAll({
|
PoliticalOffice.findAll({
|
||||||
where: { characterId },
|
where: { characterId },
|
||||||
include: [{ model: PoliticalOfficeType, as: 'type', attributes: ['name'] }],
|
include: [{ model: PoliticalOfficeType, as: 'type', attributes: ['name'] }],
|
||||||
@@ -6169,13 +6171,18 @@ class FalukantService extends BaseService {
|
|||||||
include: [{ model: PoliticalOfficeType, as: 'officeTypeHistory', attributes: ['name'] }],
|
include: [{ model: PoliticalOfficeType, as: 'officeTypeHistory', attributes: ['name'] }],
|
||||||
attributes: ['officeTypeId']
|
attributes: ['officeTypeId']
|
||||||
}),
|
}),
|
||||||
ChurchOffice.findAll({
|
this.getChurchCareerInfo(characterId)
|
||||||
where: { characterId },
|
|
||||||
include: [{ model: ChurchOfficeType, as: 'type', attributes: ['name', 'hierarchyLevel'] }],
|
|
||||||
attributes: ['officeTypeId']
|
|
||||||
})
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const churchEver = churchCareer?.highestEverOffice;
|
||||||
|
const churchCandidates = churchEver?.name
|
||||||
|
? [{
|
||||||
|
rank: Number(churchEver.hierarchyLevel ?? 0),
|
||||||
|
name: churchEver.name,
|
||||||
|
source: 'church'
|
||||||
|
}]
|
||||||
|
: [];
|
||||||
|
|
||||||
const candidates = [
|
const candidates = [
|
||||||
...politicalOffices.map((office) => ({
|
...politicalOffices.map((office) => ({
|
||||||
rank: POLITICAL_OFFICE_RANKS[office.type?.name] || 0,
|
rank: POLITICAL_OFFICE_RANKS[office.type?.name] || 0,
|
||||||
@@ -6187,11 +6194,7 @@ class FalukantService extends BaseService {
|
|||||||
name: history.officeTypeHistory?.name || null,
|
name: history.officeTypeHistory?.name || null,
|
||||||
source: 'political'
|
source: 'political'
|
||||||
})),
|
})),
|
||||||
...churchOffices.map((office) => ({
|
...churchCandidates
|
||||||
rank: Number(office.type?.hierarchyLevel || 0),
|
|
||||||
name: office.type?.name || null,
|
|
||||||
source: 'church'
|
|
||||||
}))
|
|
||||||
].sort((a, b) => b.rank - a.rank);
|
].sort((a, b) => b.rank - a.rank);
|
||||||
|
|
||||||
return candidates[0] || { rank: 0, name: null, source: null };
|
return candidates[0] || { rank: 0, name: null, source: null };
|
||||||
|
|||||||
@@ -155,11 +155,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-list__item">
|
<div class="detail-list__item">
|
||||||
<span>{{ $t('falukant.overview.certificate.factor.highestPoliticalOfficeRank') }}</span>
|
<span>{{ $t('falukant.overview.certificate.factor.highestPoliticalOfficeRank') }}</span>
|
||||||
<strong>{{ certificateProgress.currentValues.highestPoliticalOfficeRank }}</strong>
|
<strong>{{ formatCertificateHighestOffice('political') }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-list__item">
|
<div class="detail-list__item">
|
||||||
<span>{{ $t('falukant.overview.certificate.factor.highestChurchOfficeRank') }}</span>
|
<span>{{ $t('falukant.overview.certificate.factor.highestChurchOfficeRank') }}</span>
|
||||||
<strong>{{ certificateProgress.currentValues.highestChurchOfficeRank }}</strong>
|
<strong>{{ formatCertificateHighestOffice('church') }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-list__item">
|
<div class="detail-list__item">
|
||||||
<span>{{ $t('falukant.overview.certificate.factor.nobilityLevel') }}</span>
|
<span>{{ $t('falukant.overview.certificate.factor.nobilityLevel') }}</span>
|
||||||
@@ -752,6 +752,24 @@ export default {
|
|||||||
maximumFractionDigits: digits,
|
maximumFractionDigits: digits,
|
||||||
}).format(value);
|
}).format(value);
|
||||||
},
|
},
|
||||||
|
/** Höchstes politisches/kirchliches Amt als übersetzter Amtsname statt Rohzahl (z. B. 1,00). */
|
||||||
|
formatCertificateHighestOffice(kind) {
|
||||||
|
const cv = this.certificateProgress?.currentValues;
|
||||||
|
if (!cv) return '---';
|
||||||
|
const name = kind === 'church' ? cv.highestChurchOfficeName : cv.highestPoliticalOfficeName;
|
||||||
|
const rankKey = kind === 'church' ? 'highestChurchOfficeRank' : 'highestPoliticalOfficeRank';
|
||||||
|
const rank = Math.round(Number(cv[rankKey] ?? 0));
|
||||||
|
const baseKey = kind === 'church' ? 'falukant.church.offices' : 'falukant.politics.offices';
|
||||||
|
if (!name && rank <= 0) {
|
||||||
|
return this.$t('falukant.nobility.none');
|
||||||
|
}
|
||||||
|
if (name) {
|
||||||
|
return this.$te(`${baseKey}.${name}`)
|
||||||
|
? this.$t(`${baseKey}.${name}`)
|
||||||
|
: name;
|
||||||
|
}
|
||||||
|
return String(rank);
|
||||||
|
},
|
||||||
formatCertificateRequirement(current, required) {
|
formatCertificateRequirement(current, required) {
|
||||||
const currentDigits = typeof current === 'number' && !Number.isInteger(current) ? 1 : 0;
|
const currentDigits = typeof current === 'number' && !Number.isInteger(current) ? 1 : 0;
|
||||||
const requiredDigits = typeof required === 'number' && !Number.isInteger(required) ? 1 : 0;
|
const requiredDigits = typeof required === 'number' && !Number.isInteger(required) ? 1 : 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user