Jhipster:使用户能够创建自动链接到其帐户的对象

时间:2019-01-14 08:02:39

标签: angular typescript spring-boot jhipster

我正在建立一项服务,以帮助人们做出明智的决定。 为此,我需要引导用户完成入职流程,在此流程中,他们将创建描述其情况的实体。

当他们输入数据时,我希望能够将这些实体相互链接,并将这些实体也链接至用户。

为方便起见,我调查了以下答案:

Jhipster extented user entity and account creation

JHipster : Registering a user with additional information

尽管我的方法相似,但这些都没有回答我的问题。

我已经创建了一个用户元数据对象,并通过JDL将其链接到Jhipster用户实体-现在,我需要找到一种方法来获取登录用户,以便可以将对该登录用户的引用添加到实体中他们已经创建了。

我已遍历整个过程,并从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对象。

我也很清楚这是一个尝试做很多事情的大方法。一旦确认整个过程都可行,我将对其进行重构以使其更易于管理。

如果有人对这种方法有意见,做过类似的事情或知道为什么未定义帐户和用户变量(我以admin身份登录时运行了该方法),我将不胜感激!

请随时感谢您的宝贵意见!

2 个答案:

答案 0 :(得分:3)

JHipster提供了一个名为SecurityUtils的实用程序类。您可以使用它来访问当前用户的登录名或他们的JWT令牌。

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

如果您还需要其他信息,则可以使用UserRepository通过使用SecurityUtils类检索的用户登录名来检索整个用户对象。

UserRepository.findOneByLogin('usersLogin');

这存在于API端,因此不需要在前端询问您要实现的帐户对象。

P.s。您无法在上面的代码中控制台记录帐户信息的原因是因为尚未解决检索该信息的承诺-因此,该对象仍然为null。您必须将console.log放入承诺解决方案中,即

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

其他请求也需要相同的方法。

答案 1 :(得分:0)

非常感谢Phobos的信息,我创建了一个简单的解决方案,效果很好。

我将在下面为将来可能遇到相同问题的其他人详细说明:

与我当前的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获取用户的登录名,然后通过登录名找到该用户的用户元数据。客户端永远不必询问实际的用户对象。

我将UserMetadata类型的Optional传递到Web层,该Web层使用Jhipster的ResponseUtil返回该可选对象内的对象,或者返回错误:

    /**
     * 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);
    }

然后我们去前端。在userMetadata 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为您做了很多很酷的事情,但就我而言,这实际上导致了一种感觉,即“它发生在魔术中”与“我了解其工作原理”。

现在我对这个特定功能的工作原理有了更好的了解!