美文网首页ABP我爱编程
abp & ng-alain 改造前端 三 —— 登录页

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

作者: 诸葛_小亮 | 来源:发表于2018-06-21 22:48 被阅读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

    相关文章

      网友评论

      本文标题:abp & ng-alain 改造前端 三 —— 登录页

      本文链接:https://www.haomeiwen.com/subject/dzlfyftx.html