Jhipster: предоставление пользователю возможности создавать объекты, которые автоматически связаны с его учетной записью - PullRequest
0 голосов
/ 14 января 2019

Я создаю службу, которая помогает людям принимать правильные решения. Как часть этого, мне нужно провести пользователей через входящий поток, где они создают сущности, которые описывают их ситуацию.

Когда они вводят данные, я хочу иметь возможность связывать эти сущности друг с другом, а также связывать сущности с пользователем.

Чтобы облегчить это, я исследовал следующие ответы:

Создание расширенного пользовательского объекта Jhipster и создание учетной записи

JHipster: регистрация пользователя с дополнительной информацией

Они не ответили на мой вопрос, хотя мой подход аналогичен.

Я создал объект метаданных пользователя и связал его с пользовательской сущностью Jhipster через JDL - теперь мне нужно найти способ получить вошедшего в систему пользователя, чтобы я мог добавить ссылку на зарегистрированного пользователя в сущности они создали.

Я прошел большую часть пути и получил руководство от самого кода Jhipster.

У меня есть метод в компоненте, у меня есть ряд вопросов.

company: Company;
project: Project;
team: Team;

account: Account;
user: User;
userMetadata: UserMetadata;

linkEntities() {

    // Question 1: Is this the right approach?
    // Find the logged in account, the user is linked to this
    this.accountService.identity().then(account => {
        this.account = account;
    });

    // Find the user for that account
    this.userService.find(this.account.login)
            .subscribe(res => this.user = res.body);

    // Find the metadata
    this.userMetadataService.find(this.user.id)
            .subscribe(res => this.userMetadata = res.body);

    // Question 2: These values are undefined
    // Is there something obvious I am missing that might explain why?
    console.log(this.account);
    console.log(this.user);
    console.log(this.userMetadata);

    // The company, project and team entities have been 
    // created and submitted in a previous function, 
    // here I update them with the references to one another
    this.company.employees.push(currentlyLoggedInUserMetadata)
    this.project.participants.push(currentlyLoggedInUserMetadata)
    this.team.members.push(currentlyLoggedInUserMetadata)

    this.company.teamOwners.push(this.team);
    this.company.companyProjects.push(this.project);

    this.project.implementingTeams.push(this.team);
    this.project.parentCompany = this.company;

    this.team.parentCompany = this.company;
    this.team.teamProjects.push(this.project);

    // And then send the updated entities to the api
    this.subscribeToCompanySaveResponse(this.companyService.update(this.company));
    this.subscribeToProjectSaveResponse(this.projectService.update(this.project));
    this.subscribeToTeamSaveResponse(this.teamService.update(this.team));
}

Я заблудился, почему в трех указанных выше файлах console.logs есть ошибки. Я только что установил эти три значения чуть выше console.logs. Я достаточно новичок в RxJS - есть ли что-то в способе работы наблюдаемых, что может быть причиной этого?

В идеале, я бы хотел, чтобы для вошедшего в систему пользователя существовало глобально доступное значение, хранящееся в пользовательской службе (в службе учетных записей есть личный экземпляр учетной записи, но нет пользователя - я должен просто сделать эту учетную запись общедоступной, где по умолчанию это личное?)

Я не уверен в том, что лучший подход или наиболее подход "jhipster" заключается в том, чтобы получить связанный с пользователем объект userMetadata один на один для текущего пользователя, вошедшего в систему.

Я также очень хорошо понимаю, что это большой метод, который пытается сделать много вещей. Как только я смогу подтвердить, что все работает, я сделаю рефакторинг, чтобы сделать его более управляемым.

Если у кого-то есть совет по этому подходу, он сделал что-то подобное или знает, почему учетные и пользовательские переменные, в частности, не определены (я запустил метод, войдя в систему как администратор), я был бы признателен за понимание!

Заранее благодарим за предоставленное время и советы!

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Большое спасибо за информацию, Фобос, я создал простое решение, которое хорошо работает.

Я опишу это ниже для тех, у кого может появиться такая же проблема в будущем:

Как и в моей текущей версии Jhipster (5.7.2) - я использовал помощник SecurityUtils для написания простой конечной точки API, чтобы получить текущего зарегистрированного пользователя (или, более конкретно, его метаданные - это произвольная сущность с 1 -1 сопоставление с пользовательской сущностью Jhipster).

Сначала я добавил метод в хранилище сущностей метаданных:

/**
 * Spring Data  repository for the UserMetadata entity.
 */
@SuppressWarnings("unused")
@Repository
public interface UserMetadataRepository extends JpaRepository<UserMetadata, Long> {
    Optional<UserMetadata> findOneByUser(User user);
}

Я использую отдельные классы обслуживания и так называемое хранилище в классе обслуживания пользовательских метаданных:

    /**
     * Get the user metadata object that is associated with the currently logged in user
     * @return an optional containing nothing, or the metadata object
     */
    public Optional<UserMetadata> getUserMetadataForCurrentUser() {

        Optional<UserMetadata> userMetadata = Optional.empty();

        Optional<User> currentUser = SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneByLogin);

        if (currentUser.isPresent()) {
            userMetadata = userMetadataRepository.findOneByUser(currentUser.get());
        }

        return userMetadata;
    }

Обратите внимание, что я упростила задачу, поместив большую часть логики в API, чтобы клиент мог быть настолько глупым, насколько это возможно. Мне нравятся умные API и тупые клиенты.

Выше я использую securityUtils, чтобы получить логин пользователя, а затем нахожу метаданные этого пользователя по логину. Клиент никогда не должен запрашивать фактический объект пользователя.

Я передаю Optional типа UserMetadata на веб-слой, который использует ResponseUtil от Jhipster, чтобы либо вернуть объект внутри необязательного параметра, либо произошла ошибка:

    /**
     * GET  /user-metadata/me : get the user metadata of the current user.
     *
     * @return the ResponseEntity with status 200 (OK) and with body the userMetadata, or with status 404 (Not Found)
     */
    @GetMapping("/user-metadata/me")
    @Timed
    public ResponseEntity<UserMetadata> getUserMetadataForCurrentUser() {
        log.debug("REST request to get UserMetadata for current user");
        Optional<UserMetadata> userMetadata = userMetadataService.getUserMetadataForCurrentUser();
        return ResponseUtil.wrapOrNotFound(userMetadata);
    }

Тогда мы идем к передней части. В пользовательском сервисе Metadata Angular:

@Injectable({ providedIn: 'root' })
export class UserMetadataService {
    public resourceUrl = SERVER_API_URL + 'api/user-metadata';

    currentUserMetadata: UserMetadata;

    constructor(protected http: HttpClient) {
        this.getCurrentUserMetadata().subscribe(res => (this.currentUserMetadata = res.body));
    }

    getCurrentUserMetadata() {
        return this.http.get<IUserMetadata>(`${this.resourceUrl}/me`, { observe: 'response' });
    }

// Rest of File

Я решил установить глобально доступное значение, чтобы мои другие компоненты и службы могли просто получать переменную метаданных и не вызывать ее каждый раз. Я создал метод для вызова новой конечной точки API и использовал этот метод в конструкторе, чтобы объект всегда был доступен клиенту.

Я пытался оттолкнуть сложность от нижестоящего потребителя, насколько смог. Компонент, который я изначально спрашивал, теперь может достичь цели с помощью трех строк кода:

this.company.employees.push(this.userMetadataService.currentUserMetadata);
this.project.participants.push(this.userMetadataService.currentUserMetadata);
this.team.members.push(this.userMetadataService.currentUserMetadata);

Остальное скрыто в службах и самом API.

Надеюсь, другие найдут эту информацию полезной. Я попытался объяснить все, потому что это было очень запутанным, когда я впервые погрузился в кодовую базу. Jhipster делает много классных вещей для вас, но в моем случае это фактически привело к ощущению «это происходит с магией» против «я понимаю механику того, как это работает».

Теперь у меня есть лучшее представление о том, как работает эта конкретная функция!

0 голосов
/ 14 января 2019

JHipster предоставляет класс Utility под названием SecurityUtils. Вы можете использовать это для доступа к логину текущего пользователя или его токену JWT.

SecurityUtils.getCurrentUserLogin();
SecurityUtils.getCurrentUserJWT();

Если вам нужна другая информация для ваших целей, вы можете использовать UserRepository для извлечения всего объекта пользователя с использованием имени пользователя, полученного с помощью класса SecurityUtils.

UserRepository.findOneByLogin('usersLogin');

Это существует на стороне API, поэтому нет необходимости опрашивать объект учетной записи на внешнем интерфейсе для достижения того, чего вы пытаетесь достичь.

P.s. Причина, по которой вы не можете консоль записать информацию об учетной записи в приведенном выше коде, заключается в том, что обещание, которое извлекает эту информацию, еще не выполнено - таким образом, объект по-прежнему равен нулю. Вы должны будете поместить ваш console.log в ваше обещание, то есть

this.accountService.identity().then(account => {
    this.account = account;
    console.log(this.account);
});

Такой же подход необходим для других запросов.

...