• Lv0
    粉丝0

积分12 / 贡献0

提问0答案被采纳0文章6

作者动态

[经验分享] 汇率查询计算应用

fyy5679 显示全部楼层 发表于 2024-12-15 19:46:09
# 汇率查询计算应用

## 1.熟悉接口

**地址:** https://www.alapi.cn/api/view/88
**接口地址:** https://v2.alapi.cn/api/exchange
**代码块** 如下所示:

```js
{
    "code": 101,
    "msg": "token 未设置",
    "data": null,
    "time": 1734245403,
    "log_id": "726811659709874176",
    "usage": 0
}
```

**请求方法:** [ "GET", "POST"]
**请求参数:**

| 汇率查询的请求参数 |       |        |                                        |                   |
| ------------------ | ----- | ------ | -------------------------------------- | ----------------- |
| 名称               | 必填  | 类型   | 描述                                   | 示例              |
| token              | true  | string | 请求token,用户中心获取                | 用户中心获取token |
| money              | false | int    | 要换算的金额,默认1                    | 1                 |
| from               |       | string | 来源货币,USD为美元,CNY为人民币等     | USD               |
| to                 |       | string | 要转换的货币,USD为美元,CNY为人民币等 | CNY               |

**返回参数:**

| 汇率查询的返回参数 |                               |
| ------------------ | ----------------------------- |
| 名称               | 描述                          |
| exchange           | 汇率                          |
| exchange_round     | 四舍五入很汇率,保留 4 位小数 |
| currency_money     | 货币金额                      |
| currency_form      | 原货币代码                    |
| currency_form_name | 货币名称                      |
| currency_to        | 目标货币代码                  |
| currency_to_name   | 目标货币名称                  |
| update_time        | 更新时间                      |

## 2.代码示例

**2.1** **curl**

```js
curl -X POST \
https://v2.alapi.cn/api/exchange \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'token=用户中心获取token&money=1&from=USD&to=CNY'
```

**2.2** **PHP**

```js
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://v2.alapi.cn/api/exchange",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "token=用户中心获取token&money=1&from=USD&to=CNY",
  CURLOPT_HTTPHEADER => array(
    "Content-Type: application/x-www-form-urlencoded",
  ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
```

**2.3** **Java**

```js
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "token=用户中心获取token&money=1&from=USD&to=CNY");
Request request = new Request.Builder()
  .url("https://v2.alapi.cn/api/exchange")
  .post(body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .build();

Response response = client.newCall(request).execute();
```

**2.4 Python**

```js
import requests

url = "https://v2.alapi.cn/api/exchange"

payload = "token=用户中心获取token&money=1&from=USD&to=CNY"
headers = {'Content-Type': "application/x-www-form-urlencoded"}

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
```

**2.5** **JavaScript**

```js
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "token=用户中心获取token&money=1&from=USD&to=CNY");
Request request = new Request.Builder()
  .url("https://v2.alapi.cn/api/exchange")
  .post(body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .build();

Response response = client.newCall(request).execute();
```

2.6 **go**

```js
package main

import (
        "fmt"
        "strings"
        "net/http"
        "io/ioutil"
)

func main() {

        url := "https://v2.alapi.cn/api/exchange"

        payload := strings.NewReader("token=用户中心获取token&money=1&from=USD&to=CNY")

        req, _ := http.NewRequest("POST", url, payload)

        req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

        res, _ := http.DefaultClient.Do(req)

        defer res.Body.Close()
        body, _ := ioutil.ReadAll(res.Body)

        fmt.Println(res)
        fmt.Println(string(body))

}
```

## 3.错误码

| 返回状态码 code 描述参照 |                      |
| ------------------------ | -------------------- |
| 错误码                   | 说明                 |
| 200                      | 返回200表示接口正常  |
| 404                      | 接口地址不存在       |
| 422                      | 接口请求失败         |
| 400                      | 接口请求失败         |
| 405                      | 请求方法不被允许     |
| 100                      | token 错误           |
| 101                      | 账号过期             |
| 102                      | 接口请求次数超过限制 |
| 104                      | 来源或者ip不在白名单 |
| 406                      | 没有更多数据了       |
| 429                      | 请求 QPS 超过限制    |

# 4.了解HTTP数据请求步骤

## request接口开发步骤

1. 从@kit.NetworkKit中导入http命名空间。
2. 调用createHttp()方法,创建一个HttpRequest对象。
3. 调用该对象的on()方法,订阅http响应头事件,此接口会比request请求先返回。可以根据业务需要订阅此消息。
4. 调用该对象的request()方法,传入http请求的url地址和可选参数,发起网络请求。
5. 添加网络请求。
6. 按照实际业务需要,解析返回结果。
7. 调用该对象的off()方法,取消订阅http响应头事件。
8. 当该请求使用完毕时,调用destroy()方法主动销毁。

### 4.1 创建项目

![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/176299e34d054408828bb33a911af15ab1770.png)

### 4.2 具体步骤

#### 4.2.1 导入包名;

```js
// 引入包名
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
```

![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/511f4dfe31514ec8bf4d7b946b16c21db1770.png)

#### 4.2.2 调用createHttp()方法,创建一个HttpRequest对象;

```js
// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
```

![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/1b96262558f34e508d0e71ceb5f38fb1b1770.png)

#### 4.2.3 调用该对象的on()方法,可以根据业务需要订阅HTTP响应头事件、HTTP流式响应数据接收事件、HTTP流式响应数据接收进度事件和HTTP流式响应数据接收完毕事件;

```js
// 用于订阅HTTP响应头事件
httpRequest.on('headersReceive', (header: Object) => {
  console.info('header: ' + JSON.stringify(header));
});
```

![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/ab903e898a754e748c02afbeced1260db1770.png)

#### 4.2.4 调用该对象的requestInStream()方法,传入http请求的url地址和可选参数,发起网络请求;

```js
httpRequest.request(
  // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
  "EXAMPLE_URL",
  {
    method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
    // 开发者根据自身业务需要添加header字段
    header: {
      'Content-Type': 'application/json'
    },
    // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
    extraData: "data to send",
    expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
    usingCache: true, // 可选,默认为true
    priority: 1, // 可选,默认为1
    connectTimeout: 60000, // 可选,默认为60000ms
    readTimeout: 60000, // 可选,默认为60000ms
    usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
    usingProxy: false, // 可选,默认不使用网络代理,自API 10开始支持该属性
    caPath:'/path/to/cacert.pem', // 可选,默认使用系统预制证书,自API 10开始支持该属性
    clientCert: { // 可选,默认不使用客户端证书,自API 11开始支持该属性
      certPath: '/path/to/client.pem', // 默认不使用客户端证书,自API 11开始支持该属性
      keyPath: '/path/to/client.key', // 若证书包含Key信息,传入空字符串,自API 11开始支持该属性
      certType: http.CertType.PEM, // 可选,默认使用PEM,自API 11开始支持该属性
      keyPassword: "passwordToKey" // 可选,输入key文件的密码,自API 11开始支持该属性
    },
    multiFormDataList: [ // 可选,仅当Header中,'content-Type'为'multipart/form-data'时生效,自API 11开始支持该属性
      {
        name: "Part1", // 数据名,自API 11开始支持该属性
        contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
        data: 'Example data', // 可选,数据内容,自API 11开始支持该属性
        remoteFileName: 'example.txt' // 可选,自API 11开始支持该属性
      }, {
        name: "Part2", // 数据名,自API 11开始支持该属性
        contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
        // data/app/el2/100/base/com.example.myapplication/haps/entry/files/fileName.txt
        filePath: `${getContext(this).filesDir}/fileName.txt`, // 可选,传入文件路径,自API 11开始支持该属性
        remoteFileName: 'fileName.txt' // 可选,自API 11开始支持该属性
      }
    ]
  }, (err: BusinessError, data: http.HttpResponse) => {
    if (!err) {
      // data.result为HTTP响应内容,可根据业务需要进行解析
      console.info('Result:' + JSON.stringify(data.result));
      console.info('code:' + JSON.stringify(data.responseCode));
      // data.header为HTTP响应头,可根据业务需要进行解析
      console.info('header:' + JSON.stringify(data.header));
      console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
      // 当该请求使用完毕时,调用destroy方法主动销毁
      httpRequest.destroy();
    } else {
      console.error('error:' + JSON.stringify(err));
      // 取消订阅HTTP响应头事件
      httpRequest.off('headersReceive');
      // 当该请求使用完毕时,调用destroy方法主动销毁
      httpRequest.destroy();
    }
  }
);
```

上述代码块如下所示:
![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/ecf610b29ae541be9c0c3eff1faea1a3b1770.png)
![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/4d71339084774749845917e381c7ab9eb1770.png)

- 传入http请求的url地址和可选参数,如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/18dc21fbc7964680a6b0339f29f623c7b1770.png)
- header可以保持默认,如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/486461a51b844940bdb98b07cade48f0b1770.png)
- 获取Token,如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/6b07a1d8604f429bb76db1504808b162b1770.png)
- 将Token复制到代码块中,如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/b4eff4ef5a2c484f9cad5ef99b8db133b1770.png)

#### 4.2.5 添加网络权限;

```js
"requestPermissions": [
      {
      "name": "ohos.permission.INTERNET"
      }
    ],
```

如下所示:
![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/c607de4a36024c26a07ed7f4249f6840b1770.png)

- 发起网络请求,结果如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/8c9efb75ecc74dcd98afcd1a28e57ac4b1770.png)

#### 4.2.6 按照实际业务需要,可以解析返回的响应码;

- 在线测试一下返回的结果:

```js
{
  "code": 200,
  "msg": "success",
  "data": {
    "exchange": 7.276113973049274,
    "exchange_round": 7.2761,
    "currency_money": 1,
    "currency_form": "USD",
    "currency_form_name": "美元",
    "currency_to": "CNY",
    "currency_to_name": "人民币",
    "update_time": "2024-12-15 12:00:03"
  },
  "time": 1734251127,
  "usage": 0,
  "log_id": "726835670326079488"
}
```

- 返回结果如下所示(以POST为例):
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/d1525d4c6c7243f497a348c3c81c2f7bb1770.png)
- 在ets下新建文件夹model,如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/83a75b1c82d14b4cbc5788fcc40cf4e9b1770.png)
- 在model文件夹下新建文件夹ArkTS文件exchange,如下所示:
  ![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/5b0db2e9c73e4241bd6d8a8adb94d8e8b1770.png)

#### 4.2.7 调用该对象的off()方法,取消订阅响应事件;

```js
// 取消订阅HTTP响应头事件
httpRequest.off('headersReceive');
```

![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/49417b94dab04e14a537e6f4b82f4455b1770.png)

#### 4.2.8 当该请求使用完毕时,调用destroy()方法主动销毁;

```js
// 当该请求使用完毕时,调用destroy方法主动销毁
httpRequest.destroy();
```

![image.png](https://api.nutpi.net/file/topic/2024-12-15/image/9e0112384a944111a80bce18ca21815cb1770.png)

### 5. 完整代码index.ets

```js
// 引入包名
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { exchange, ExchangeData } from '../model/exchange';

@Entry
@Component
struct Index {
  @State value: number = 0

  @State exchangeData:ExchangeData=new ExchangeData()
  aboutToAppear(): void {
    this.getData(1)
  }
  getData(mony:number){
    // 每一个httpRequest对应一个HTTP请求任务,不可复用
    let httpRequest = http.createHttp();
    // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
    // 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
    httpRequest.on('headersReceive', (header) => {
      console.info('header: ' + JSON.stringify(header));
    });
    httpRequest.request(
      // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
      "https://v2.alapi.cn/api/exchange",
      {
        method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
        // 开发者根据自身业务需要添加header字段
        header: {
          'Content-Type': 'application/json'
        },
        // 当使用POST请求时此字段用于传递请求体内容,具体格式与服务端协商确定
        extraData:{
          "token":'csqZ883ui2KOdhUh',
          "money":1,
          "from":'USD',
          "to":'CNY',
        },
        expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
        usingCache: true, // 可选,默认为true
        priority: 1, // 可选,默认为1
        connectTimeout: 60000, // 可选,默认为60000ms
        readTimeout: 60000, // 可选,默认为60000ms
        usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
        usingProxy: false, // 可选,默认不使用网络代理,自API 10开始支持该属性
        caPath:'/path/to/cacert.pem', // 可选,默认使用系统预制证书,自API 10开始支持该属性
        clientCert: { // 可选,默认不使用客户端证书,自API 11开始支持该属性
          certPath: '/path/to/client.pem', // 默认不使用客户端证书,自API 11开始支持该属性
          keyPath: '/path/to/client.key', // 若证书包含Key信息,传入空字符串,自API 11开始支持该属性
          certType: http.CertType.PEM, // 可选,默认使用PEM,自API 11开始支持该属性
          keyPassword: "passwordToKey" // 可选,输入key文件的密码,自API 11开始支持该属性
        },
        multiFormDataList: [ // 可选,仅当Header中,'content-Type'为'multipart/form-data'时生效,自API 11开始支持该属性
          {
            name: "Part1", // 数据名,自API 11开始支持该属性
            contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
            data: 'Example data', // 可选,数据内容,自API 11开始支持该属性
            remoteFileName: 'example.txt' // 可选,自API 11开始支持该属性
          }, {
          name: "Part2", // 数据名,自API 11开始支持该属性
          contentType: 'text/plain', // 数据类型,自API 11开始支持该属性
          // data/app/el2/100/base/com.example.myapplication/haps/entry/files/fileName.txt
          filePath: `${getContext(this).filesDir}/fileName.txt`, // 可选,传入文件路径,自API 11开始支持该属性
          remoteFileName: 'fileName.txt' // 可选,自API 11开始支持该属性
        }
        ]
      }, (err: BusinessError, data: http.HttpResponse) => {
      if (!err) {
        // data.result为HTTP响应内容,可根据业务需要进行解析

        let exchange:exchange=JSON.parse(data.result.toString())
        this.exchangeData=exchange.data!
        console.info('Result:' + JSON.stringify(data.result));
        console.info('code:' + JSON.stringify(data.responseCode));
        // data.header为HTTP响应头,可根据业务需要进行解析
        console.info('header:' + JSON.stringify(data.header));
        console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
        // 当该请求使用完毕时,调用destroy方法主动销毁
        httpRequest.destroy();
      } else {
        console.error('error:' + JSON.stringify(err));
        // 取消订阅HTTP响应头事件
        httpRequest.off('headersReceive');
        // 当该请求使用完毕时,调用destroy方法主动销毁
        httpRequest.destroy();
      }
    }
    );
  }
  build() {
    Column() {
      TextInput({
        placeholder:" 请输入兑换的金额:",
        text: this.value.toString()

      }).onChange((e:string)=>{
        this.value = parseInt(e)
        this.getData(parseInt(e))
      })
      Text(this.exchangeData.exchange
      ?.toString())
    }
    .height('100%')
    .width('100%')
  }
}
```

# 联系方式

| **有问题可以根据以下方式联系我哟~** |                   |
| ----------------------------------------- | ----------------- |
| QQ                                        | 3277508694@qq.com |
| VX                                        | LYF14589          |
| Github                                    | fyy534            |
| **欢迎各位有问题来咨询哦😀!!!**  |                   |

# 参考文档

HTTP请求:[https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/http-request-V5]()

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部