ABP我爱编程

abp & ng-alain 改造前端 三 —— 登录页

2018-06-21  本文已影响175人  诸葛_小亮

介绍

ABP 是 ASP.NET Boilerplate Project(Asp.net 样板项目)的简称,网址:http://aspnetboilerplate.com/
ng-alain 是基于 antd 中后台前端解决方案,网址:https://ng-alain.com/
官方网页下载的项目的angular项目是基于(AdminBSB:https://github.com/gurayyarar/AdminBSBMaterialDesign)

  1. 目录:https://www.jianshu.com/p/589af988637c
  2. 源代码:https://github.com/ZhaoRd/abp-alain

路由守护

路由守护的功能,是在定义ng路由的时候,添加一个条件,判断当前登录信息是否能够进行正常的路由调整。
打开文件routes-routing.module.ts,导入AppRouteGuard

import { AppRouteGuard } from '@shared/auth/auth-route-guard';

修改'dashboard/v1'路径,添加内容如下

path: 'dashboard/v1',
        component: DashboardV1Component,
        canActivate: [AppRouteGuard]

添加路由守护之后,在打开项目首页,会发现自动界面会自动跳转到登录页面


登录界面主要元素

登录界面主要有三处主要元素:租户切换、登录框、多语言切换


多语言切换

如下图所示,在界面上,有一系列的语言列表,点击国家旗帜,即可跳转到对应的语言


多语言

将angular项目中的account-languages.component相关文件copy到app\layout\passport\layout中,目录结构

目录结构

修改account-languages.component.less文件,修改完毕后的内容如下:


:host {
    ::ng-deep {

        .account-language-switch-list {
            text-align: center;
            list-style: none;
            margin: 0px;
            padding: 10px;
        
            > li {
                display: inline;
                margin: 0px;
                padding: 0px;

                i{
                    display: inline-block;
                }
            }
        }

    }
}

只有采用该方式,语言列表才会显示

修改account-languages.component.ts,只要修改selector即可,修改完毕的内容如下

import { Component, OnInit, Injector } from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';

import * as _ from 'lodash';

@Component({
  selector: 'passport-account-languages',
  templateUrl: './account-languages.component.html',
  styleUrls: ['./account-languages.component.less'],
})
export class AccountLanguagesComponent extends AppComponentBase
  implements OnInit {
  languages: abp.localization.ILanguageInfo[];
  currentLanguage: abp.localization.ILanguageInfo;

  constructor(injector: Injector) {
    super(injector);
  }

  ngOnInit() {
    this.languages = _.filter(this.localization.languages, l => !l.isDisabled);
    this.currentLanguage = this.localization.currentLanguage;
  }

  /***
   * 切换多语言
   * 存储cookie值并刷新当前页面
   */
  changeLanguage(languageName: string): void {
    abp.utils.setCookieValue(
      'Abp.Localization.CultureName',
      languageName,
      new Date(new Date().getTime() + 5 * 365 * 86400000), // 5 year
      abp.appPath,
    );

    location.reload();
  }
}

修改之后,在layout.module.ts中增加该组件的定义


修改布局文件passort.component.html,修改完毕代码如下

<div class="container">
  <div class="wrap">
    <div class="top">
      <div class="head">
        <img class="logo" src="./assets/logo-color.svg">
        <span class="title">AbpAlain
        </span>
      </div>
      <div class="desc">Abp & NgAlain</div>
    </div>
    <router-outlet></router-outlet>
    
    <passport-account-languages></passport-account-languages>
  
    <global-footer [links]="links">

      Copyright 
      <i class="anticon anticon-copyright"></i> {{currentYear}} 
      AbpAlain. <b>Version </b> {{versionText}}
    </global-footer>
  </div>
</div>


租户切换

租户切换的界面如下


功能
修改租户

使用的文件如下图


文件

修改 tenant-change.component.html,内容如下

<div *ngIf="isMultiTenancyEnabled" class="card tenant-change-component" style="margin-bottom: 3px;">
  <div class="body text-center">
    <span>
      {{l("CurrentTenant")}}: <span *ngIf="tenancyName" title="{{name}}"><strong>{{tenancyName}}</strong></span>
      <span *ngIf="!tenancyName">{{l("NotSelected")}}</span> (<a href="javascript:void();" (click)="showChangeModal()">{{l("Change")}}</a>)
    </span>
  </div>
</div>

修改tenant-change.component.ts,内容如下

import { Component, OnInit, Injector } from '@angular/core';
import { TenantChangeModalComponent } from './tenant-change-modal.component';
import { AppComponentBase } from '@shared/app-component-base';

import { AppModalService } from '@shared/modal/appModalService';

@Component({
  selector: 'passport-tenant-change',
  templateUrl: './tenant-change.component.html',
})
export class TenantChangeComponent extends AppComponentBase implements OnInit {
  tenancyName: string;
  name: string;
  options = {};

  constructor(injector: Injector, private _appModalService: AppModalService) {
    super(injector);
  }

  ngOnInit() {
    if (this.appSession.tenant) {
      this.tenancyName = this.appSession.tenant.tenancyName;
      this.name = this.appSession.tenant.name;
    }
  }

  get isMultiTenancyEnabled(): boolean {
    return abp.multiTenancy.isEnabled;
  }

  /**
   * 显示切换租户弹出框
   */
  showChangeModal(): void {
    
    this._appModalService
      .show(TenantChangeModalComponent, {
        tenancyName: this.tenancyName,
      })
      .subscribe(result => {
        abp.log.debug({
          afterClose: result,
        });
      });
  }
}


修改tenant-change-modal.component.html,内容如下


<div class="modal-header">
  <div class="modal-title">{{l("ChangeTenant")}}</div>
</div>


<div nz-row>
  <div nz-col class="mt-sm">
    {{l("TenancyName")}}
  </div>
  <div ng-col class="mt-sm">
    <input nz-input #tenancyNameInput [(ngModel)]="tenancyName" />
  </div>
  <div ng-col class="mt-sm">
    {{l("LeaveEmptyToSwitchToHost")}}
  </div>
</div>

<div class="modal-footer">
  <button nz-button [nzType]="'default'" [nzSize]="'large'" (click)="close()">
    {{l("Cancel")}}
  </button>
  <button nz-button [nzType]="'primary'" [nzSize]="'large'" (click)="save()">
    {{l("Save")}}
  </button>
</div>

修改tenant-change-modal.component.ts,内容如下

import {
  Component,
  OnInit,
  ViewChild,
  Injector,
  ElementRef,
  Input,
  AfterViewInit,
} from '@angular/core';
import { AppComponentBase } from '@shared/app-component-base';
import { AccountServiceProxy } from '@shared/service-proxies/service-proxies';
import { IsTenantAvailableInput } from '@shared/service-proxies/service-proxies';
import { AppTenantAvailabilityState } from '@shared/AppEnums';

import { NzModalRef, NzModalService, NzMessageService } from 'ng-zorro-antd';

@Component({
  selector: 'passport-tenant-change-modal',
  templateUrl: './tenant-change-modal.component.html',
})
export class TenantChangeModalComponent extends AppComponentBase
  implements AfterViewInit {
  
  @ViewChild('tenancyNameInput') tenancyNameInput: ElementRef;

  active = false;
  saving = false;

  /**
   * 租主名,使用@Input 传递参数
   */
  @Input() tenancyName = '';

  constructor(
    private _accountService: AccountServiceProxy,
    private modal: NzModalService,
    private subject: NzModalRef,
    injector: Injector,
  ) {
    super(injector);
  }

  show(tenancyName: string): void {
    this.tenancyName = tenancyName;
    this.active = true;
  }

  ngAfterViewInit(): void {
  }

  /**
   * 保存操作,如果租户为空,则清空cookie租户信息,并重新加载当前页面
   * 如果租户名正确,则保存当前租户名到cookie,并重新加载当前页面
   */
  save(): void {
    if (!this.tenancyName) {
      abp.multiTenancy.setTenantIdCookie(undefined);
      this.close();
      location.reload();
      return;
    }

    const input = new IsTenantAvailableInput();
    input.tenancyName = this.tenancyName;

    this.saving = true;
    // 验证租户
    this._accountService
      .isTenantAvailable(input)
      .finally(() => {
        this.saving = false;
      })
      .subscribe(result => {
        switch (result.state) {
          case AppTenantAvailabilityState.Available:
            abp.multiTenancy.setTenantIdCookie(result.tenantId);
            this.close();
            location.reload();
            return;
          case AppTenantAvailabilityState.InActive:
            this.message.warn(this.l('TenantIsNotActive', this.tenancyName));
            break;
          case AppTenantAvailabilityState.NotFound: // NotFound
            this.message.warn(
              this.l('ThereIsNoTenantDefinedWithName{0}', this.tenancyName),
            );
            break;
        }
      });
  }

  /**
   * 关闭弹出窗
   */
  close(): void {
    this.subject.destroy();
  }
}


在 layout.module中导入这两个组件


注意组件TenantChangeModalComponent,由于该组件是动态弹出框,所以需要添加在entryComponents中,关于动态加载的弹出框,在后面的篇幅会介绍。

修改布局界面,导入切换租户组件


切换租户组件

运行结果

租户切换

1
2
3

语言切换

1
2

总结

abp自带项目angular中,多语言的切换和租户的切换,是登录界面上进行操作的,其本质是将租户信息和多语言信息存储到cookie中,我们使用abp组件的功能,修改abp组件,符合ng-alain项目的样式即可实现。
通过修改组件也发现,ng-alain在组件命名方面是由规范的,主要组件,需要用app、passport等前缀。


我的公众号

我的公众号

源代码

源代码:https://github.com/ZhaoRd/abp-alain

上一篇 下一篇

猜你喜欢

热点阅读