对于医疗项目框架的讲述——前端部分

只讲组织结构和如何使用,如何实现可以看源码。不涉及怎样使用 Angular 以及其他相关技术

目录结构

  • path-to-your-project/src/app/components:存储我定义的一些可复用组件,作用根据名称一目了然;
  • path-to-your-project/src/app/container:存储网站主业务框架
  • path-to-your-project/src/app/components:存储我定义的一些可复用的指令
  • path-to-your-project/src/app/interceptors:存储我定义的一些拦截器
  • path-to-your-project/src/app/interfaces:存储我定义的一些接口
  • path-to-your-project/src/app/pipes:存储我定义的一些管道
  • path-to-your-project/src/app/service:存储我定义的一些服务
  • path-to-your-project/src/app/utils:存储我定义的一些杂项
  • path-to-your-project/src/app/views:存储我定义的一些视图组件

界面部分

  • 左侧导航菜单

    全功能列表存在如下文件中:
    path-to-your-project/src/app/_nav.ts
    TIPS:
    • 与原框架相比,NavData 接口增加 pcode?: string;pcode 对应于后台权限表中的某个权限的权限代码,登录时后台会以正则表达式字面量的形式返回当前用户所具有的所有权限,我会 test 这个 RegExp 与这些 pcode,true 则添加。如果某元素不含有 pcode 这个 property,则默认添加;
    • 只支持一层 children 嵌套,更深层次的嵌套不被解析;
    • icon 这个 property 是定义导航 item 的左侧图标的,原模板已经引入了一些图标,我有根据具体功能,新引入了几个阿里出品的开源图标,可根据具体业务功能类型添加。
  • 主区域 TAB 页

    Tab 页单击选中,双击关闭,Tab头可拖动,Tab 页最少会留一个“新标签页”。

路由设置

path-to-your-project/src/app/app.routing.ts

...
children: [
      {
        path: 'new-tab',
        component: NewTabComponent,
        data: {
          title: '新标签页',
          cid: '041FF088415C6BBF458F9475FEE79986'
        }
      },
      {
        path: 'system',
        canLoad: [CanLoadGuard],
        data: {pcode: '001'},
        loadChildren: () => import('./views/system/system.module').then(m => m.SystemModule)
      }
    ]
...

path-to-your-project/app/views/system/system-routing.module.ts

...
children: [
    {
      path: 'people',
      component: PeopleComponent,
      data: {
        title: '自然人管理',
        cid: '88C9EF4BD6306E26D3D2DA01FC2BB0FE',
        pcode: '001001',
        reuse: true
      }
    }]
...

我写的一些公共功能的使用

基本上都可以在“自然人管理”这个例子下找到使用方法(要使用,先引入相关模块)

  • datatable 是一个组件,相关设置通过属性传值,组件选择器与接口格式如下:
    path-to-your-project/src/app/views/system/people/people.component.html
<app-rd-datatable #tb [rdTHead]="thead" [rdTbConfig]="tbConfig" (selectedRows)="setSelectedRows($event)"></app-rd-datatable>

path-to-your-project/src/app/views/system/people/people.component.ts

thead: Array<Array<RdDatatableThTd>> = [
    [
      {content: '姓名', style: {width: '15%'}},
      {content: '性别', style: {width: '10%'}},
      {content: '电话', style: {width: '15%'}},
      {content: '电子邮件', style: {width: '20%'}},
      {content: '身份证', style: {width: '25%'}},
      {content: '是否冻结', style: {width: '15%'}}
    ]
  ];
  tbConfig: RdDatatableConf = {
    url: 'system/people',
    hasCheckBox: true,
    rowsPrefetch: 100,
    rowsPerPage: 5,
    rowsTimes: [1, 2, 4, 6]
  };
  • datalist-validator 是一个指令,当表单中有长列表形式的域需要校验时,往往可以用到这个指令,如:
    path-to-your-project/src/app/views/system/people/people.component.html
<input type="text" class="form-control" id="country" list="psy" formControlName="country" placeholder="请选择国家" [appRdDatalist]="countrys4V"/>

path-to-your-project/src/app/views/system/people/people.component.ts

this.countrys4V = this.countrys.map(e => e.countryName);
  • http-interceptor 现在里面写了做四种功能的拦截,仅仅是提一下:
    • 多线路选择与格式化请求的 URL ;
    • 填充必要 HEADERS;
    • 会话超时提示用户重新登录;
    • 打印请求日志;
    • (TODO) 本地数据源代理。
  • interfaces 里写了一堆接口,根据名字很容易看出功能。
  • pipes 里写了一个管道,用来在 datatable 显示的时候,自动加入 checkbox 使用。
  • utils 里写了两个 snippets,一个用于依赖注入的 Token 用于在请求拦截器里依赖注入备选URL数组,全局配置信息和响应式表单校验器。
  • login 登录页的表单是用了模板驱动表单,另外还有上面提到的响应式表单(自然人管理里用到)有示例。
  • services 一般都是根注入,这些都是类注入,关于非类注入,上面有一个全局配置信息的对象注入:
    • can-load.guard 路由守卫,在上面配置路由时出现过,根据用户权限,判断应否 load 某模块,这只是其中一个守卫,另外还应有判断应否 Active 等的守卫;
    • rd-auth.service判断权限使用,包括判断用户是否登录和是否具有其试图触发路由的权限;
    • rd-browser-storage.service 根据 Angular 预置 Token,使用的是 LocalStorage 方式的存储,现在存了选举出的URL、用户权限正则字面量和用户是否登录。
    • rd-http.service 原则支持 RESTful,支持超时、重试、防抖等功能。支持带状态反馈的文件上传功能。
    • rd-message.service 一个简单日志打印服务,可扩充至复杂日志系统。
    • rd-modal.service Modal 功能,使用方法如下:
...
this.rdModal.onHidden().subscribe(reason => {
  switch (reason) {
    case 'secondLogin':
      this.login(true);
      break;
    case 'loginFailed':
      this.formData.password = '';
      break;
  }
});
...
const modalOptions = {
  animated: true,
  initialState: {
    title: '用户登录提示',
    content: '此用户已在别处登录,继续登录会将其踢下线,是否继续?',
    btnSecondary: '否',
    btnPrimary: '是',
    reasonPositive: 'secondLogin',
    type: 'danger'
  },
  class: 'modal-danger'
};
this.rdModal.show(modalOptions);
...
  • rd-reuse-strategy 路由策略
  • rd-ws.service WebSocket
    • 支持重连;
    • 支持心跳;
    • 支持恶意请求或超时时的策略;