Füge neue Funktionen zur Verwaltung von Erben hinzu: Implementiere die API-Endpunkte zum Abrufen potenzieller Erben und zum Auswählen eines Erben. Ergänze die Logik in FalukantService zur Verarbeitung dieser Funktionen.

This commit is contained in:
Torsten Schulz (local)
2026-03-02 00:36:43 +01:00
parent 42fe568e2b
commit a2652c983f
4 changed files with 96 additions and 8 deletions

View File

@@ -98,6 +98,8 @@ class FalukantController {
if (!result) throw { status: 404, message: 'No family data found' }; if (!result) throw { status: 404, message: 'No family data found' };
return result; return result;
}); });
this.getPotentialHeirs = this._wrapWithUser((userId) => this.service.getPotentialHeirs(userId));
this.selectHeir = this._wrapWithUser((userId, req) => this.service.selectHeir(userId, req.body.heirId));
this.setHeir = this._wrapWithUser((userId, req) => this.service.setHeir(userId, req.body.childCharacterId)); this.setHeir = this._wrapWithUser((userId, req) => this.service.setHeir(userId, req.body.childCharacterId));
this.acceptMarriageProposal = this._wrapWithUser((userId, req) => this.service.acceptMarriageProposal(userId, req.body.proposalId)); this.acceptMarriageProposal = this._wrapWithUser((userId, req) => this.service.acceptMarriageProposal(userId, req.body.proposalId));
this.cancelWooing = this._wrapWithUser(async (userId) => { this.cancelWooing = this._wrapWithUser(async (userId) => {

View File

@@ -47,6 +47,8 @@ router.get('/dashboard-widget', falukantController.getDashboardWidget);
router.post('/family/acceptmarriageproposal', falukantController.acceptMarriageProposal); router.post('/family/acceptmarriageproposal', falukantController.acceptMarriageProposal);
router.post('/family/cancel-wooing', falukantController.cancelWooing); router.post('/family/cancel-wooing', falukantController.cancelWooing);
router.post('/family/set-heir', falukantController.setHeir); router.post('/family/set-heir', falukantController.setHeir);
router.get('/heirs/potential', falukantController.getPotentialHeirs);
router.post('/heirs/select', falukantController.selectHeir);
router.get('/family/gifts', falukantController.getGifts); router.get('/family/gifts', falukantController.getGifts);
router.get('/family/children', falukantController.getChildren); router.get('/family/children', falukantController.getChildren);
router.post('/family/gift', falukantController.sendGift); router.post('/family/gift', falukantController.sendGift);

View File

@@ -2910,6 +2910,97 @@ class FalukantService extends BaseService {
return { success: true, childCharacterId }; return { success: true, childCharacterId };
} }
async getPotentialHeirs(hashedUserId) {
const user = await this.getFalukantUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found');
if (user.character?.id) return [];
const noncivilTitle = await TitleOfNobility.findOne({
where: { labelTr: 'noncivil' },
attributes: ['id']
});
if (!noncivilTitle?.id) return [];
const tenDaysAgo = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000);
const mainRegionId = user.mainBranchRegionId || null;
const includes = [
{ model: FalukantPredefineFirstname, as: 'definedFirstName', attributes: ['name'] },
{ model: FalukantPredefineLastname, as: 'definedLastName', attributes: ['name'] }
];
const buildWhere = ({ withRegion = true, withYoungAge = true } = {}) => {
const where = {
userId: null,
titleOfNobility: noncivilTitle.id,
health: { [Op.gt]: 0 }
};
if (withRegion && mainRegionId) where.regionId = mainRegionId;
if (withYoungAge) where.birthdate = { [Op.gte]: tenDaysAgo };
return where;
};
const loadCandidates = async (where) => FalukantCharacter.findAll({
where,
include: includes,
attributes: ['id', 'birthdate', 'gender'],
order: sequelize.random(),
limit: 10
});
let candidates = await loadCandidates(buildWhere({ withRegion: true, withYoungAge: true }));
if (candidates.length === 0) {
candidates = await loadCandidates(buildWhere({ withRegion: true, withYoungAge: false }));
}
if (candidates.length === 0) {
candidates = await loadCandidates(buildWhere({ withRegion: false, withYoungAge: false }));
}
return candidates.map(candidate => {
const plain = candidate.get({ plain: true });
return {
...plain,
age: plain.birthdate ? calcAge(plain.birthdate) : null
};
});
}
async selectHeir(hashedUserId, heirId) {
const parsedHeirId = Number(heirId);
if (!Number.isInteger(parsedHeirId) || parsedHeirId < 1) {
throw { status: 400, message: 'Invalid heirId' };
}
const user = await this.getFalukantUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found');
if (user.character?.id) {
throw { status: 409, message: 'User already has an active character' };
}
const noncivilTitle = await TitleOfNobility.findOne({
where: { labelTr: 'noncivil' },
attributes: ['id']
});
if (!noncivilTitle?.id) throw new Error('Title "noncivil" not found');
const mainRegionId = user.mainBranchRegionId || null;
const where = {
id: parsedHeirId,
userId: null,
titleOfNobility: noncivilTitle.id,
health: { [Op.gt]: 0 }
};
if (mainRegionId) where.regionId = mainRegionId;
const candidate = await FalukantCharacter.findOne({ where, attributes: ['id'] });
if (!candidate) {
throw { status: 404, message: 'Selected heir is not available' };
}
await candidate.update({ userId: user.id });
return { success: true, heirId: candidate.id };
}
async getPossiblePartners(requestingCharacterId) { async getPossiblePartners(requestingCharacterId) {
const proposals = await MarriageProposal.findAll({ const proposals = await MarriageProposal.findAll({
where: { where: {

View File

@@ -16,7 +16,7 @@
<div class="heir-info"> <div class="heir-info">
<div class="heir-name"> <div class="heir-name">
{{ $t(`falukant.titles.${heir.gender}.noncivil`) }} {{ $t(`falukant.titles.${heir.gender}.noncivil`) }}
{{ heir.definedFirstName.name }} {{ heir.definedLastName.name }} {{ heir.definedFirstName?.name || '---' }} {{ heir.definedLastName?.name || '' }}
</div> </div>
<div class="heir-age">{{ $t('falukant.overview.metadata.age') }}: {{ heir.age }}</div> <div class="heir-age">{{ $t('falukant.overview.metadata.age') }}: {{ heir.age }}</div>
</div> </div>
@@ -381,13 +381,6 @@ export default {
return new Date(timestamp).toLocaleString(); return new Date(timestamp).toLocaleString();
}, },
async fetchPotentialHeirs() { async fetchPotentialHeirs() {
// Prüfe sowohl mainBranchRegion.id als auch mainBranchRegionId
const regionId = this.falukantUser?.mainBranchRegion?.id || this.falukantUser?.mainBranchRegionId;
if (!regionId) {
console.error('No main branch region found', this.falukantUser);
this.potentialHeirs = [];
return;
}
this.loadingHeirs = true; this.loadingHeirs = true;
try { try {
const response = await apiClient.get('/api/falukant/heirs/potential'); const response = await apiClient.get('/api/falukant/heirs/potential');