技术文章

当前位置:首页>帮助手册>技术文章

如何在Angular应用中集成O2OA

时间:2022-02-23   
内容导读

本篇围绕把 Angular 应用从平台自带 web 服务中独立出来、自行搭建前端服务的做法展开。文中先说明环境准备,用命令行工具创建应用,再把服务端的脚本目录拷入项目并引入全局脚本。随后调整配置文件中的中心服务器与应用服务器地址,解决登录凭据的跨域传递问题。接着创建展现待办与信息视图的组件,挂载到根组件后编译运行。若把静态资源放入子目录,还需同步修改打包输出路径与脚本中的基础路径。

angular.jpg

上一章节中,我们介绍了在 O2OA 中使用 Angular 开发应用,编译后在 O2服务器的 webServer 中运行。如果您考虑完全脱离 O2的 web 服务器、自己搭建 web 服务器,就请阅读本章。

本例仍使用 Angular CLI 搭建应用,实现一个简单门户,用于显示当前用户的最新待办、通过 O2视图展现信息类文档,以及启动指定流程和发布文档等功能。效果如下:

待办.png

版本要求

本文适用于如下版本:

使用 ng version 命令查看当前版本:

version.png

环境搭建

我们使用 Angular CLI 工具搭建 Angular 开发环境,首先需要安装 Node.js 和 npm 包管理器,然后通过以下命令安装 Angular CLI:

npm install -g @angular/cli

以上命令全局安装了 Angular CLI,然后通过以下命令查看相关版本信息:

ng version

可以通过以下命令查看 Angular CLI 的更多命令:

ng help

创建 Angular 应用

创建一个新的工作空间和初始入门应用:

运行 CLI 命令 ng new,并以 my-app 作为名称参数,如下所示:

ng new angular-app

ng new 命令会提示需要将哪些特性包含在初始应用中,按 Enter 或 Return 键接受默认值。

Angular CLI 会安装所需的 Angular npm 包及其它依赖包,这一过程可能需要几分钟。

此时已创建名为 angular-app 的应用。

命令窗口.png

创建完成后生成的目录如下:

目录.png

添加 O2脚本引入

本步骤需要在 src 目录下创建一个 o2目录(目录名称可任意修改,后续相关引用和配置同步修改即可),并将 O2服务器的 webServer 下的所有文件夹拷贝到 src/o2目录下:

目录.png

在 src/index.html 的 head 中添加 O2脚本引入:

脚本.png

修改 public/x_desktop/res/config/config.json 文件:

{
	"center": [
    {
      "port": "20030",		//O2服务器中心服务器端口
      "host": "develop.o2oa.net"	//O2服务器中心服务器Host
    }
  ],
  "applicationServer": {
    "host": "develop.o2oa.net"	//O2应用服务器Host
  },
  "sessionStorageEnable": true,
  "initManagerChanged": true,
  "initManagerName": "",
	...
}

此文件主要修改两部分内容:

1、center 部分:修改为要访问的 O2中心服务器地址和端口;

2、applicationServer 部分:修改为要访问的 O2应用服务器地址;如果没有 applicationServer,就添加一项。集群环境下可配置应用服务器负载地址;

3、sessionStorageEnable 设置为 true,通过 sessionStorage 传递登录后的 token,解决跨域 cookies 传递问题。(生产环境出于安全性考虑,一般情况下不要设置此项)

为便于后续引用,在 src 下创建 o2.js,并添加以下代码:

let o2 = window.o2;
let layout = window.layout;
export {o2, layout};

  修改 src/main.ts 文件如下:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

//引入o2的layout对象
import { layout } from './o2';

if (environment.production) {
  enableProdMode();
}

//当o2载入完成后启动Angular Module
layout.addReady(() => {
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
  }
);

此后修改和创建组件的过程,与上一章完全相同(直到编译运行之前)。

添加组件(component)

需要实现展现待办和展现信息两部分内容,因此需要添加两个组件。通过以下 CLI 命令,Angular-CLI 可以自动帮我们创建好组件。

ng generate component o2-task
ng generate component o2-info

以上两条命令创建了两个组件:

o2-task:用于展现待办,并通过一个按钮启动指定流程;

o2-info:用于通过 O2视图展现信息,并通过一个按钮创建新文档。

创建完组件后,可以看到在 app 目录下新建了两个目录:o2-task 和 o2-info,每个目录下分别有以下文件:

*.component.css

组件样式文件

*.component.html

组件模板文件

*.component.spec.ts

组件的单元测试文件

*.component.ts

组件脚本文件

组件脚本文件.png

再打开 src/app.module.ts 文件,可以看到 Angular 已经为我们添加了新建组件的引用:

组件2.png

在 app.component 组件中使用 o2-task 和 o2-info

现在需要修改 app.component 组件以使用新建的组件,将 src/app/app.component.ts 修改为如下内容:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  //仅修改了此处的title
  title = 'Angular With O2OA';
}

  修改 src/app/app.component.html 为如下内容:

<div class="toolbar">{{title}}</div>
<div class="content">
  <app-o2-task></app-o2-task>
  <app-o2-info></app-o2-info>
</div>

  此处我们删除了原来的所有内容,并增加了<app-o2-task></app-o2-task>;和<app-o2-info></app-o2-info>;用来渲染 o2-task 和 o2-info 组件。

  修改 src/app/app.component.css 为如下内容:

.toolbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 60px;
  line-height: 60px;
  align-items: center;
  text-align: center;
  background-color: #1976d2;
  color: white;
  font-weight: 600;
  font-size: 32px;
}
.content {
  margin: 80px auto 0 auto;
  width: 90%;
  overflow: hidden;
}

修改 o2-task 组件

接着修改 o2-task 组件,将 src/app/o2-task/o2-task.component.css 文件修改为如下内容:

.taskContent{
  height: 500px;
  width: 48%;
  float: left;
  padding: 10px;
  border: 1px solid #eeeeee;
}
.taskItem {
  height: 40px;
  line-height: 40px;
  color: #666666;
  cursor: pointer;
  border-bottom: 1px solid #eeeeee;
}
.taskTitle {
  height: 50px;
  line-height: 50px;
  font-weight: bold;
  font-size: 18px;
  color: #333333;
  padding: 0 10px;
  background-color: #eeeeee;
  margin-bottom: 5px;
}
button {
  padding: 3px 20px;
  text-align: center;
  background: #0f81cc;
  border: 1px solid #ffffff;
  margin-top: 8px;
  color: #ffffff;
  font-size: 18px;
  float: right;
  cursor: pointer;
}

修改 src/app/o2-task/o2-task.component.html 文件如下:

<div class="taskContent">
  <div class="taskTitle">
    <span>{{title}}</span>
		<!--发起流程按钮,绑定click事件到组件的startProcess方法-->
    <button (click)="startProcess()">发起流程</button>
  </div>
  
	<!--通过ngfor循环tasks,展现每一条待办-->
  <div *ngFor="let task of tasks">
    <div class="taskItem" (click)="openTask(task.work)">
      <a [title]="task.title">
        {{ task.title || "无标题" }}
      </a>
    </div>
  </div>
</div>

修改 src/app/o2-task/o2-task.component.ts 文件如下:

import { Component, OnInit } from '@angular/core';
//引入o2对象
import {o2} from "../../o2";

@Component({
  //组件的选择器,对应我们在app.component.html模板中的<app-o2-task>
  selector: 'app-o2-task',
  templateUrl: './o2-task.component.html',
  styleUrls: ['./o2-task.component.css']
})
export class O2TaskComponent implements OnInit {
  tasks = [];
  title = "我的待办";

  constructor() {}

  ngOnInit(): void {
		//通过调用O2平台的服务,获取当前用户的前20条待办
    o2.Actions.load("x_processplatform_assemble_surface").TaskAction.V2ListPaging(1,20, {}, (json)=>{
      this.tasks = json.data;
    });
  }
  startProcess() {
    //通过o2.env对象启动流程
    //o2.env对象即是在O2门户页面的脚本中的this指向,可以使用其方法。
    //请将“application-name”和“process-name”修改为您的流程应用名称和流程名
    o2.env.page.startProcess("application-name", "process-name");
  }
  openTask(id) {
    //通过o2.env对象打开待办
    o2.env.page.openWork(id);
  }
}

以上代码中,有关 Angular 的内容,请参考 Angular 的官方文档。

修改 o2-info 组件

接着修改 o2-task 组件,将 src/app/o2-task/o2-info.component.css 文件修改为如下内容:

.viewContent{
  height: 500px;
  width: 48%;
  float: right;
  padding: 10px;
  border: 1px solid #eeeeee;
}
.view {
  height: 460px;
}
.viewTitle {
  height: 50px;
  line-height: 50px;
  font-weight: bold;
  font-size: 18px;
  color: #333333;
  padding: 0 10px;
  background-color: #eeeeee;
  margin-bottom: 5px;
}
button {
  padding: 3px 20px;
  text-align: center;
  background: #0f81cc;
  border: 1px solid #ffffff;
  margin-top: 8px;
  color: #ffffff;
  font-size: 18px;
  float: right;
  cursor: pointer;
}

修改 src/app/o2-task/o2-task.component.html 文件如下:

<div class="viewContent">
  <div class="viewTitle">
    <span>{{title}}</span>
    <button (click)="createDocument()">新建信息</button>
  </div>
  <!--用于视图展现的dom对象-->
  <div #viewContent  class="view"></div>
</div>

修改 src/app/o2-task/o2-task.component.ts 文件如下:

import {Component, ElementRef, OnInit,ViewChild} from '@angular/core';
//引入o2对象
import {o2} from "../../o2";

@Component({
  //组件的选择器,对应我们在app.component.html模板中的<app-o2-info>
  selector: 'app-o2-info',
  templateUrl: './o2-info.component.html',
  styleUrls: ['./o2-info.component.css']
})
export class O2InfoComponent implements OnInit {
  //要展现的视图信息,我们必须在O2平台创建好名为“内容管理数据”的数据应用和“所有信息”视图
  //修改此值,可显示不同的视图
  viewApp="内容管理数据";
  viewName="所有信息";
  //获取展现视图的原生Dom对象
  @ViewChild("viewContent") content: ElementRef;
  title = "最新信息";

  constructor() {
    //新建一个Viewer对象,用于展现指定的视图
    //将Viewer展现挂载到viewContentst的原生DOM对象上,就是模板中的<div #viewContent  class="view"></div>
    o2.xDesktop.requireApp("query.Query", "Viewer", function(){
      new o2.xApplication.query.Query.Viewer(this.content.nativeElement, {
        "application": this.viewApp,
        "viewName": this.viewName,
      });
    }.bind(this));
  }

  ngOnInit(): void {
  }

  createDocument(){
    //通过o2.env对象新建内容管理文档
    //o2.env对象即是在O2门户页面的脚本中的this指向,可以使用其方法。
    //createDocument方法创建内容管理文档,可传入栏目和分类参数,请参考API文档
    o2.env.page.createDocument();
  }
}

以上代码中,有关 Angular 的内容,请参考 Angular 的官方文档。

编译并运行

完成上述开发工作后,还需要几项配置,即可编译并运行我们的应用。

  修改 angular.json 文件,找到对应应用下的 architect.build.options,assets,增加一个元素:

{"glob": "**/*", "input": "src/o2/", "output": "/"}

该行代码表示:将 o2目录下的所有文件在编译时输出到编译目录的根目录下。(我们建议将 o2的所有文件编译到根目录下,否则需要修改部分静态文件的引用,这部分内容将在后面介绍)。

接着,我们可以运行开发服务器了,使用以下任一命令启动开发服务器:

ng serve --open

  Angular 会为我们编译代码,并启动一个 web 服务器,默认端口4200,并自动打开默认浏览器,运行我们的应用,就可以看到和上一章相同的效果了。(Angular 默认不支持 IE 浏览器,可以通过配置 src/polyfills.ts、browserslist、tsconfig.json 等文件来生成兼容的版本,但从 V10开始 Angular 已经放弃了对 IE9、10和 IE Mobile 的支持。详见Angular 官方文档。)

如果尚未登录服务器,会出现登录页面,登录后即可看到实现的效果。

  登陆后:

待办.png

接下来可以继续修改代码,每次修改保存后,Angular 会自动编译并刷新浏览器,从而及时查看修改效果。

开发完成后,可使用命令:

ng build

Angular 会将所有代码编译到 dist 目录下,之后即可将 dist 中的内容部署到任意 web 服务器上。

更改 O2文件路径

前面我们在 angular.json 文件中将输出路径配置为根目录,这是我们建议的方式;但如果确实需要将 O2文件放置到其他目录,则需要完成以下几步操作:

1、在 angular.json 文件中将刚才的 assets 配置修改为:

//假设我们将O2文件全部放置到/o2目录下
{"glob": "**/*", "input": "src/o2/", "output": "/o2/"}

  2、修改 src/o2.js 文件

let o2 = window.o2;
let layout = window.layout;
//修改o2的base属性
o2.base = "/o2/";
export {o2, layout};

然后即可正常编译和运行应用。


总结

  至此,我们将三个目前最主流的前端框架于 O2OA 的集成开发都介绍完了,其实还是万变不离其宗,正确的应用到 O2中的全局对象 o2和 layout,您就可以干任何事了。如果您使用其他的前端框架,也可以参考此系列文章中的方法。

希望本系列文章对您有所帮助,感谢您对 O2OA 的关注!

相关问题讨论

在 Vue 应用中集成 O2OA 照着文档配置完之后报错

至此,我们将三个目前最主流的前端框架于 O2OA 的集成开发都介绍完了,其实还是万变不离其宗,正确的应用到 O2中的全局对象 o2和 layout,您就可以干任何事了。

查看原帖讨论 · 20,943 次浏览

钉钉集成 O2OA 的 H5应用不生效问题

至此,我们将三个目前最主流的前端框架于 O2OA 的集成开发都介绍完了,其实还是万变不离其宗,正确的应用到 O2中的全局对象 o2和 layout,您就可以干任何事了。

查看原帖讨论 · 19,369 次浏览

集成企业微信后,在企业微信应用中审批流程,提交后一直 loading

在上一个章节中,我们介绍了在 O2OA 中使用 Angular 开发应用,编译后在 O2服务器的 webServer 中运行。

查看原帖讨论 · 9,309 次浏览

相关内容

O2OA 翱途 企业应用开发平台

兰德网络O2OA平台软件

开源、自主可控的协同办公底座

研发与运营

纵横翱途(杭州)科技有限公司

企业级协同应用 · 工作流引擎 · AI 智能体

www.o2oa.net | 400-888-0545

上一篇:O2OA 平台涉密信息化系统建设-如何使用三员管理

下一篇:开源OA办公:使用Promise处理表单异步