五、Abp Vnext中使用Minio打造文件管理模块(下)

上一章介绍了使用Minio创建文件管理模块的aspnetcore后端代码的实现,这一章主要介绍angular前端代码的实现,具体步骤如下:

1、安装文件上传依赖包

上一章我们已经使用模板生成了框架代码,使用vscode打开filemanagement.angular文件夹,启用终端,输入如下命令安装ngx-uploader文件上传组件

npm install ngx-uploader

2、添加文件管理模块

在vscode终端输入如下命令添加文件管理库:

ng generate library file-management

文件管理lib中可以删除掉自动生成的component和service,只保留module文件,注意同时要删除错误的引用

输入如下命令添加一个文件浏览组件file-browser

ng generate component file-browser --skip-tests --project file-management

输入命令添加个人文件浏览组件

ng generate component my-file-browser --skip-tests --project file-management

输入命令添加公共文件浏览组件

ng generate component public-file-browser --skip-tests --project file-management

接着在lib目录添加file-management-routing.module.ts文件,内容如下:

import { NgModule } from '@angular/core';
import { AuthGuard, DynamicLayoutComponent, PermissionGuard } from '@abp/ng.core';
import { Routes, RouterModule } from '@angular/router';
import { MyFileBrowserComponent } from './my-file-browser/my-file-browser.component';
import { PublicFileBrowserComponent } from './public-file-browser/public-file-browser.component';

const routes: Routes = [
  {
    path: '',
    // 注意升级5.0.0正式版本后,需要将DynamicLayoutComponent修改为RouterOutletComponent,否则组件页面无法显示
    component: DynamicLayoutComponent,
    canActivate: [AuthGuard, PermissionGuard],
    children: [
      {
        path: 'public-files',
        component: PublicFileBrowserComponent,
        data: { requiredPolicy: 'FileManagement.PublicFiles'},
      },
      {
          path: 'my-files',
          component: MyFileBrowserComponent,
          data: { requiredPolicy: 'FileManagement.MyFiles'},
      },
    ],
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class FileManagementRoutingModule {}

最后修改模块file-management.module.ts文件,添加必须的模块引入以及配置模块懒加载:

import { CoreModule, LazyModuleFactory } from '@abp/ng.core';
import { ThemeSharedModule } from '@abp/ng.theme.shared';
import { ModuleWithProviders, NgModule, NgModuleFactory } from '@angular/core';
import { NgxUploaderModule } from 'ngx-uploader';
import { FileBrowserComponent } from './file-browser/file-browser.component';
import { FileManagementRoutingModule } from './file-management-routing.module';
import { MyFileBrowserComponent } from './my-file-browser/my-file-browser.component';
import { PublicFileBrowserComponent } from './public-file-browser/public-file-browser.component';
import { UploadFilesComponent } from './upload-files/upload-files.component';
import { NgbDropdownModule, NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  declarations: [ FileBrowserComponent, MyFileBrowserComponent, PublicFileBrowserComponent, UploadFilesComponent
  ],
  imports: [ CoreModule, ThemeSharedModule, FileManagementRoutingModule, NgxUploaderModule, NgbDropdownModule, NgbProgressbarModule ],
  exports: [ ]
})
export class FileManagementModule { 
  static forChild(): ModuleWithProviders<FileManagementModule> {
    return {
      ngModule: FileManagementModule
    };
  }

  static forLazy(): NgModuleFactory<FileManagementModule> {
    return new LazyModuleFactory(FileManagementModule.forChild());
  }
}

routing中配置的是模块的组件路由表,控制页面跳转,我们还需要根据路由生成一个菜单导航,因此还需要配置菜单路由表

3、配置Abp菜单路由表

菜单路由的配置是不直接依赖于页面组件的,可以将其定义在config子模块中,这样根模块中就可以从文件管理的config子模块中加载菜单,而文件管理主模块使用LazyLoad懒加载模式,这样程序打包后主文件会小一些;这很重要,如果直接在文件管理主模块中配置路由菜单,那么根模块就不能懒加载文件模块,因为菜单必须在应用程序初始化时生成,打包后会将整个文件管理模块打包到主文件;另外如果模块有公共的组件或服务需要在根模块引用,那么最好也放到一个子模块中,否则懒加载就没意义了

添加文件管理config子模块步骤如下:

  • projects\file-management目录下添加config目录,在其中添加ng-package.json文件,内容如下:
    {
      "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
      "dest": "../../dist/file-management/config",
      "lib": {
        "entryFile": "src/public-api.ts"
      }
    }
    
  • 在config目录下添加src\enums目录,在其中添加route-names.ts,配置菜单枚举常量
    export const enum eFileManagementRouteNames {
      FileManagement = 'FileManagement::Menu:FileManagement',
      PublicFiles = 'FileManagement::Menu:PublicFiles',
      MyFiles = 'FileManagement::Menu:MyFiles',
      AppMenu = '::Menu:AppMenu'
    }
    
  • 在src目录下添加providers目录,在其中添加route.provider.ts,配置路由菜单项
    import { eLayoutType, RoutesService } from '@abp/ng.core';
    import { APP_INITIALIZER } from '@angular/core';
    import { eFileManagementRouteNames } from '../enums/route-names';
    
    export const FILE_MANAGEMENT_ROUTE_PROVIDERS = [
      {
        provide: APP_INITIALIZER,
        useFactory: configureRoutes,
        deps: [RoutesService],
        multi: true,
      },
    ];
    
    export function configureRoutes(routesService: RoutesService) {
      return () => {
        routesService.add([
          {
            path: '/file-management',
            name: eFileManagementRouteNames.FileManagement,
            iconClass: 'cil-file',
            layout: eLayoutType.application,
            requiredPolicy: 'FileManagement.MyFiles || FileManagement.ProjectResources',
            order: 50,
          },
          {
            path: '/file-management/public-files',
            name: eFileManagementRouteNames.PublicFiles,
            parentName: eFileManagementRouteNames.FileManagement,
            requiredPolicy: 'FileManagement.PublicFiles',
            layout: eLayoutType.application,
            order: 1,
          },
          {
            path: '/file-management/my-files',
            name: eFileManagementRouteNames.MyFiles,
            parentName: eFileManagementRouteNames.FileManagement,
            requiredPolicy: 'FileManagement.MyFiles',
            layout: eLayoutType.application,
            order: 2,
          },
        ]);
      };
    }
    
  • 在src目录下添加file-management-config.module.ts文件,内容如下:
    import { CoreModule } from '@abp/ng.core';
    import { ModuleWithProviders, NgModule } from '@angular/core';
    import { FILE_MANAGEMENT_ROUTE_PROVIDERS } from './providers/route.provider';
    
    @NgModule({
      imports: [CoreModule],
      declarations: [],
      exports: [],
    })
    export class FileManagementConfigModule {
      // 在跟模块中import时调用此方法,将模块的配置提供给根模块进行初始化路由菜单
      static forRoot(): ModuleWithProviders<FileManagementConfigModule> {
        return {
          ngModule: FileManagementConfigModule,
          providers: [FILE_MANAGEMENT_ROUTE_PROVIDERS],
        };
      }
    }
    
  • 在src目录下添加public-api.ts文件,内容如下:
    export * from './enums/route-names';
    export * from './file-management-config.module';
    export * from './providers/route.provider';
    
  •  在终端执行如下命令打包模块
    ng build file-management --configuration production

    最好在package.json文件中添加命令脚本,如下:

      "scripts": {
        ...
        "build:files": "ng build file-management --configuration production",
        ...
      },

    这样以后打包只要执行 yarn build:files就可以了,打包完成后你可以把它发布到npm服务器上

4、在根模块中引入文件管理模块

在引入文件管理模块之前,需要先打包, 

在app.module.ts中添加如下内容:

import { FileManagementConfigModule } from 'file-management/config';
...
@NgModule({
  imports: [
    ...
    ...
    FileManagementConfigModule.forRoot(), // 文件管理模块配置子模块
  ],
  ...

接着在app-routing.module.ts添加模块懒加载路由如下:

const routes: Routes = [
  ...
  ...
  {
    path: 'file-management',
    loadChildren: () =>
      import('file-management').then(m => m.FileManagementModule.forLazy()),
  },
];

此处import模块参数的配置来源于tsconfig.json中的paths配置

      

 它指向打包后的文件目录,因此必须打包后才能引入

 在终端执行命令npm start 启动项目,可以看到模块菜单已经启用:

 现在页面还是空的,我们需要为其添加内容,在这之前我们还需要生成webapi访问的客户端代理服务

5、使用abp cli生成客户端代理的代码

生成客户端代理,直接在vscode终端执行 abp generate-proxy即可,但是这样生成的代码都是根模块中的,即src/app目录下;既然我们将文件管理封装为独立模块,就需要将客户端代理的代码生成在文件管理模块中,需要的操作步骤如下:

首先,找到aspnetcore后端文件管理模块的MyCompany.FileManagement.HttpApi项目,依次打开MyFilesController和PublicFilesController文件,为类添加如下属性装饰:

    [RemoteService(Name = FileManagementRemoteServiceConsts.RemoteServiceName)]
    [Area(FileManagementRemoteServiceConsts.ModuleName)]
    ...
    public class ...

然后,打开angular前端根模块中environments\environments.ts文件,添加模块api配置

  apis: {
    ...
    FileManagement: {
      // api的地址,不配置时使用default中配置
      url: 'https://localhost:44358',
      // 与后端根命名空间对应,生成客户端代理时不生成此命名空间目录
      rootNamespace: 'MyCompany.FileManagement',
    }
  },

接着打开package.json,在脚本中添加生成客户端代理的指令(注意abp5.0.0正式版后,指令有所变化,参考CLI | Documentation Center | ABP.IO):

"scripts": {
    ...
    ...
    "gen:files": "abp generate-proxy -m fileManagement -a FileManagement -t file-management",
    ...
  },
  • --module 或 -m: 指定要为其生成代理的后端模块的名称. 默认值: app,在本示例中,此值为controller属性装饰[Area(FileManagementRemoteServiceConsts.ModuleName)]中ModuleName对应的值,即fileManagement
  • --api-name 或 -a: 在 /src/environments/environment.ts 中定义的API端点名称。. 默认值: default。在本示例中,此值为environments.ts中配置的api名称FileManagement
  • --target 或 -t: 指定放置生成的代码的Angular项目名称. 默认值: defaultProject。本实例中此值为模块的项目名称,即file-management

 最后执行如下指令生成客户端代理:

yarn gen:files

生成的代码文件如下:

 6、编写文件管理模块组件代码

这部分代码比较多,篇幅有限,就不贴在这,可在文章结尾找到源码下载查看

7、多语言资源

主要涉及到文件模块组件页面、菜单显示,以及后台权限部分的多语言资源,整理好后添加到后台文件模块的MyCompany.FileManagement.Domain.Shared\Localization\FileManagement中的资源文件中,中文资源文件zh-Hans.json如下:

{
  "culture": "zh-Hans",
  "texts": {
    "Menu:FileManagement": "文件管理",
    "Menu:PublicFiles": "公共文件",
    "Menu:MyFiles": "我的文件",
    "Files:CurrentFolder": "当前目录",
    "Files:CreateDir": "新建目录",
    "Files:UploadFiles": "上传文件",
    "Files:GoUpFolder": "上级目录",
    "Files:Filter": "筛选",
    "Files:Actions": "操作",
    "Files:ReName": "重命名",
    "Files:Delete": "删除",
    "Files:Download": "下载",
    "Files:Size": "文件大小",
    "Files:LastWriteTime": "最后修改时间",
    "Files:Save": "保存",
    "Files:Name": "文件名",
    "Files:UploadDesc": "拖拽文件到这里,或者",
    "Files:UploadDescEnd": "上传。",
    "Files:Browse": "浏览文件",
    "Files:DeleteDirComfirm": "目录<strong>[{0}]</strong>以及目录中的内容都将被删除. 你要继续吗?",
    "Files:DeleteFileComfirm": "文件<strong>[{0}]</strong>将被删除. 你要继续吗?"
  }
}

7、编译运行

编译文件管理模块

yarn build:files

执行npm start 启动项目,效果如下:

 上传文件:

 本章源码:Abp Vnext中使用Minio打造文件管理模块

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沝林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值