O2OA開源免費開發平臺:在O2門戶頁面中使用React(二)

本章我們介紹使用React的Create React App工具,在O2平臺中創建React應用。在本例中,我們將列示當前用戶的前20條待辦,點擊標題打開待辦;並通過點擊按鈕啓動流程和打開主頁。

版本要求

本文適用於如下版本:

O2OA版本要求:5.1及以上版本;

React版本:本文撰寫時,react版本是16.13.1。(更低的版本未經驗證)

前提

開發端安裝了Node.js,Node >= 8.10, npm >= 5.6

有一臺O2服務器

使用合適的開發工具:WebStorm、VSCode、Atom等(本例使用WebStorm)

創建React應用

  您可以使用WebStorm創建一個新的React App,如下圖:

或者創建一個空項目,然後使用以下命令創建React應用:

npx create-react-app my-app

cd my-app

創建後目錄結構如下:

添加O2腳本引入

在public/index.html的head中添加O2腳本引入:

<script src="../o2_core/bundle.js"></script>

修改src/index.js文件如下:

import React from 'react';

import ReactDOM from 'react-dom';

import './index.css';

import App from './App';

//定義O2平臺對象

let layout = window.layout;

let o2 = window.o2;

//在O2平臺腳本載入完成後執行

layout.addReady(function(){

    layout.app = true;

    //通過平臺服務,獲取當前用戶的前20條待辦(可通過http://your-server:20030/x_program_center/jest/list.html查詢平臺接口服務)

    o2.Actions.load("x_processplatform_assemble_surface").TaskAction.V2ListPaging(1,20, {}, function(json){

        //React渲染App組件

        ReactDOM.render(

            <React.StrictMode>

                <App value={json.count} data={json.data}></App>

            </React.StrictMode>,

            document.getElementById('root')

        );

    });

});

其中:

let layout = window.layout;

let o2 = window.o2;

獲取兩個O2的全局對象。

layout.addReady 方法會在O2載入完成後執行回調方法。

o2.Actions.load 方法可以調用平臺的Restful服務。

修改App組件

先修改src/App.css樣式文件,拷貝以下代碼:

.App {

  padding: 20px;

  margin: 20px;

}

.App-header {

  padding: 5px 10px;

  background: #0f81cc;

  font-size: 18px;

  color: #ffffff;

}

.o2-tasklist {

  padding: 10px;

  background: #f3f3f3;

  font-size: 18px;

}

.o2-task {

  line-height: 30px;

  height: 30px;

  cursor: pointer;

}

.o2-button {

  padding: 10px 20px;

  text-align: center;

  background: #0f81cc;

  margin-top: 10px;

  color: #ffffff;

  font-size: 18px;

  float: left;

  margin-right: 20px;

  cursor: pointer;

}

修改src/App.js文件如下:

import React from 'react';

import './App.css';

function App(props) {

    function openHomepage(){

            //通過O2全局對象layout的openApplication方法打開主頁"Homepage"

        window.layout.openApplication(null,"Homepage")

    }

    function openTask(id){

        //通過O2全局對象layout的openApplication方法打開待辦

        window.layout.openApplication(null,"process.Work", {"workId": id});

    }

    function startProcess(){

        //通過o2.env對象啓動流程

        //o2.env對象即是在O2門戶頁面的腳本中的this指向,可以使用其方法。

        //請將“application-name”和“process-name”修改爲您的流程應用名稱和流程名

        window.o2.env.page.startProcess("application-name", "process-name");

    }

    function listTask(){

        let list = [];

        props.data.each(function(d){

            list.push(<div className="o2-task" onClick={()=>{openTask(d.work)}}>{d.title || "無標題"}</div>);

        });

        return list;

    }

    return (

        <div className="App">

            <header className="App-header">

                <p>

                    您有{props.value}個待辦

                </p>

            </header>

            <div className="o2-tasklist">

                {listTask()}

            </div>

            <div className="o2-button" onClick={startProcess}>點擊此處啓動流程</div>

            <div className="o2-button" onClick={openHomepage}>點擊此處打開O2首頁</div>

        </div>

    );

}

export default App;

  上述代碼創建了一個React組件,列示了待辦列表,並創建兩個div,點擊後分別啓動指定的流程,打開主頁。

其中用到兩個全局對象:o2和layout。我們在Node.Js環境中開發,o2的對象是通過<script>標籤引入的,由於全局環境不同,直接使用layout和o2訪問對象會引起編譯錯誤,所以我們使用window.layout和window.o2來訪問。

  當然,我們可以通過import來解決這個問題,創建一個src/o2.js文件,添加以下代碼:

let o2 = window.o2;

let layout = window.layout;

export {o2, layout};

  然後在需要使用o2對象的組件中,使用以下代碼引入:

import {o2, layout} from './o2.js';

  然後就可以直接使用layout和o2對象了。

  App.js中,我們使用了o2.env對象,這個對象和在門戶頁面腳本中的this指向一致,可以調用除了與門戶頁面組件相關方法以外的各種方法,如:o2.env.page.openWork、o2.env.inculde、o2.env.confirm、o2.env.page.startProcess等,詳細內容可以參考API文檔。

編譯並運行

  我們完成了上述開發工作,就可以編譯並運行我們的應用了。

  由於我們要將react應用放到O2的web服務器的目錄下,而非根路徑下,所以我們需要在package.json中增加homepage字段,設置值爲".":

{

    ...

    "homepage": ".",

  ...

}

  在當前項目路徑下執行以下命令:

npm run build

  React會在將所有的代碼編譯到build目錄,如下圖:

接着將build目錄部署到O2服務器的webServer下,並重命名爲“react-app”。然後通過瀏覽器訪問:http://your-server/react-app。

如果您未登錄到服務器,會出現登錄頁面,登錄後就可以看到登錄人的待辦列表,並可以啓動流程了。

登錄後:

  如果您將您的應用部署到服務器的其他目錄,如custom/react-app下,那麼您需要在src/index.js文件中增加一行代碼:o2.base = "../";

import React from 'react';

import ReactDOM from 'react-dom';

import './index.css';

import App from './App';

//定義O2平臺對象

let layout = window.layout;

let o2 = window.o2;

//設置o2目錄

o2.base = "../";

//在O2平臺腳本載入完成後執行

layout.addReady(function(){

    layout.app = true;

    //通過平臺服務,獲取當前用戶的前20條待辦(可通過http://your-server:20030/x_program_center/jest/list.html查詢平臺接口服務)

    o2.Actions.load("x_processplatform_assemble_surface").TaskAction.V2ListPaging(1,20, {}, function(json){

        //React渲染App組件

        ReactDOM.render(

            <React.StrictMode>

                <App value={json.count} data={json.data}></App>

            </React.StrictMode>,

            document.getElementById('root')

        );

    });

});

至此,我們已經可以在O2平臺的框架下,使用React開發應用了。

開發模式優化

  雖然我們可以使用React開發O2應用,但上述模式在我們每次修改代碼後,需要運行build命令,並手工上傳到服務器,在開發比較複雜的應用時,還是比較影響效率的。下面價紹兩種方式來應對這種情況。

本地運行O2服務器

  您可以在本地運行服務器,然後直接在服務器的webServer目錄下創建項目。然後您必須修改React的build路徑到正確的路徑。其中一個方法爲:

  在項目目錄下運行以下命令:

npm run eject

  此命令會暴露React應用的隱藏配置項,我們找到config/paths.js,找到“appBuild”並修改之:appBuild: resolveApp('../react-app')

module.exports = {

  dotenv: resolveApp('.env'),

  appPath: resolveApp('.'),

  appBuild: resolveApp('../react-app'),

  appPublic: resolveApp('public'),

  appHtml: resolveApp('public/index.html'),

  ...

};

  然後每次運行npm run build後,React會將編譯後的應用生成在webServer/react-app/目錄下,我們直接通過http://locahost/react-app就可以查看運行結果。

通過部署工具自動化部署到遠程服務器

  當然,爲了節省我們部署遠程服務器的時間,我們可以使用javascript打包工具,自動完成這個過程,這裏我們使用gulp,通過ftp或sftp來進行自動化部署到遠程服務器。

  這種方式不需要您本地運行O2服務器,但您必須有一臺遠程服務器,並可以通過ftp或sftp連接到服務器的webServer。

  按上述方式創建好應用,然後我們安裝gulp環境:

npm i -g gulp-cli

  安裝gulp以及gulp相關插件:

npm i gulp gulp-ftp gulp-sftp-up4 gulp-run -save-dev

  在項目根目錄新建gulpfile.js文件:

var gulp = require('gulp'),

    ftp = require('gulp-ftp'),

    sftp = require('gulp-sftp-up4'),

    run = require('gulp-run');

//根據您的實際服務器修改

var options = {

    'build': 'build',

    'host': 'o2server服務器',

    'user': 'sftp user',

    'pass': 'sftp password',

    "port": 22,

    "remotePath": "/data/o2server/servers/webServer/react-app"

};

//sftp任務

function upload_sftp(){

    var build = "build/**/*";

    return gulp.src(build)

        .pipe(sftp({

            host: options.host,

            user: options.user || 'anonymous',

            pass: options.pass || null,

            port: options.port || 22,

            remotePath: (options.remotePath || '/')

        }));

}

//ftp任務

function upload_ftp(){

    var build = "build/**/*";

    return gulp.src(build)

        .pipe(ftp({

            host: options.host,

            user: options.user || 'anonymous',

            pass: options.pass || null,

            port: options.port || 21,

            remotePath: (options.remotePath || '/')

        }));

}

//運行React build

function build_react() {

    return run('npm run build').exec();

}

輸出gulp任務,如果使用ftp,更換第二個任務爲upload_ftp

exports.build = gulp.series(build_react, upload_sftp);

  然後,當開發或修改代碼完成後,執行以下命令:

gulp build

  就可以自動編譯React應用,並上傳到O2服務器。通過瀏覽器訪問:http://your-server/react-app就可以看到結果。

  當然,這只是一個很簡單的例子,提供一個思路,您也可以使用其他您熟悉的工具實現相同或類似的功能。對於熟悉前端構建工具的用戶,實現更便捷的功能也不是難事,比如可以監控文件改動,實時部署,並刷新瀏覽器等。

總結

  本章給大家介紹了在O2平臺的框架內,使用React開發應用,並在O2服務器的webServer中運行了起來。它集成了O2平臺的所有功能,您也不需要處理類似登錄等一些繁瑣的事,而且可以方便的調用O2的後端服務。並提供了一些優化開發模式的思路。

  在大多數情況下,這樣的方式已經足夠滿足需要了,但如果您想要搭建自己的web服務器,並通過React作爲前端構建框架,那O2OA怎麼能夠與之集成呢?

  下回分解!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章