当前位置:首页 > 资讯 > 区块链新闻 > 正文

使用Hyperledger Composer和React.js构建保险应用程序-part2

发布:中币网   时间:2019-07-20 00:00:00   加入收藏 打赏

在本节中,我们将介绍如何通过RESTful API将HyperledgeFabric网络与Web应用程序集成,并使用react.js作为前端。本教程中构建的Web应用程序仅是保单持有者应用程序。 应用执行 在继续下面操作
在本节中,我们将介绍如何通过RESTful API将HyperledgeFabric网络与Web应用程序集成,并使用react.js作为前端。本教程中构建的Web应用程序仅是保单持有者应用程序。

应用执行

在继续下面操作步骤时,请按照第一节内容进行搭建后,再继续以下操作。

在insurance_application文件夹中,运行以下命令以创建保单持有人Web应用程序的框架:

npx create-react-app policyholder_app
cd policyholder_app

打开src/app.js并删除函数app返回中的代码,只需添加hello world作为占位符,这样app.js文件现在看起来如下

import React from 'react';
import './App.css';

function App() {
  return (
    <p>Hello World</p>
  );
}

export default App;
用以下内容替换src / App.css中的代码:

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: Arial, Helvetica, sans-serif;
  line-height: 1.4;
  background: #5B5B5B;
  font-family: monospace;
  font-size: 150%
}

a {
  color: #333;
  text-decoration: none;
  font-family: monospace;
}

.container {
  padding: 0 1rem;
}

.btn {
  display: inline-block;
  border: none;
  background: #555;
  color: #fff;
  padding: 7px 20px;
  cursor: pointer;
}

.btn:hover {
  background: #666;
}

React应用程序的默认端口号是3000,因此需要更改它以使其不与REST API端口冲突。要执行此操作,请将package.json的scripts部分更改为以下内容以创建端口3001:

 "scripts": {
    "start": "PORT=3001 react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

此外,我们需要在文件的底部添加一个代理,该代理将连接到Hyperledger Composer Network,因此只需在结束大括号之前添加以下行:

"proxy": "http://localhost:3000/"

在此文件夹中创建以下新文件夹src/components和以下新文件header.js。这将为我们的应用程序创建一个简单的标题,其中包含指向主页的链接:

import React, { Component } from 'react'
import { Link } from 'react-router-dom';

class Header extends Component {
  render() {
    return (
      <header style={headerStyle}>
        <h1 style={titleStyle}>Policyholder Blockchain Insurance</h1>
        <Link style={linkStyle} to="/">Home</Link>
      </header>
    )
  }
}

const headerStyle = {
  background: '#333',
  color: '#fff',
  textAlign: 'right',
  padding: '10px'
}

const linkStyle = {
  color: '#fff',
  textDecoration: 'none'

}

const titleStyle = {
  textAlign: 'left'
}

export default Header;

现在修改app.js,以便导入:

import { BrowserRouter as Router, Route } from 'react-router-dom';
import Header from './components/Header'

它实现了组件Header.js,如下所示:

<Router>
      <Header/>
</Router>

App.js现在看起来应该是这样的:

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';
import Header from './components/Header'

function App() {
  return (
    <Router>
      <Header/>
    </Router>
  );
}

export default App;

您可能需要安装react-router-dom:

npm install --save react-router-dom

此外,您可能还需要安装react-responsive-modal:

npm install react-responsive-modal --save

现在运行应用程序以通过从policyholder_app文件夹运行以下命令来测试所有工作正常

npm start

如果一切正常,应用程序应如下所示:

创建一个与Blockchain RESTful API连接的函数。使用以下代码创建src / Connection.js:

function search(query, cb) {
  return new Promise( (resolve,reject) => {
    return fetch(`api/${query}`, {
      accept: "application/json"
    })
      .then(parseJSON)
      .then(data => resolve(data));
  })

}

function create(type, data){
  return new Promise((resolve, reject) => {
    return fetch(`api/${type}`, {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      method: 'post',
      body: JSON.stringify(data)
    })
    .then(parseJSON)
    .then(() => resolve())
  })

}

function parseJSON(response) {
  return response.json();
}

const Connection = { search, create };
export default Connection;

在components文件夹中创建一个类组件Homepage.js. 这将显示主页上的所有组件:

import React, { Component } from 'react'

class Homepage extends Component {

  render() {

    return (
      <div>
      </div>);

  }
}

//PropTypes
Homepage.propTypes = {
}

export default Homepage

要导入用户资产并在主页上显示它们,需要另一个类组件。创建一个类组件usersassets.js并包含以下代码:

import React, { Component } from 'react'
import PropTypes from 'prop-types';
import UserAssetsItems from './UserAssetsItems'

class UserAssets extends Component {

    render() {

        return (
            <div>
                {this.props.assets.map((asset) => (
                    <UserAssetsItems key={asset.id} asset={asset}/>
                ))}
            </div>

        )}
}

//PropTypes
UserAssets.propTypes = {
    assets: PropTypes.array.isRequired
}

export default UserAssets

这将需要以props数组的形式传递资产。要显示资源,请使用map循环遍历数组,并将项目传递给名为UserAssetsItems.js的类组件。

创建单独处理资产的类组件UserAssetsItems.js。这只是创建一张具有资产类型和价值的卡片。请注意,我已经在这里完成了内联样式,但如果您更喜欢使用CSS,则可以使用CSS执行此操作。

import React, { Component } from 'react'
import PropTypes from 'prop-types';

class UserAssetsItems extends Component {

    render() {
        let assetStyle = {
            card: {
                display: 'inline-block',
                background: '#333',
                width: '350px',
                height: '160px',
                textAlign: 'left',
                padding: '20px',
                margin: '20px',
                border: '5px solid #333',
                color: 'white'
            }
        }
        return (
            <div style = { assetStyle.card }>
                <p>Description: {this.props.asset.assetType}</p>
                <p> Value: {this.props.asset.value}</p>
            </div>

        )
    }

}

//PropTypes
UserAssetsItems.propTypes = {
    asset: PropTypes.object.isRequired
}

export default UserAssetsItems

通过在文件顶部添加以下行,将userassetsitems导入到userassets

import UserAssetsItems from './UserAssetsItems'

将UserAssets导入主页并更新主页代码,如下所示。这只是显示用户资产并为其设置样式。现在主页还要求将资产数组作为prop传递,以便将其传递给UserAssets.js

import React, { Component } from 'react'
import UserAssets from './UserAssets'
import PropTypes from 'prop-types';

class Homepage extends Component {

  render() {
    let style = {
      UserAssetsStyle: {
        position: 'relative',
        top: '10px',
        width: '58%',
        borderRight: '1px solid black',
      }
    }

    return (
      <div>
        <div style = { style.UserAssetsStyle }>
        <UserAssets assets = { this.props.assets } />
        </div>
      </div>);

  }
}

//PropTypes
Homepage.propTypes = {
  assets: PropTypes.array.isRequired
}

export default Homepage

回到app.js中,添加一个状态,以便包括用户的名称和一个空的资产数组,如下所示:

state = {
  name: "joe",
  assets: []
}

该名称将用作硬编码值,因为该网站尚未登录。

通过在文件顶部添加以下行,将connection.js导入app.js。

import Connection from './Connection'

为了能够获取用户资产,需要在执行此操作的区块链网络中创建查询。因此,在文件夹risk-analysis-tutorial中,将以下行添加到将返回用户资产的queries.qry:

query selectAssetByPolicyholder {
  description: "Select an asset based on the owner"
  statement:
    SELECT org.acme.riskanalysis.PrivateAsset
      WHERE (policyholder == _$policyholder)
}

现在将package.json更新到版本4并重新部署您的网络:

composer archive create --sourceType dir --sourceName . -a [email protected]
composer network install --card [email protected] --archiveFile [email protected]
composer network upgrade -c [email protected] -n risk-analysis-tutorial -V 0.0.4

运行composer rest服务器

composer-rest-server -c [email protected] -n never -u true -w true

向App.js添加一个函数以从区块链网络中检索用户资产,如下所示:

  getAssets = () => {
    // Search for the users assets
    Connection.search('queries/selectAssetByPolicyholder?policyholder=resource%3Aorg.acme.riskanalysis.Policyholder%23' + this.state.name)
      .then(data => {
        //store the assets in the assets array
        this.setState({
          assets: data
        })
        // Retrieve the user object from the state
        let user = this.state.user
        // Add the number of assets to the object
        user.numAssets = this.state.assets.length
        // Update the state
        this.setState({
          user
        })

        let assets = this.state.assets
        for (let i = 0; i < assets.length; i++) {
          // Set insurance status
          if (assets[i].insuranceCompany == null) {
            assets[i].insured = false
          }
          else {
            assets[i].insured = true
          }
        }
        // Update the state
        this.setState({
          assets: assets
        })

      })
  }

通过将以下行添加到文件顶部,将主页导入App.js

import Homepage from './components/Homepage'

既然我们有了这些资产,就可以将它们传递到我们的主页,所以在app.js中的路由器中添加以下行,将这些资产作为props传递。

<Route exact path={"/"} render={props => (
  <React.Fragment>
    <h1>My Assets</h1>
    <Homepage assets={this.state.assets} />
  </React.Fragment>
)}
/>

您的完整app.js文件现在应该如下所示:componentwillmount():

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';
import Header from './components/Header'
import Connection from './Connection'
import Homepage from './components/Homepage'

class App extends Component {

  state = {
    name: "joe",
    assets: []
  }

  componentWillMount() {
    this.getAssets()
  }

  getAssets = () => {
    // Search for the users assets
    Connection.search('queries/selectAssetByPolicyholder?policyholder=resource%3Aorg.acme.riskanalysis.Policyholder%23' + this.state.name)
      .then(data => {
        //store the assets in the assets array
        this.setState({
          assets: data
        })
        // Retrieve the user object from the state
        let user = this.state.user
        // Add the number of assets to the object
        user.numAssets = this.state.assets.length
        // Update the state
        this.setState({
          user
        })

        let assets = this.state.assets
        for (let i = 0; i < assets.length; i++) {
          // Set insurance status
          if (assets[i].insuranceCompany == null) {
            assets[i].insured = false
          }
          else {
            assets[i].insured = true
          }
        }
        // Update the state
        this.setState({
          assets: assets
        })

      })
  }

  render() {
    return (
      <Router>
        <Header />
        <Route exact path={"/"} render={props => (
          <React.Fragment>
            <h1>My Assets</h1>
            <Homepage assets={this.state.assets} />
          </React.Fragment>
        )}
        />

      </Router>
    );
  }
}
export default App;

如果一切正常,您应该在Web应用程序中看到以下内容。 注意此处显示的资产是本教程第1部分中创建的资产。

为了可以添加新资产,我们需要App.js中的一个函数来实现这一点,所以在App.js中创建AddAsset函数:

addAsset = (assetType, value, durationInMonths) => {
  // Create the data object
  const data = {
    "$class": "org.acme.riskanalysis.CreateNewAsset",
    "policyholder": "org.acme.riskanalysis.Policyholder#" + this.state.name,
    "assetType": assetType,
    "value": Number(value),
    "durationInMonths": Number(durationInMonths)
  }
  // Send this data to the Hyperledger Network
  Connection.create('CreateNewAsset', data)
    .then((err) => {
      if (err) {
        console.log(err)
      }
      // Get the new asset
      this.getAssets()
    })

}

在下一章节,我们将学习如何创建用于显示和实现添加新资产的功能的组件。


币搜:比特币领域的搜索引擎www.btcsearch.com

来源:网络




来源:中币网  https://www.zhongbi.net/news/blocknews/145159.html
声明:登载此文仅出于分享区块链知识,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不构成投资建议。投资者据此操作,风险自担。 此文如侵犯到您的合法权益,请联系我们3111859717@qq.com,我们将第一时间处理。