> For the complete documentation index, see [llms.txt](https://geotag.gitbook.io/api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://geotag.gitbook.io/api/geotag-jie-kou-wen-dang.md).

# GeoTag接口文档

## 🔐签名以及公共参数说明

### 📌 数据加密传输与签名机制说明

* 企业自己生成公私钥对，给平台提供公钥。
* 平台针对企业生成公私钥对，给企业提供公钥。
* 企业请求数据用自己生成的私钥签名，系统提供的公钥对数据加密
* 平台接收数据用企业公钥钥验签，用系统私钥对数据解密，获取明文数据。
* 平台返回数据用平台私钥签名，用企业公钥加密返回数据。
* 企业接受平台返回数据用平台公钥验签，用自己私钥解密数据
*

### 🔐 加密规则

* 构造业务参数 JSON，例如：

{% tabs %}
{% tab title="业务参数 JSON" %}

```javascript
{
    "page": 1,
    "pageSize": 10,
    "status": 1
}
```

{% endtab %}
{% endtabs %}

* 随机生成*AesKey*。
* 用随机生成的*AesKey为原始参数的 JSON 字符串加密，原始参数为空的时候用`{}`（encryptedData）*
* 再用公钥对*AesKey加密（encryptedAesKey）*
* 最后data组成&#x4E3A;*`encryptedData+","+encryptedAesKey`*

### 🔓 解密规则

* 接收到data，根据`,`来分割成两部分。
* 第一部分&#x4E3A;*`encryptedData`，第二部分为`encryptedAesKey`*
* 先用私钥来解&#x5BC6;*`encryptedAesKey`为`aesKey`*
* 再&#x7528;*`aesKey`来解密`encryptedData`*
* 最终得到明文json数据

### 📌 签名规则

* 用处理好的data（*`encryptedData+","+encryptedAesKey`*）后面拼上timestamp
* 用私钥签名

{% tabs %}
{% tab title="处理好请求的Json" %}

```javascript
{
    "businessNo": "B197458838294",
    "data": "p/SPhan0ix6ltS7XNjpQKRkU0iMEd5jrBb8m/0FHnmbu8zdU8raGsLxTOhxxjrAT,aX3Ne0ewKW8pdqsExBZMJcPvPTjoS9brFM4HL/TaM+TTGVvOeMO586lEHW+UErzFioEvaAEYp3jw5KU580j34xIgeY1F0z+D3FuNyn/PpoQJu6V6j5vIkATe40Dz3S384dhl61lKpZc94WVDxw33bFaaM23LPL+AfgV7m5PNHUvqVfQ4WlDOQ09LNY+AHwx5/wZfJaTx9kc0z5TNPUYZdYtZArJ/fr0XAJiIPRPfFLNE/ZF+kMuBxEOpoKYkeWpQngKS/oXveM+c+6MJS24Y8ClcX0JIxS3tN054MH+c+sf/DG+4jvk36O6d7UXqMZLMF+NRYStMpESjbXnbOXxEpA==",
    "sign": "SHo/wMcj6cZmGjxa/ZTmSOHk5TGKCNE1A/99ZFCYM3ZheK4O+tg41YIIosQoyAi7s3EH8d71Py7OlMAM4DEJgbFBMOouw0nGsc2tMVQRNbAe2DihFt4ixD/y+eZldZlRotpRSbGHGfBeLnQx/7zGKbdK/v7ouuQJKbSCNPSMjdKNy5w3sMQVNTmWLSanfv91d1EMDn0ynwughZYYqyjEe78Dyn/ZgfN19Lg32xN+1h8owmI/wJvwICo5hT3AcesL2DtRFDtHDVQPvZp0Lw0E5pox9Lj385q9Ohy+v40q4o5iwP3VasAiz2TEywQKW46/raQnelPRUz+AiseDRuYTFg==",
    "timestamp": 1773043271220
}
```

{% endtab %}
{% endtabs %}

#### 例：

* 企业公钥为：<mark style="color:$danger;">businessPublicKey</mark><mark style="color:$danger;">="</mark><mark style="color:$danger;">MIIBIjANBgkq\*\*\*\*\*</mark><mark style="color:$danger;">"</mark>
* 企业私钥为：<mark style="color:$danger;">business</mark><mark style="color:$danger;">PrivateKey="</mark><mark style="color:$danger;">MIIEvwIBADANBg\*\*\*\*\*</mark><mark style="color:$danger;">"</mark>
* 平台公钥为：<mark style="color:red;">platformPublicKey="MIIBIjANBgkqhkiG\*\*\*\*\*"</mark>
* 企业号为：<mark style="color:$danger;">businessNo</mark><mark style="color:$danger;">="</mark><mark style="color:$danger;">B19745\*\*\*\*</mark><mark style="color:$danger;">"</mark>
* 请求参数json为：<mark style="color:$danger;">{"page": 1,"pageSize": 10,"status": 1}</mark>

#### 📌请求加密签名处理

1、生成随机的<mark style="color:red;">AesKey</mark>

2、用生成的<mark style="color:red;">AesKey</mark>对请求的json进行<mark style="color:red;">AES/ECB/PKCS5Padding</mark>加密得到加密后的<mark style="color:red;">encryptedData</mark>

&#x20;<mark style="color:red;">encryptedData</mark> = aesEncrypt(

<mark style="color:red;">"</mark><mark style="color:$danger;">{"page": 1,"pageSize": 10,"status": 1}</mark><mark style="color:red;">"</mark>,&#x20;

&#x20;<mark style="color:red;">aesKey</mark>)

<mark style="color:red;">encryptedData</mark> = <mark style="color:red;">"+iHd7R+BCyaZtBKBLnEmrCjfSUMror7XwfP5eeeJbY0KKr84yQ5PvY1dsQTkJB78"</mark>;

3、用平台公钥<mark style="color:red;">platformPublicKey</mark>对1生成的<mark style="color:red;">AesKey</mark>进行<mark style="color:red;">RSA/ECB/PKCS1Padding</mark>加密后得到<mark style="color:red;">encryptedAesKey</mark>

<mark style="color:red;">encryptedAesKey</mark>=rsaEncryptAesKey(<mark style="color:red;">aesKey</mark>, <mark style="color:red;">publicKeyStr</mark>);

<mark style="color:red;">encryptedAesKey</mark>=rsaEncryptAesKey(<mark style="color:red;">aesKey</mark>, <mark style="color:red;">"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Fj0+R/lddYvx0BxH39emqKNA2MNvCVq7gf5TBHkLzMHoat/ChmS3JWnNgbR0teRGEr6N5r6GXt2w4DVGwuzVYSYo5npqifGbFS9xtoDafHZ5S5E5Qb/ahxrssYCyZVuxCuOHfP1pJV+jnryyC/BBw5DMdf80/G4FraoyDlitxOa8/3je6Mq9AbuxUibVNghqrpAx2RF/h68wkxgVaXE2T8ZhOYhKEWEQxJ7A19FuCOPruHl7nuG1/cANTwRYo7jawTup9k2tHjh0RpUr1koRQSwI8V0VLOZ3tqPjMFflGHS7aqxLFRjK8ED8gqLOWfB6rLZ4PgYpdNsDrRhFaPCrQIDAQAB"</mark>);

<mark style="color:red;">encryptedAesKey</mark>=<mark style="color:red;">"bLnnDrgZ3y2eSScHKBFhPQGkF3ewAPDNFdskQSBWI9xy9leT3ToMDmyKF/bs4Xmxy/BddaOWh2ncxmEtStCGjC7RfBtPEcZNGNbJwT5XZojAo5TXi2yCcABrpnUZrbemIuQNMIWyQUQSwPXwM+AhrMzaU4YpuMH+E2mEKyFD3t4ZEr0iO+AY+Rmy+4RkI5OWmTecrr6Jo69eDo35ZHs5QUlvwA3/8PdKs+weAtDZV2zsEGqE+EzrtCN7A9dbN4ft2KXD4Y98bCGywWRaZsMUjebCiCPySQcI7EgVRk51/2/KD5VtPepVGLfK5/UKstHnd8R0+f237TZdyGvuHOKdiQ=="</mark>;

4、以','拼合<mark style="color:red;">encryptedData</mark>和<mark style="color:red;">encryptedAesKey</mark>组成请求的data

<mark style="color:red;">data</mark>=<mark style="color:red;">encryptedData+","+encryptedAesKey;</mark>

<mark style="color:red;">data</mark>=<mark style="color:red;">"+iHd7R+BCyaZtBKBLnEmrCjfSUMror7XwfP5eeeJbY0KKr84yQ5PvY1dsQTkJB78,bLnnDrgZ3y2eSScHKBFhPQGkF3ewAPDNFdskQSBWI9xy9leT3ToMDmyKF/bs4Xmxy/BddaOWh2ncxmEtStCGjC7RfBtPEcZNGNbJwT5XZojAo5TXi2yCcABrpnUZrbemIuQNMIWyQUQSwPXwM+AhrMzaU4YpuMH+E2mEKyFD3t4ZEr0iO+AY+Rmy+4RkI5OWmTecrr6Jo69eDo35ZHs5QUlvwA3/8PdKs+weAtDZV2zsEGqE+EzrtCN7A9dbN4ft2KXD4Y98bCGywWRaZsMUjebCiCPySQcI7EgVRk51/2/KD5VtPepVGLfK5/UKstHnd8R0+f237TZdyGvuHOKdiQ=="</mark>

5、获取当前时间戳<mark style="color:red;">timestamp</mark>并拼在加密<mark style="color:red;">data</mark>后用企业私钥<mark style="color:$danger;">business</mark><mark style="color:$danger;">PrivateKey</mark>签进行<mark style="color:red;">SHA256withRSA</mark>签名得到<mark style="color:red;">sign</mark>

<mark style="color:red;">timestamp</mark> = <mark style="color:red;">1766564810</mark>

<mark style="color:red;">sign</mark>=sign(<mark style="color:red;">data</mark>+<mark style="color:red;">timestamp</mark>,<mark style="color:$danger;">business</mark><mark style="color:$danger;">PrivateKey</mark>)

<mark style="color:red;">sign</mark>=sign(<mark style="color:red;">"+iHd7R+BCyaZtBKBLnEmrCjfSUMror7XwfP5eeeJbY0KKr84yQ5PvY1dsQTkJB78,bLnnDrgZ3y2eSScHKBFhPQGkF3ewAPDNFdskQSBWI9xy9leT3ToMDmyKF/bs4Xmxy/BddaOWh2ncxmEtStCGjC7RfBtPEcZNGNbJwT5XZojAo5TXi2yCcABrpnUZrbemIuQNMIWyQUQSwPXwM+AhrMzaU4YpuMH+E2mEKyFD3t4ZEr0iO+AY+Rmy+4RkI5OWmTecrr6Jo69eDo35ZHs5QUlvwA3/8PdKs+weAtDZV2zsEGqE+EzrtCN7A9dbN4ft2KXD4Y98bCGywWRaZsMUjebCiCPySQcI7EgVRk51/2/KD5VtPepVGLfK5/UKstHnd8R0+f237TZdyGvuHOKdiQ=="</mark>+<mark style="color:red;">"1766564810"</mark>,<mark style="color:red;">"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQWPT5H+V11i/HQHEff16aoo0DYw28JWruB/lMEeQvMwehq38KGZLclac2BtHS15EYSvo3mvoZe3bDgNUbC7NVhJijmemqJ8ZsVL3G2gNp8dnlLkTlBv9qHGuyxgLJlW7EK44d8/WklX6OevLIL8EHDkMx1/zT8bgWtqjIOWK3E5rz/eN7oyr0Bu7FSJtU2CGqukDHZEX+HrzCTGBVpcTZPxmE5iEoRYRDEnsDX0W4I4+u4eXue4bX9wA1PBFijuNrBO6n2Ta0eOHRGlSvWShFBLAjxXRUs5ne2o+MwV+UYdLtqrEsVGMrwQPyCos5Z8Hqstng+Bil02wOtGEVo8KtAgMBAAECggEAeZ9EOd1NxJDoySasIpfmsNws9wourWMmXZdYBvj2vDrMvKpw+YNeQNg3iQlIGQ1vjL/P+v/D+XYiKRQe0q/s2wIRXIdvaL3ZTcnWEquXjJP6/5cX7p48IUQ/9lcyr1xFEczfJEsSXSZLf370FLoTszu3K/SKiWq0bMXqFx+wqW+BIxfllTYIy6OE9fZOJyRCtlsDRlbOzBD1gN/k0MZXUW3YewQAT1ctCimQfuBTxr9mn/x4JVwuxmFGKNNd4B3fUxlbM9DoHZxHqkJIXEpuqohfzwSM2wBc9Y9pfdpSHnPtyVKFu+kgML6qcGTsaZVaPB7EOWBnQzzQ+tpKNT1R4QKBgQD3WD59/SfETSJu0LAZcxefhJNWPmCP6aJmJjHUB6WwC3kUOII5wikJ0joru80RBqjI2N6mQMl6rZffecbqkZVa8eXVUKXNtxGGXILfGvsg/Bu/u/w8VmPTM7ZnxZFkGPdvE/9WvCtg8X1iBMZDrV0Fe+D2abp1ETFtDYC7Z7OmWQKBgQDXo15/bhA97CRF+Do8SwVwfF5FfCH00IHsBv4QZhh91iMMN+re+oOUZuJDKjPzUproPpaR31TcDlH0iJ49bj34wF5yOwIpFqRJ+ufOxkm01ofGZJyewlOoTXhNPhP92+9IiJXYnJ0Da2h9EbToJ7QDqxkBIO2ycDXAZoKzgC8cdQKBgQDaw2WiMQG3ETHfKRxXpf/CypM1uD3XiyBjkGyJx6m3pq4UQFaNlziMwy9H9vZMlMM7wPRLvwl0Q40Lzr0sQk8C/Of2XzoGVGBfofruMQLkDZbNYgqZox7vcdFmvsr06VAPInS31f3X5D6tLuPcf7zCWOqDhsevOuGoPkUZe4LdIQKBgEnEDiiDazTzmfkBkFJdy4+OS+VzMF6CEV+/iJvtgQVTAoxEeKksg2R5yX72ae0b3fgCqRlfj7TzhR+kuJUFKFf23pgvDW8m2q6gETpP5JjjJnE8q8M3cMzLK5Mo4EfgO7vRVYlTEfdAf+8A5qTgKBl1J0mWjRmUfx7BMobbG8KdAoGBANLoLEzAXvzpCOSWqjwTOkq1243judtikpGTe87ELZuKl7NcEgy424G5I+hJjyA6hPElCaJteLUaySWCOPbUDnBh42dCizAV4i72FbXgAGtIF5xsWC986BCrOU7olk05S6pvF9U/EiUGRR8jZ3dD2dC0Um8+Tdt/6rx0bvX7LG5i"</mark>)

<mark style="color:red;">sign</mark>=<mark style="color:red;">"wDOXf0eiC/3QnwitzYWawRL//UcZgOvbKYvYeOuMTROAQYHmRxlWILdx+TMeMZp6QsQgEDSncXkBhHsvRT8ik/spM7J9sp4EY3d4wZO8YZCfq5bU+hiV1F7z1HCpoNvjgLVWs4ETa/wqNBcMsU9WyLQR21mhP5JxlHF31tLZP0zk6gQ4IxAZ4yaYmaWMtwLmsys/JxJejkBl7zOEzNw1cDW+CFnW1bmCREHqUVMsCw36a3xfXKGXsC714m2TxKADypxfAGZUuw7pDSirM6VFt4GEGGKHLcuxlZsux/JzDVAdVAV6G/thxV9FtFtGhqTlkkxtAw/z4vUODyInQEDZ8Q=="</mark>

6、组成最终请求json

{\
"businessNo": <mark style="color:$danger;">"B197458838294"</mark>,\
"data": <mark style="color:$danger;">"p/SPhan0ix6ltS7XNjpQKRkU0iMEd5jrBb8m/0FHnmbu8zdU8raGsLxTOhxxjrAT,aX3Ne0ewKW8pdqsExBZMJcPvPTjoS9brFM4HL/TaM+TTGVvOeMO586lEHW+UErzFioEvaAEYp3jw5KU580j34xIgeY1F0z+D3FuNyn/PpoQJu6V6j5vIkATe40Dz3S384dhl61lKpZc94WVDxw33bFaaM23LPL+AfgV7m5PNHUvqVfQ4WlDOQ09LNY+AHwx5/wZfJaTx9kc0z5TNPUYZdYtZArJ/fr0XAJiIPRPfFLNE/ZF+kMuBxEOpoKYkeWpQngKS/oXveM+c+6MJS24Y8ClcX0JIxS3tN054MH+c+sf/DG+4jvk36O6d7UXqMZLMF+NRYStMpESjbXnbOXxEpA=="</mark>,\
"sign": <mark style="color:$danger;">"SHo/wMcj6cZmGjxa/ZTmSOHk5TGKCNE1A/99ZFCYM3ZheK4O+tg41YIIosQoyAi7s3EH8d71Py7OlMAM4DEJgbFBMOouw0nGsc2tMVQRNbAe2DihFt4ixD/y+eZldZlRotpRSbGHGfBeLnQx/7zGKbdK/v7ouuQJKbSCNPSMjdKNy5w3sMQVNTmWLSanfv91d1EMDn0ynwughZYYqyjEe78Dyn/ZgfN19Lg32xN+1h8owmI/wJvwICo5hT3AcesL2DtRFDtHDVQPvZp0Lw0E5pox9Lj385q9Ohy+v40q4o5iwP3VasAiz2TEywQKW46/raQnelPRUz+AiseDRuYTFg=="</mark>,\
"timestamp": <mark style="color:$danger;">1773043271</mark>\
}

#### 📌响应验签解密处理

1、接收响应<mark style="color:red;">apiResponse</mark>

<mark style="color:red;">apiResponse</mark> =<mark style="color:red;">{\\"msg\\":\\"success\\",\\"code\\":200,\\"data\\":\\"C8v2iKX4tm1aV9KBIcHNvljsik2fpm9AOLpIfcHifArb0w3YplH6agR/8wAvIC1zjgfBGvqJf2meEdi9iXdhyXzWQqZ5upFWVuOh2DyFzIuCyMBov2fKEiMjQOgsF3/s,OaPymaL9XukQ/KgV/2EUSa2uvuNv3nUsY9s9WvQdZ0T24XSEsNpyOxruNyPmb7S2DaKT+qzirJUnNnfGh8T50vSCAsW0A8OcX1F7xozcl2Q8F35RnS+RQpnogQ7MFzK6YvF5bidBTg7JWqXasdAMUee1ZkCsKkwFT2eneJoGgNePmllA5B24ESGD5PFLmD+fKz97biYO8+xnhQUfzc2Yb9yxEtVvSNALOTH6Hs6HER3qdO5RF2mOkIpbek4YHmhQVGJeRImehzgAT6TrgXiAlc/qAjmq05Bl1O8XsSXfFZHV27L92uRzRVHqR7R7xqhwDoUwiPDr3Pb90pzysNEZEw==\\",\\"sign\\":\\"bBUjjVIZoQx0LISIEiELwF8FZ8VXvDhIiz6eCsbzQPum53mFwid+1jYCc7ho4yFYChgwr7KzDz2B18nyHhOpujY+7KiFQIjC1FuE/rZXrySLCP9CZbPsSjkWxqlUKPedKxyIEEbsOwgk8nc9ClwW6jrnbp2aozuEwLaOfswJIiF5ocVuPQDgoBEr+G/KiCriMaBIn0SkBRehdymzaK6OgW7D/5V8E+H6mB28uBQU6XyGhJnXWk23OJdfxKAgYDuhCaJMDKRVaXUaLYz2CetwhTtivgrMDoFLpvX2rlhQCji3ShrNYty3dRE9sZgoJq71CcOKxOjABNpEpx+4PDq3ug==\\",\\"timestamp\\":1766565488886}"</mark>

2、用平台公钥<mark style="color:red;">platformPublicKey</mark>对<mark style="color:red;">sign</mark>进行<mark style="color:red;">SHA256withRSA</mark>验签

verifySignature(apiResponse.getData()+apiResponse.getTimestamp(),apiResponse.getSign(),<mark style="color:red;">platformPublicKey</mark>)

verifySignature(<mark style="color:red;">"C8v2iKX4tm1aV9KBIcHNvljsik2fpm9AOLpIfcHifArb0w3YplH6agR/8wAvIC1zjgfBGvqJf2meEdi9iXdhyXzWQqZ5upFWVuOh2DyFzIuCyMBov2fKEiMjQOgsF3/s,OaPymaL9XukQ/KgV/2EUSa2uvuNv3nUsY9s9WvQdZ0T24XSEsNpyOxruNyPmb7S2DaKT+qzirJUnNnfGh8T50vSCAsW0A8OcX1F7xozcl2Q8F35RnS+RQpnogQ7MFzK6YvF5bidBTg7JWqXasdAMUee1ZkCsKkwFT2eneJoGgNePmllA5B24ESGD5PFLmD+fKz97biYO8+xnhQUfzc2Yb9yxEtVvSNALOTH6Hs6HER3qdO5RF2mOkIpbek4YHmhQVGJeRImehzgAT6TrgXiAlc/qAjmq05Bl1O8XsSXfFZHV27L92uRzRVHqR7R7xqhwDoUwiPDr3Pb90pzysNEZEw=="</mark>+<mark style="color:red;">1766565488886</mark>,<mark style="color:red;">"bBUjjVIZoQx0LISIEiELwF8FZ8VXvDhIiz6eCsbzQPum53mFwid+1jYCc7ho4yFYChgwr7KzDz2B18nyHhOpujY+7KiFQIjC1FuE/rZXrySLCP9CZbPsSjkWxqlUKPedKxyIEEbsOwgk8nc9ClwW6jrnbp2aozuEwLaOfswJIiF5ocVuPQDgoBEr+G/KiCriMaBIn0SkBRehdymzaK6OgW7D/5V8E+H6mB28uBQU6XyGhJnXWk23OJdfxKAgYDuhCaJMDKRVaXUaLYz2CetwhTtivgrMDoFLpvX2rlhQCji3ShrNYty3dRE9sZgoJq71CcOKxOjABNpEpx+4PDq3ug==\\"</mark>,<mark style="color:red;">"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiTY7jloW5ZLAqc2xJ3IMq7k3dRsa8hlZ7h33XNNtmGwhc07OLE9VVnCw034LoM0aSAgcyOZiQ/RGTnOUcWTZ5q5U3saoTSran7Qq6Nd7Fbpv2qowTv76xhra1TqoAUhiMl00S9vNDDu11yqRTodMG+ab2NduZf70KyHRf/LOYi9FO6H/GA6ontUNQHnD8cqW2iVw9Y1oQXGz/j83g+rK7Ez9vU9a56CFlfFLACwYoB7wW/i4gzdLtvCd3wH9jo3M/UgH3D5SgPxHQd8QYvSIUpM5Lj8VD8xsvsfxn3YY4tSUUyqXoizyqbFIGzxJ3M29ajv/WEfjw38i+YQN6tPr3wIDAQAB"</mark>);

3、对data进行拆分成加密后的<mark style="color:red;">encryptedAesKey</mark>和加密后的请求数据<mark style="color:red;">encryptedData</mark>

data=<mark style="color:red;">"C8v2iKX4tm1aV9KBIcHNvljsik2fpm9AOLpIfcHifArb0w3YplH6agR/8wAvIC1zjgfBGvqJf2meEdi9iXdhyXzWQqZ5upFWVuOh2DyFzIuCyMBov2fKEiMjQOgsF3/s,OaPymaL9XukQ/KgV/2EUSa2uvuNv3nUsY9s9WvQdZ0T24XSEsNpyOxruNyPmb7S2DaKT+qzirJUnNnfGh8T50vSCAsW0A8OcX1F7xozcl2Q8F35RnS+RQpnogQ7MFzK6YvF5bidBTg7JWqXasdAMUee1ZkCsKkwFT2eneJoGgNePmllA5B24ESGD5PFLmD+fKz97biYO8+xnhQUfzc2Yb9yxEtVvSNALOTH6Hs6HER3qdO5RF2mOkIpbek4YHmhQVGJeRImehzgAT6TrgXiAlc/qAjmq05Bl1O8XsSXfFZHV27L92uRzRVHqR7R7xqhwDoUwiPDr3Pb90pzysNEZEw=="</mark>

<mark style="color:red;">encryptedAesKey</mark>=<mark style="color:red;">"OaPymaL9XukQ/KgV/2EUSa2uvuNv3nUsY9s9WvQdZ0T24XSEsNpyOxruNyPmb7S2DaKT+qzirJUnNnfGh8T50vSCAsW0A8OcX1F7xozcl2Q8F35RnS+RQpnogQ7MFzK6YvF5bidBTg7JWqXasdAMUee1ZkCsKkwFT2eneJoGgNePmllA5B24ESGD5PFLmD+fKz97biYO8+xnhQUfzc2Yb9yxEtVvSNALOTH6Hs6HER3qdO5RF2mOkIpbek4YHmhQVGJeRImehzgAT6TrgXiAlc/qAjmq05Bl1O8XsSXfFZHV27L92uRzRVHqR7R7xqhwDoUwiPDr3Pb90pzysNEZEw=="</mark>

<mark style="color:red;">encryptedData</mark>=<mark style="color:red;">"C8v2iKX4tm1aV9KBIcHNvljsik2fpm9AOLpIfcHifArb0w3YplH6agR/8wAvIC1zjgfBGvqJf2meEdi9iXdhyXzWQqZ5upFWVuOh2DyFzIuCyMBov2fKEiMjQOgsF3/s"</mark>

3、用企业私钥<mark style="color:$danger;">business</mark><mark style="color:$danger;">PrivateKey</mark>解密<mark style="color:red;">encryptedAesKey</mark>得到<mark style="color:red;">AesKey</mark>

<mark style="color:red;">AesKey</mark>=decryptAesKey(<mark style="color:red;">encryptedAesKey</mark>,<mark style="color:$danger;">business</mark><mark style="color:$danger;">PrivateKey</mark>)

<mark style="color:red;">AesKey</mark>=decryptAesKey(<mark style="color:red;">"OaPymaL9XukQ/KgV/2EUSa2uvuNv3nUsY9s9WvQdZ0T24XSEsNpyOxruNyPmb7S2DaKT+qzirJUnNnfGh8T50vSCAsW0A8OcX1F7xozcl2Q8F35RnS+RQpnogQ7MFzK6YvF5bidBTg7JWqXasdAMUee1ZkCsKkwFT2eneJoGgNePmllA5B24ESGD5PFLmD+fKz97biYO8+xnhQUfzc2Yb9yxEtVvSNALOTH6Hs6HER3qdO5RF2mOkIpbek4YHmhQVGJeRImehzgAT6TrgXiAlc/qAjmq05Bl1O8XsSXfFZHV27L92uRzRVHqR7R7xqhwDoUwiPDr3Pb90pzysNEZEw=="</mark>,<mark style="color:red;">"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQWPT5H+V11i/HQHEff16aoo0DYw28JWruB/lMEeQvMwehq38KGZLclac2BtHS15EYSvo3mvoZe3bDgNUbC7NVhJijmemqJ8ZsVL3G2gNp8dnlLkTlBv9qHGuyxgLJlW7EK44d8/WklX6OevLIL8EHDkMx1/zT8bgWtqjIOWK3E5rz/eN7oyr0Bu7FSJtU2CGqukDHZEX+HrzCTGBVpcTZPxmE5iEoRYRDEnsDX0W4I4+u4eXue4bX9wA1PBFijuNrBO6n2Ta0eOHRGlSvWShFBLAjxXRUs5ne2o+MwV+UYdLtqrEsVGMrwQPyCos5Z8Hqstng+Bil02wOtGEVo8KtAgMBAAECggEAeZ9EOd1NxJDoySasIpfmsNws9wourWMmXZdYBvj2vDrMvKpw+YNeQNg3iQlIGQ1vjL/P+v/D+XYiKRQe0q/s2wIRXIdvaL3ZTcnWEquXjJP6/5cX7p48IUQ/9lcyr1xFEczfJEsSXSZLf370FLoTszu3K/SKiWq0bMXqFx+wqW+BIxfllTYIy6OE9fZOJyRCtlsDRlbOzBD1gN/k0MZXUW3YewQAT1ctCimQfuBTxr9mn/x4JVwuxmFGKNNd4B3fUxlbM9DoHZxHqkJIXEpuqohfzwSM2wBc9Y9pfdpSHnPtyVKFu+kgML6qcGTsaZVaPB7EOWBnQzzQ+tpKNT1R4QKBgQD3WD59/SfETSJu0LAZcxefhJNWPmCP6aJmJjHUB6WwC3kUOII5wikJ0joru80RBqjI2N6mQMl6rZffecbqkZVa8eXVUKXNtxGGXILfGvsg/Bu/u/w8VmPTM7ZnxZFkGPdvE/9WvCtg8X1iBMZDrV0Fe+D2abp1ETFtDYC7Z7OmWQKBgQDXo15/bhA97CRF+Do8SwVwfF5FfCH00IHsBv4QZhh91iMMN+re+oOUZuJDKjPzUproPpaR31TcDlH0iJ49bj34wF5yOwIpFqRJ+ufOxkm01ofGZJyewlOoTXhNPhP92+9IiJXYnJ0Da2h9EbToJ7QDqxkBIO2ycDXAZoKzgC8cdQKBgQDaw2WiMQG3ETHfKRxXpf/CypM1uD3XiyBjkGyJx6m3pq4UQFaNlziMwy9H9vZMlMM7wPRLvwl0Q40Lzr0sQk8C/Of2XzoGVGBfofruMQLkDZbNYgqZox7vcdFmvsr06VAPInS31f3X5D6tLuPcf7zCWOqDhsevOuGoPkUZe4LdIQKBgEnEDiiDazTzmfkBkFJdy4+OS+VzMF6CEV+/iJvtgQVTAoxEeKksg2R5yX72ae0b3fgCqRlfj7TzhR+kuJUFKFf23pgvDW8m2q6gETpP5JjjJnE8q8M3cMzLK5Mo4EfgO7vRVYlTEfdAf+8A5qTgKBl1J0mWjRmUfx7BMobbG8KdAoGBANLoLEzAXvzpCOSWqjwTOkq1243judtikpGTe87ELZuKl7NcEgy424G5I+hJjyA6hPElCaJteLUaySWCOPbUDnBh42dCizAV4i72FbXgAGtIF5xsWC986BCrOU7olk05S6pvF9U/EiUGRR8jZ3dD2dC0Um8+Tdt/6rx0bvX7LG5i"</mark>)

4、用<mark style="color:red;">AesKey</mark>对<mark style="color:red;">encryptedData</mark>进行解密得出<mark style="color:red;">responseData</mark>

<mark style="color:red;">responseData</mark>=aesDecrypt(<mark style="color:red;">AesKey</mark>,<mark style="color:red;">encryptedData</mark>)

<mark style="color:red;">responseData</mark>=aesDecrypt(<mark style="color:red;">AesKey</mark>,<mark style="color:red;">"C8v2iKX4tm1aV9KBIcHNvljsik2fpm9AOLpIfcHifArb0w3YplH6agR/8wAvIC1zjgfBGvqJf2meEdi9iXdhyXzWQqZ5upFWVuOh2DyFzIuCyMBov2fKEiMjQOgsF3/s"</mark>)

<mark style="color:red;">responseData</mark> = <mark style="color:red;">"</mark><mark style="color:$danger;">{"list":\[{"mac":"11:11","sn":"GeoTag-S5XBFZSI","status":1}],"page":1,"pageSize":10,"total":1}</mark><mark style="color:$danger;">"</mark>

{% tabs %}
{% tab title="JAVA" %}

```javascript
public static SecretKey decryptAesKey(String base64AesKey, PrivateKey privateKey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(base64AesKey));
    return new SecretKeySpec(decrypted, "AES");
}

public static String aesDecrypt(String base64Data, SecretKey aesKey) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, aesKey);
    byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(base64Data));
    return new String(decrypted, StandardCharsets.UTF_8);
}
public static String decryptData(String base64Data, String privateKeyStr) throws Exception {
    String [] dataKey=base64Data.split(",");
    PrivateKey privateKey=getPrivateKeyFromBase64(privateKeyStr);
    SecretKey aesKey = decryptAesKey(dataKey[1], privateKey);
    String dataJsonStr = aesDecrypt(dataKey[0], aesKey);
    return dataJsonStr;
}
public static SecretKey generateAesKey() throws Exception {
    KeyGenerator generator = KeyGenerator.getInstance("AES");
    generator.init(128); // 或 256
    return generator.generateKey();
}

public static String aesEncrypt(String plaintext, SecretKey aesKey) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, aesKey);
    byte[] encrypted = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
    return Base64.getEncoder().encodeToString(encrypted);
}

public static String rsaEncryptAesKey(SecretKey aesKey, String privateKeyStr) throws Exception {
    PublicKey publicKey=getPublicKeyFromBase64(privateKeyStr);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] encrypted = cipher.doFinal(aesKey.getEncoded());
    return Base64.getEncoder().encodeToString(encrypted);
}
public static String ecryptData(String data, String publicKeyStr) throws Exception {
    SecretKey aesKey = generateAesKey();
    String encryptedData = aesEncrypt(data, aesKey);
    String encryptedAesKey = rsaEncryptAesKey(aesKey, publicKeyStr);
    return encryptedData+","+encryptedAesKey;
}
public static PrivateKey getPrivateKeyFromBase64(String privateKeyStr) throws Exception {
    // 解码Base64格式的私钥字符串为字节数组
    byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);

    // 创建PKCS8EncodedKeySpec对象，用于解析PKCS#8格式的密钥数据
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);

    // 获取KeyFactory对象，指定算法名称，用于生成密钥对象
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");

    // 使用密钥工厂从密钥规范中生成PrivateKey对象，并返回
    return keyFactory.generatePrivate(keySpec);
}


/**
 * 从Base64编码的字符串中获取PublicKey对象
 *
 * @param publicKeyStr Base64编码的公钥字符串
 * @return PublicKey对象
 * @throws Exception 如果生成PublicKey过程中出现错误，则抛出异常
 */
public static PublicKey getPublicKeyFromBase64(String publicKeyStr) throws Exception {
    // 将Base64编码的公钥字符串解码为字节数组
    byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);

    // 将字节数组封装到X509EncodedKeySpec对象中，以便KeyFactory能够处理
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

    // 创建一个KeyFactory对象，指定密钥算法为RSA
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");

    // 使用KeyFactory生成PublicKey对象，并返回
    return keyFactory.generatePublic(keySpec);
}
/**
 * 生成RSA密钥对
 *
 * 此方法使用RSA算法生成一个密钥对，包括公钥和私钥密钥对生成器初始化为2048位，
 * 以确保足够的安全性生成的密钥对随后被编码为Base64字符串，以便于传输和存储
 *
 * @return RSAKey对象，包含编码后的公钥和私钥
 * @throws NoSuchAlgorithmException 如果RSA算法不可用
 */
public static RSAKey keyPairGenerator() throws NoSuchAlgorithmException {
    // 初始化密钥对生成器
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
    // 设置密钥长度为2048位
    keyPairGen.initialize(2048);
    // 生成密钥对
    KeyPair pair = keyPairGen.generateKeyPair();

    // 将公钥编码为Base64字符串
    String publicKey = Base64.getEncoder().encodeToString(pair.getPublic().getEncoded());
    // 将私钥编码为Base64字符串
    String privateKey = Base64.getEncoder().encodeToString(pair.getPrivate().getEncoded());
    // 构建并返回RSAKey对象
    return RSAKey.builder().privateKey(privateKey).publicKey(publicKey).build();
}
/**
 * 用私钥对数据进行签名
 *
 * @param data 待签名的原始数据
 * @param privateKeyStr Base64编码的私钥
 * @return Base64编码的签名
 */
public static String sign(String data, String privateKeyStr) throws Exception {
    PrivateKey privateKey = getPrivateKeyFromBase64(privateKeyStr);
    Signature signature = Signature.getInstance("SHA256withRSA");
    signature.initSign(privateKey);
    signature.update(data.getBytes(StandardCharsets.UTF_8));
    byte[] signBytes = signature.sign();
    return Base64.getEncoder().encodeToString(signBytes);
}

/**
 * 验证签名是否有效
 *
 * @param data 原始数据
 * @param signatureStr Base64编码的签名
 * @param publicKeyStr Base64编码的公钥
 * @return true: 签名有效，false: 无效
 */
public static boolean verifySignature(String data, String signatureStr, String publicKeyStr) throws Exception {
    PublicKey publicKey = getPublicKeyFromBase64(publicKeyStr);
    Signature signature = Signature.getInstance("SHA256withRSA");
    signature.initVerify(publicKey);
    signature.update(data.getBytes(StandardCharsets.UTF_8));
    byte[] signBytes = Base64.getDecoder().decode(signatureStr);
    return signature.verify(signBytes);
}
```

{% endtab %}

{% tab title="PHP" %}

```
/** 使用 RSA 公钥对数据进行加密
 * @param string $data 需要加密的数据
 * @param string $publicKeyBase64 RSA 公钥
 * @return string 加密后的数据
 * @throws \Random\RandomException
 */
public static function encrypt(string $data, string $publicKeyBase64): string
{
    // AES key
    $aesKey = random_bytes(16);

    //AES encrypt
    $encryptedData = openssl_encrypt(
            $data,
            'AES-128-ECB',
            $aesKey,
            OPENSSL_RAW_DATA
    );
    if ($encryptedData === false) {
        throw new Exception('AES encrypt failed');
    }

    //Load public key (Java getEncoded Base64)
    $pubPem = "-----BEGIN PUBLIC KEY-----\n"
            . chunk_split($publicKeyBase64, 64, "\n")
            . "-----END PUBLIC KEY-----";

    $pubKey = openssl_pkey_get_public($pubPem);
    if ($pubKey === false) {
        throw new Exception('Invalid public key');
    }

    //RSA encrypt AES key
    $ok = openssl_public_encrypt(
            $aesKey,
            $encryptedAesKey,
            $pubKey,
            OPENSSL_PKCS1_PADDING
    );
    if (!$ok) {
        throw new Exception('RSA encrypt AES key failed');
    }

    //拼接返回
    return base64_encode($encryptedData)
            . ','
        . base64_encode($encryptedAesKey);
}

/** 使用 RSA 私钥对数据进行解密
 * @param string $encrypted 加密的数据
 * @param string $privateKeyBase64 RSA 私钥
 * @return string 解密后的数据
 */
public static function decryptData(string $encrypted, string $privateKeyBase64): string
{
    //校验格式
    if (substr_count($encrypted, ',') !== 1) {
        throw new RuntimeException('ENCRYPTED FORMAT ERROR');
    }

        [$data, $key] = explode(',', $encrypted, 2);

    //还原私钥 PEM
    $privateKeyPem =
            "-----BEGIN PRIVATE KEY-----\n" .
                    chunk_split($privateKeyBase64, 64, "\n") .
                    "-----END PRIVATE KEY-----";

    $privateKey = openssl_pkey_get_private($privateKeyPem);
    if ($privateKey === false) {
        throw new RuntimeException('Invalid private key');
    }

    //RSA 解密 AES Key
    $aesKey = null;
    $ok = openssl_private_decrypt(
            base64_decode($key),
            $aesKey,
            $privateKey,
            OPENSSL_PKCS1_PADDING
    );

    if (!$ok || $aesKey === null) {
        throw new RuntimeException('RSA decrypt AES key failed');
    }

    //AES-128-ECB 解密数据
    $plain = openssl_decrypt(
            base64_decode($data),
            'AES-128-ECB',
            $aesKey,
            OPENSSL_RAW_DATA
    );

    if ($plain === false) {
        throw new RuntimeException('AES decrypt failed');
    }

    return $plain;
}
/**
 * 使用 RSA 私钥对数据进行 SHA256withRSA 签名
 *
 * @param string $data               原始数据
 * @param string $privateKeyBase64   私钥（PKCS8，Base64，无 PEM 头）
 * @return string                   Base64 编码的签名
 */
public static function sign(string $data, string $privateKeyBase64): string
{
    $privateKeyPem =
            "-----BEGIN PRIVATE KEY-----\n" .
                    chunk_split($privateKeyBase64, 64, "\n") .
                    "-----END PRIVATE KEY-----";

    $privateKey = openssl_pkey_get_private($privateKeyPem);
    if ($privateKey === false) {
        throw new RuntimeException('Invalid private key');
    }

    $signature = '';
    $ok = openssl_sign(
            $data,
            $signature,
            $privateKey,
            OPENSSL_ALGO_SHA256
    );

    if (!$ok) {
        throw new RuntimeException('RSA sign failed');
    }

    return base64_encode($signature);
}

/**
 * 使用 RSA 公钥验证 SHA256withRSA 签名
 *
 * @param string $data               原始数据
 * @param string $signatureBase64    Base64 编码的签名
 * @param string $publicKeyBase64    公钥（X509，Base64，无 PEM 头）
 * @return bool
 */
public static function verify(string $data, string $signatureBase64, string $publicKeyBase64): bool
{
    $publicKeyPem =
            "-----BEGIN PUBLIC KEY-----\n" .
                    chunk_split($publicKeyBase64, 64, "\n") .
                    "-----END PUBLIC KEY-----";

    $publicKey = openssl_pkey_get_public($publicKeyPem);
    if ($publicKey === false) {
        return false;
    }

    $signature = base64_decode($signatureBase64, true);
    if ($signature === false) {
        return false;
    }

    $result = openssl_verify(
            $data,
            $signature,
            $publicKey,
            OPENSSL_ALGO_SHA256
    );

    return $result === 1;
}
```

{% endtab %}
{% endtabs %}

## 🔗API接口说明

### 📌 获取设备列表

> **请求方式**：<mark style="color:$success;">`POST`</mark>&#x20;
>
> **接口地址**：[<mark style="color:$success;">`/device/getList`</mark>](#user-content-fn-1)[^1]
>
> Content-Type：<mark style="color:$success;">`application/json`</mark>

* 请求参数说明：

| **参数名**  | **类型** | **必填** | **说明**              |
| -------- | ------ | ------ | ------------------- |
| page     | int    | 否      | 当前页数，默认1            |
| pageSize | int    | 否      | 页大小，默认20            |
| sortNum  | int    | 否      | 排序：1、时间正序，2时间倒序，默认1 |
| status   | int    | 否      | 启用状态：0、未启用，1、已启用    |

{% tabs %}
{% tab title="请求加密前Json" %}

```javascript

{
    "page": 1,
    "pageSize": 10,
    "status": 1
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="加密后请求Json" %}

```javascript
{
    "businessNo": "B197458838294",
    "data": "SUIP+9pc+qhEMtXg5FzH/E0AVbjsmg8b6+js/UxMrxpPFCPakFIqdEKUhoCATnsd,MxpweoRlyGz6vaEApcFT46WdhTr7GJH1fRVpAn4k6u1QJ1kkfuDWchE2QTph0ERD5AERMhwGw0jhS+YHwao6GOUYyZTlDUByM2JQXasu5fhhmB0u+4UsPpDePjBe1e22JCbFmHJqVpCHmAZ6/02lrvfpnViufyO2J9Lj2wC5HLtVhKMOessBKtMW3QUprkLrUV/dB05h/IcZb2WW0iGAtFa1FL0B62QNk9EUB7oF1v563FD/y9tW06bB3j/qbiDlFoCf2rGQ6lHWH4ipkmrNCHwWqT0NRhkq65dO7J7PFMEa0c3TIaKjM+x+jJbuu99JOMNu+ISM0srQfWSKdH1PCg==",
    "sign": "7HFEPDf/skNj9xrggF4WrZX12wko6HRa67/WaCWEm5ZxwgvxdQU/P4282CzcGyIXf6UakiuhgF3z4g1HpBtNGam4exO3al08Q8Z6ddyHSQmnlnxaXbKUQSY2i9+8Wu6SEAkfD7dBZyGr6H+BwgNq9eGuO4l4zDlKXpJjklSU2Er3a6YffFTsFTKcHiSLswsir6pW33mxoDWcrwZU8Yg1ZJXSVxeUC5jceTKp8VHrpSBSV0IMFW1vofZHSxBzYSI1Q3FBO5M/jJs+q1YiH4XHEgV5axGdIgbgTltpRgFVmxymJsfLZId/x7Bjco/GKPR6Nrx/uI1wbjY6XckUjd8y5g==",
    "timestamp": 1773056221220
}
```

{% endtab %}
{% endtabs %}

* 响应参数data说明：

| **参数名**  | **类型** | **说明**           |
| -------- | ------ | ---------------- |
| page     | int    | 当前页数             |
| pageSize | int    | 页大小              |
| total    | int    | 总页数              |
| list     |        | 设备列表             |
| sn       | string | 设备号              |
| mac      | string | mac              |
| status   | int    | 启用状态：0、未启用，1、已启用 |
| uuid     | string | 设备唯一码            |

{% tabs %}
{% tab title="加密响应参数Json" %}

```javascript
{
    "msg": "success",
    "code": 200,
    "data": "isfDTIPcLS6dmUorCUk9+bACW6nKa5RbqN6YgVAfqi6Cf8WVnGNCwzZtqFjIDztRDHDgzU/WEVwxLlDuKNYYolQAYW/1YHXoh6tPjBMaHVZl/FTtx3gyvyDRYyyIg5jvo8Ywc32fyOmNZj+J2HZ5Qg==,0tVDo4Gleqnr87AHEzo0YxA3lHzZx852atGiXQgfXFVA+Wc9oKnq3rAPJXcG/o/V9mmbtSjgdSsGBrsLQgXPUqa2ANR5FaDsuIGknGhvdfQxP57f3xltJYqvz8RvZk1KMKLbqC02kyQgg/y/raDyOmQ869rYnImRGYfn2Fs/56km4fn3vUnUV8OXP4M0Pvd6dmWWKrOOEiBI/CPBz8bC+lcEGmhUdPi3nbaF1Wa3Dr0SFeuuENxzafM7Nik4YNNOiYwwyzQ6WQcZ7jGZOOv9swXYcBzx+RkOtnbGFGVarRiJawrEItefRFAAb3H9CqmByv+ii/m8Yu+oumR5UHePEg==",
    "sign": "IpoOmwZtC1OnleL6jbHSNfrtTNecgov8Ql/BMy9+wzkOJuk888w9a0+ASBi8autmrGNMLMKEvYULDXKdakLRRjSACpSAUx91f0mbkHSlwDWDkQ2PXlF3K/RGfdSdNpP+5J3/qMs71SNONGVznACG13PT6dKZk89MmzbQkT8yDD8BwxZNFXcsFB/UsJuZ9/YEv8XOGYVVWlt8/oU3JLttr7c8N/nIxXJ/z6yD7d1djOxAkOy6d6ljLg6mMcBSKS2InpuewgzhF5dR6khL9IVupjfbRiI3krQGm0v86ZoZPEnH5Za6O6uVR2UwQfEp7wgQjzSfltVkzr1bl3o9ZYVh+g==",
    "timestamp": 1773059201220
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="响应解密Json" %}

```javascript
{
    "list": [
        {
            "mac": "E8:C8:4F:76:C3:38",
            "sn": "GeoTag-EQLRIDQK",
            "uuid": "e03041c82cd7f55ac2c5f76df7ffbe32",
            "status": 0
        }
    ],
    "page": 1,
    "pageSize": 10,
    "total": 1
}
```

{% endtab %}
{% endtabs %}

### <br>

### 📌 获取设备历史轨迹

> **请求方式**：<mark style="color:$success;">`POST`</mark>&#x20;
>
> **接口地址**：[<mark style="color:$success;">`/device/getHistory`</mark>](#user-content-fn-1)[^1]
>
> Content-Type：<mark style="color:$success;">`application/json`</mark>

* 请求参数说明：

| **参数名**  | **类型** | **必填** | **说明**                             |
| -------- | ------ | ------ | ---------------------------------- |
| page     | int    | 否      | 当前页数，默认1                           |
| pageSize | int    | 否      | 页大小，默认20                           |
| sn       | string | 是      | 设备号，多个设备查询用','分隔单个(sn1)多个(sn1,sn2) |

{% tabs %}
{% tab title="请求加密前Json" %}

```javascript

{
    "page": 1,
    "pageSize": 10,
    "sn": "GeoTag-EQLRIDQK"
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="加密后请求Json" %}

```javascript
{
    "businessNo": "B197458838294",
    "data": "SUIP+9pc+qhEMtXg5FzH/E0AVbjsmg8b6+js/UxMrxpPFCPakFIqdEKUhoCATnsd,MxpweoRlyGz6vaEApcFT46WdhTr7GJH1fRVpAn4k6u1QJ1kkfuDWchE2QTph0ERD5AERMhwGw0jhS+YHwao6GOUYyZTlDUByM2JQXasu5fhhmB0u+4UsPpDePjBe1e22JCbFmHJqVpCHmAZ6/02lrvfpnViufyO2J9Lj2wC5HLtVhKMOessBKtMW3QUprkLrUV/dB05h/IcZb2WW0iGAtFa1FL0B62QNk9EUB7oF1v563FD/y9tW06bB3j/qbiDlFoCf2rGQ6lHWH4ipkmrNCHwWqT0NRhkq65dO7J7PFMEa0c3TIaKjM+x+jJbuu99JOMNu+ISM0srQfWSKdH1PCg==",
    "sign": "7HFEPDf/skNj9xrggF4WrZX12wko6HRa67/WaCWEm5ZxwgvxdQU/P4282CzcGyIXf6UakiuhgF3z4g1HpBtNGam4exO3al08Q8Z6ddyHSQmnlnxaXbKUQSY2i9+8Wu6SEAkfD7dBZyGr6H+BwgNq9eGuO4l4zDlKXpJjklSU2Er3a6YffFTsFTKcHiSLswsir6pW33mxoDWcrwZU8Yg1ZJXSVxeUC5jceTKp8VHrpSBSV0IMFW1vofZHSxBzYSI1Q3FBO5M/jJs+q1YiH4XHEgV5axGdIgbgTltpRgFVmxymJsfLZId/x7Bjco/GKPR6Nrx/uI1wbjY6XckUjd8y5g==",
    "timestamp": 1773056221220
}
```

{% endtab %}
{% endtabs %}

* 响应参数data说明：

| **参数名**       | **类型** | **说明** |
| ------------- | ------ | ------ |
| page          | int    | 当前页数   |
| pageSize      | int    | 页大小    |
| total         | int    | 总页数    |
| list          |        | 设备列表   |
| sn            | string | sn     |
| address       | string | 地址     |
| lat           | double | 纬度     |
| lng           | double | 经度     |
| battery       | long   | 电量     |
| reportedTime  | long   | 上报时间   |
| locationTime  | long   | 定位时间   |
| accuracy      | string | 误差范围   |
| confidence    | string | 信任度    |
| batteryStatus | string | 电池状态   |

{% tabs %}
{% tab title="加密响应参数Json" %}

```javascript
{
    "msg": "success",
    "code": 200,
    "data": "isfDTIPcLS6dmUorCUk9+bACW6nKa5RbqN6YgVAfqi6Cf8WVnGNCwzZtqFjIDztRDHDgzU/WEVwxLlDuKNYYolQAYW/1YHXoh6tPjBMaHVZl/FTtx3gyvyDRYyyIg5jvo8Ywc32fyOmNZj+J2HZ5Qg==,0tVDo4Gleqnr87AHEzo0YxA3lHzZx852atGiXQgfXFVA+Wc9oKnq3rAPJXcG/o/V9mmbtSjgdSsGBrsLQgXPUqa2ANR5FaDsuIGknGhvdfQxP57f3xltJYqvz8RvZk1KMKLbqC02kyQgg/y/raDyOmQ869rYnImRGYfn2Fs/56km4fn3vUnUV8OXP4M0Pvd6dmWWKrOOEiBI/CPBz8bC+lcEGmhUdPi3nbaF1Wa3Dr0SFeuuENxzafM7Nik4YNNOiYwwyzQ6WQcZ7jGZOOv9swXYcBzx+RkOtnbGFGVarRiJawrEItefRFAAb3H9CqmByv+ii/m8Yu+oumR5UHePEg==",
    "sign": "IpoOmwZtC1OnleL6jbHSNfrtTNecgov8Ql/BMy9+wzkOJuk888w9a0+ASBi8autmrGNMLMKEvYULDXKdakLRRjSACpSAUx91f0mbkHSlwDWDkQ2PXlF3K/RGfdSdNpP+5J3/qMs71SNONGVznACG13PT6dKZk89MmzbQkT8yDD8BwxZNFXcsFB/UsJuZ9/YEv8XOGYVVWlt8/oU3JLttr7c8N/nIxXJ/z6yD7d1djOxAkOy6d6ljLg6mMcBSKS2InpuewgzhF5dR6khL9IVupjfbRiI3krQGm0v86ZoZPEnH5Za6O6uVR2UwQfEp7wgQjzSfltVkzr1bl3o9ZYVh+g==",
    "timestamp": 1773059201220
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="响应解密Json" %}

```javascript
{
    "list": [
        {
            "accuracy": "39",
            "battery": 100,
            "batteryStatus": "ok",
            "confidence": "19",
            "sn": "gentag-uqeu",
            "address": "...",
            "lat": 22.789893,
            "lng": 115.802679,
            "locationTime": 1773060529000,
            "reportedTime": 1773060519000
        }
    ],
    "page": 1,
    "pageSize": 10,
    "total": 1
}
```

{% endtab %}
{% endtabs %}

### 📌 获取推送失败的webhook记录（最大支持7天数据）

> **请求方式**：<mark style="color:$success;">`POST`</mark>&#x20;
>
> **接口地址**：<mark style="color:$success;">`/device/getWebHookFail`</mark>&#x20;
>
> Content-Type：<mark style="color:$success;">`application/json`</mark>

* 请求参数说明：

| **参数名**   | **类型** | **必填** | **说明**      |   |
| --------- | ------ | ------ | ----------- | - |
| page      | int    | 否      | 当前页数，默认1    |   |
| pageSize  | int    | 否      | 页大小，默认20    |   |
| beginTime | long   | 否      | 开始时间（毫秒时间戳） |   |
| endTime   | long   | 否      | 结束时间（毫秒时间戳） |   |

{% tabs %}
{% tab title="请求加密前Json" %}

```javascript

{
    "page": 1,
    "pageSize": 10,
    "sn": "GeoTag-EQLRIDQK",
    "beginTime": 1782081060000,
    "endTime": 1782127860000,
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="加密后请求Json" %}

```javascript
{
    "businessNo": "B197458838294",
    "data": "SUIP+9pc+qhEMtXg5FzH/E0AVbjsmg8b6+js/UxMrxpPFCPakFIqdEKUhoCATnsd,MxpweoRlyGz6vaEApcFT46WdhTr7GJH1fRVpAn4k6u1QJ1kkfuDWchE2QTph0ERD5AERMhwGw0jhS+YHwao6GOUYyZTlDUByM2JQXasu5fhhmB0u+4UsPpDePjBe1e22JCbFmHJqVpCHmAZ6/02lrvfpnViufyO2J9Lj2wC5HLtVhKMOessBKtMW3QUprkLrUV/dB05h/IcZb2WW0iGAtFa1FL0B62QNk9EUB7oF1v563FD/y9tW06bB3j/qbiDlFoCf2rGQ6lHWH4ipkmrNCHwWqT0NRhkq65dO7J7PFMEa0c3TIaKjM+x+jJbuu99JOMNu+ISM0srQfWSKdH1PCg==",
    "sign": "7HFEPDf/skNj9xrggF4WrZX12wko6HRa67/WaCWEm5ZxwgvxdQU/P4282CzcGyIXf6UakiuhgF3z4g1HpBtNGam4exO3al08Q8Z6ddyHSQmnlnxaXbKUQSY2i9+8Wu6SEAkfD7dBZyGr6H+BwgNq9eGuO4l4zDlKXpJjklSU2Er3a6YffFTsFTKcHiSLswsir6pW33mxoDWcrwZU8Yg1ZJXSVxeUC5jceTKp8VHrpSBSV0IMFW1vofZHSxBzYSI1Q3FBO5M/jJs+q1YiH4XHEgV5axGdIgbgTltpRgFVmxymJsfLZId/x7Bjco/GKPR6Nrx/uI1wbjY6XckUjd8y5g==",
    "timestamp": 1773056221220
}
```

{% endtab %}
{% endtabs %}

* 响应参数data说明：

| **参数名**       | **类型** | **说明** |
| ------------- | ------ | ------ |
| page          | int    | 当前页数   |
| pageSize      | int    | 页大小    |
| total         | int    | 总页数    |
| list          |        | 设备列表   |
| sn            | string | sn     |
| address       | string | 地址     |
| lat           | double | 纬度     |
| lng           | double | 经度     |
| battery       | long   | 电量     |
| reportedTime  | long   | 上报时间   |
| locationTime  | long   | 定位时间   |
| accuracy      | string | 误差范围   |
| confidence    | string | 信任度    |
| batteryStatus | string | 电池状态   |

{% tabs %}
{% tab title="加密响应参数Json" %}

```javascript
{
    "msg": "success",
    "code": 200,
    "data": "isfDTIPcLS6dmUorCUk9+bACW6nKa5RbqN6YgVAfqi6Cf8WVnGNCwzZtqFjIDztRDHDgzU/WEVwxLlDuKNYYolQAYW/1YHXoh6tPjBMaHVZl/FTtx3gyvyDRYyyIg5jvo8Ywc32fyOmNZj+J2HZ5Qg==,0tVDo4Gleqnr87AHEzo0YxA3lHzZx852atGiXQgfXFVA+Wc9oKnq3rAPJXcG/o/V9mmbtSjgdSsGBrsLQgXPUqa2ANR5FaDsuIGknGhvdfQxP57f3xltJYqvz8RvZk1KMKLbqC02kyQgg/y/raDyOmQ869rYnImRGYfn2Fs/56km4fn3vUnUV8OXP4M0Pvd6dmWWKrOOEiBI/CPBz8bC+lcEGmhUdPi3nbaF1Wa3Dr0SFeuuENxzafM7Nik4YNNOiYwwyzQ6WQcZ7jGZOOv9swXYcBzx+RkOtnbGFGVarRiJawrEItefRFAAb3H9CqmByv+ii/m8Yu+oumR5UHePEg==",
    "sign": "IpoOmwZtC1OnleL6jbHSNfrtTNecgov8Ql/BMy9+wzkOJuk888w9a0+ASBi8autmrGNMLMKEvYULDXKdakLRRjSACpSAUx91f0mbkHSlwDWDkQ2PXlF3K/RGfdSdNpP+5J3/qMs71SNONGVznACG13PT6dKZk89MmzbQkT8yDD8BwxZNFXcsFB/UsJuZ9/YEv8XOGYVVWlt8/oU3JLttr7c8N/nIxXJ/z6yD7d1djOxAkOy6d6ljLg6mMcBSKS2InpuewgzhF5dR6khL9IVupjfbRiI3krQGm0v86ZoZPEnH5Za6O6uVR2UwQfEp7wgQjzSfltVkzr1bl3o9ZYVh+g==",
    "timestamp": 1773059201220
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="响应解密Json" %}

```javascript
{
    "list": [
        {
            "accuracy": "39",
            "battery": 100,
            "batteryStatus": "ok",
            "confidence": "19",
            "sn": "gentag-uqeu",
            "address": "...",
            "lat": 22.789893,
            "lng": 115.802679,
            "locationTime": 1773060529000,
            "reportedTime": 1773060519000
        }
    ],
    "page": 1,
    "pageSize": 10,
    "total": 1
}
```

{% endtab %}
{% endtabs %}

### 📌 修改设备状态

> **请求方式**：<mark style="color:$success;">`POST`</mark>&#x20;
>
> **接口地址**：<mark style="color:$success;">`/device/updateStatus`</mark>
>
> Content-Type：<mark style="color:$success;">`application/json`</mark>

* 请求参数说明：

| **参数名** | **类型** | **必填** | **说明**           |
| ------- | ------ | ------ | ---------------- |
| sn      | string | 是      | 设备号              |
| status  | int    | 是      | 启用状态：0、未启用，1、已启用 |

{% tabs %}
{% tab title="请求加密前Json" %}

```javascript

{
    "sn": "GeoTag-EQLRIDQK",
    "status": 1
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="加密后请求Json" %}

```javascript
{
    "businessNo": "B197458838294",
    "data": "SUIP+9pc+qhEMtXg5FzH/E0AVbjsmg8b6+js/UxMrxpPFCPakFIqdEKUhoCATnsd,MxpweoRlyGz6vaEApcFT46WdhTr7GJH1fRVpAn4k6u1QJ1kkfuDWchE2QTph0ERD5AERMhwGw0jhS+YHwao6GOUYyZTlDUByM2JQXasu5fhhmB0u+4UsPpDePjBe1e22JCbFmHJqVpCHmAZ6/02lrvfpnViufyO2J9Lj2wC5HLtVhKMOessBKtMW3QUprkLrUV/dB05h/IcZb2WW0iGAtFa1FL0B62QNk9EUB7oF1v563FD/y9tW06bB3j/qbiDlFoCf2rGQ6lHWH4ipkmrNCHwWqT0NRhkq65dO7J7PFMEa0c3TIaKjM+x+jJbuu99JOMNu+ISM0srQfWSKdH1PCg==",
    "sign": "7HFEPDf/skNj9xrggF4WrZX12wko6HRa67/WaCWEm5ZxwgvxdQU/P4282CzcGyIXf6UakiuhgF3z4g1HpBtNGam4exO3al08Q8Z6ddyHSQmnlnxaXbKUQSY2i9+8Wu6SEAkfD7dBZyGr6H+BwgNq9eGuO4l4zDlKXpJjklSU2Er3a6YffFTsFTKcHiSLswsir6pW33mxoDWcrwZU8Yg1ZJXSVxeUC5jceTKp8VHrpSBSV0IMFW1vofZHSxBzYSI1Q3FBO5M/jJs+q1YiH4XHEgV5axGdIgbgTltpRgFVmxymJsfLZId/x7Bjco/GKPR6Nrx/uI1wbjY6XckUjd8y5g==",
    "timestamp": 1773056221220
}
```

{% endtab %}
{% endtabs %}

* 响应参数data说明：

| **参数名** | **类型** | **说明**           |
| ------- | ------ | ---------------- |
| sn      | string | 设备号              |
| mac     | string | mac              |
| status  | int    | 启用状态：0、未启用，1、已启用 |
|         |        |                  |

{% tabs %}
{% tab title="加密响应参数Json" %}

```javascript
{
    "msg": "success",
    "code": 200,
    "data": "isfDTIPcLS6dmUorCUk9+bACW6nKa5RbqN6YgVAfqi6Cf8WVnGNCwzZtqFjIDztRDHDgzU/WEVwxLlDuKNYYolQAYW/1YHXoh6tPjBMaHVZl/FTtx3gyvyDRYyyIg5jvo8Ywc32fyOmNZj+J2HZ5Qg==,0tVDo4Gleqnr87AHEzo0YxA3lHzZx852atGiXQgfXFVA+Wc9oKnq3rAPJXcG/o/V9mmbtSjgdSsGBrsLQgXPUqa2ANR5FaDsuIGknGhvdfQxP57f3xltJYqvz8RvZk1KMKLbqC02kyQgg/y/raDyOmQ869rYnImRGYfn2Fs/56km4fn3vUnUV8OXP4M0Pvd6dmWWKrOOEiBI/CPBz8bC+lcEGmhUdPi3nbaF1Wa3Dr0SFeuuENxzafM7Nik4YNNOiYwwyzQ6WQcZ7jGZOOv9swXYcBzx+RkOtnbGFGVarRiJawrEItefRFAAb3H9CqmByv+ii/m8Yu+oumR5UHePEg==",
    "sign": "IpoOmwZtC1OnleL6jbHSNfrtTNecgov8Ql/BMy9+wzkOJuk888w9a0+ASBi8autmrGNMLMKEvYULDXKdakLRRjSACpSAUx91f0mbkHSlwDWDkQ2PXlF3K/RGfdSdNpP+5J3/qMs71SNONGVznACG13PT6dKZk89MmzbQkT8yDD8BwxZNFXcsFB/UsJuZ9/YEv8XOGYVVWlt8/oU3JLttr7c8N/nIxXJ/z6yD7d1djOxAkOy6d6ljLg6mMcBSKS2InpuewgzhF5dR6khL9IVupjfbRiI3krQGm0v86ZoZPEnH5Za6O6uVR2UwQfEp7wgQjzSfltVkzr1bl3o9ZYVh+g==",
    "timestamp": 1773059201220
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="响应解密Json" %}

```javascript
{
    "mac": "E8:C8:4F:76:C3:38",
    "sn": "GeoTag-EQLRIDQK",
    "status": 0
 }
```

{% endtab %}
{% endtabs %}

## #webhook

企业配置了webhook的连接后，当企业的设备有位置更新都会实时通过webhook推送给企业

* 推送参数说明：

| **参数名**       | **类型** | **说明** |
| ------------- | ------ | ------ |
| sn            | string | sn     |
| lat           | double | 纬度     |
| lng           | double | 经度     |
| battery       | long   | 电量     |
| reportedTime  | long   | 上报时间   |
| locationTime  | long   | 定位时间   |
| accuracy      | string | 误差范围   |
| confidence    | string | 信任度    |
| batteryStatus | string | 电池状态   |

{% tabs %}
{% tab title="加密推送参数Json" %}

```javascript
{
    "msg": "success",
    "code": 200,
    "data": "isfDTIPcLS6dmUorCUk9+bACW6nKa5RbqN6YgVAfqi6Cf8WVnGNCwzZtqFjIDztRDHDgzU/WEVwxLlDuKNYYolQAYW/1YHXoh6tPjBMaHVZl/FTtx3gyvyDRYyyIg5jvo8Ywc32fyOmNZj+J2HZ5Qg==,0tVDo4Gleqnr87AHEzo0YxA3lHzZx852atGiXQgfXFVA+Wc9oKnq3rAPJXcG/o/V9mmbtSjgdSsGBrsLQgXPUqa2ANR5FaDsuIGknGhvdfQxP57f3xltJYqvz8RvZk1KMKLbqC02kyQgg/y/raDyOmQ869rYnImRGYfn2Fs/56km4fn3vUnUV8OXP4M0Pvd6dmWWKrOOEiBI/CPBz8bC+lcEGmhUdPi3nbaF1Wa3Dr0SFeuuENxzafM7Nik4YNNOiYwwyzQ6WQcZ7jGZOOv9swXYcBzx+RkOtnbGFGVarRiJawrEItefRFAAb3H9CqmByv+ii/m8Yu+oumR5UHePEg==",
    "sign": "IpoOmwZtC1OnleL6jbHSNfrtTNecgov8Ql/BMy9+wzkOJuk888w9a0+ASBi8autmrGNMLMKEvYULDXKdakLRRjSACpSAUx91f0mbkHSlwDWDkQ2PXlF3K/RGfdSdNpP+5J3/qMs71SNONGVznACG13PT6dKZk89MmzbQkT8yDD8BwxZNFXcsFB/UsJuZ9/YEv8XOGYVVWlt8/oU3JLttr7c8N/nIxXJ/z6yD7d1djOxAkOy6d6ljLg6mMcBSKS2InpuewgzhF5dR6khL9IVupjfbRiI3krQGm0v86ZoZPEnH5Za6O6uVR2UwQfEp7wgQjzSfltVkzr1bl3o9ZYVh+g==",
    "timestamp": 1773059201220
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="响应解密Json" %}

```javascript
{
    "accuracy": "39",
    "battery": 100,
    "batteryStatus": "ok",
    "confidence": "19",
    "sn": "gentag-uqeu",
    "lat": 22.789893,
    "lng": 115.802679,
    "locationTime": 1773060529000,
    "reportedTime": 1773060519000
}
```

{% endtab %}
{% endtabs %}

## #SDK

### 📌 JAVA

#### ⏬ [JAVA SDK Download](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Frj1oeSOmouAR9NBjdyri%2Fuploads%2Fd3jt1nJk4Ug14GIGEQM4%2Fgentag-sdk.jar.zip?alt=media\&token=aa6f2948-9cfd-4a46-908c-40dfd8b0479b)

* 项目引入SDK jar

{% tabs %}
{% tab title="调用sdk示例" %}

```javascript
public static void main( String[] args ) throws Exception {

         String apiUrl="http://127.0.0.1:10023";

        /**
         * 企业号
         */
         String businessNo="B197458838294";
        /**
         * 企业公钥
         */
         String businessPublicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7KoQO0uq06je3vy1FQ2uRorAi8Yu4vdEPfs44ZBIvcPSx7JeLBq4UTz1EKkTtreFegzN1FmxSoZWiY65cRnMwVXm1Aiz8LncXTUdb2CMf3GWXLXiYeQImZ4yxgETkZZJcEaxJgT0KYWwWdeDJLjfC5DiKyahJ3sEZzC17At+LFooiQLHn8I2UG1xmdZ3fC3YUsRuJS5LOwN12jDz4yHffz0H+4uRtMIUH0ra7jHSzvDMJ+UAlMYP42zxSMW3GmTlrqJlxVOZQrcL9vH7KVD0lh4xiXwbvP3brbFlcYIrHlqzdGJtv7xer5E5w2Q5z6DDmTpVpqnnpRdEU+Ye0Xy8sQIDAQAB";
        /**
         * 企业私钥
         */
         String businessPrivateKey="MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDsqhA7S6rTqN7e/LUVDa5GisCLxi7i90Q9+zjhkEi9w9LHsl4sGrhRPPUQqRO2t4V6DM3UWbFKhlaJjrlxGczBVebUCLPwudxdNR1vYIx/cZZcteJh5AiZnjLGARORlklwRrEmBPQphbBZ14MkuN8LkOIrJqEnewRnMLXsC34sWiiJAsefwjZQbXGZ1nd8LdhSxG4lLks7A3XaMPPjId9/PQf7i5G0whQfStruMdLO8Mwn5QCUxg/jbPFIxbcaZOWuomXFU5lCtwv28fspUPSWHjGJfBu8/dutsWVxgiseWrN0Ym2/vF6vkTnDZDnPoMOZOlWmqeelF0RT5h7RfLyxAgMBAAECggEAVxjzZk8frEvO0fPg1MG3LKDt4cLrCH6Fr+Xf9it6idQio3nCbKrcwJEVg68l4S3DQrqpmYf01n+AI5nSJ4yeLVzm2YvmZSaRsf/VOGMo8dIkyzPo/6vDen2dI//Lat4LYvWxRlO2Y/2efEHzMrWS6JfGlKjf0D7WzP9BRICqS7mhVr7+RqjQPLriUOnaFfGX50b05MqgMRslikQ+1q5j7UgEYHSYkoUa05IXQL556Vb6g7NDlhwZN+ojecn0qe/Xt2aAONrUkPAK/P3BtZyHiefa/ySs2UsLlujvCO66aqwf2tnqoclgIPSBOyB5f4ewwJJpA5AZDCHNrBso+lCc7QKBgQDy4ucruq8McWdzEMpVVPhZCSNq/Y/svm7aSmtHohjeR93ilQHF/YrKN/NZho4LA/NRReL+aIFiWlUFkLTXkVjCKoF/MuTqzx/HGgn2KZ1uz2moKr4kDyQ484rNXFxxKvWLfD7p3OE+sNNr0ddHRxeD+pjGq1G6Yf5COMB2+Ef3gwKBgQD5cSlX4j1uBKYd/1w80Vr81PNHqRKSXvP/8d6Pybhn6R1tdwA8zpok6BXvD2szXkAgiiA+rfmkzM6l3mjsJV2YNExLfIuvZg0xFq5mKpx9DrTovLuce85aqz47bGhr2TGmtjelFwuMEE/Bkk2mNS6cu9xE6B8I8vPh5LWfo4ZQuwKBgQCJv4W7lzSPqgExkOQvYPE4Daa4lvV5HsdfpbUR+yx/Y+LDDh7jWtfLt8+bhmQoeyUTgr8p6br3PKPbdCYb26Kq+9BVg1ewk6dCE9JyeUeAAMG7TgJoEO5KHlUqAqeqxuJbKSvFFi/ojgBZtbiSBA+iGg1rHt5LBihdBjKhRk4KYQKBgQCfEr1s4EiQmsJdKvZlipVd22fx8S54zbkJJfPq+pdxHMa5gkRSgubmVmN2evzAW4DFv5BkqIolwL6gJMAAqKuRXviwwxJJnukWvwIlAVOepPxV19ZFKuckB0S+nJnS/UWerWG7FIE2p0hVh7mhHxVEusDz6JuyF03UZwg0cBI99QKBgQCQ/gJ1y8eH/AySTwVmozhpcN0fzw7keSBFIg9xGTW1Pwx2iEg11rUVQp7GnPnGipNdRWclzs5L/npR/ysaMWEs8YyJeRyp87BBq2Zssn24F3jOBU8CUPUDUn56uV/nvcQ0mhuDktAtX8ArdKlEmZDue0ROUnwfgxOF8CYYwaRMWw==";
        /**
         * 平台公钥
         */
         String platformPublicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwsclKYNj3jvlui4OsLJ/uzPxbLFQxfv80MXpKa2QdIX8/9UCLW7x+faK3MY8+MGkZ0sfkQVKyo6kHqmZTWgke1OhXeASWeg7sBMsUX1CaKVjzwFHH5nhVQGBYzfH/aE5B1RMeJBvujNHKOiCem+gN1GtSlIiK3c4gJwbPhDobRKApRO/ziVPmrKr03adyeibpFmA657uI/LDyhWnWhL9ukZkfkAYsV1TadQhH4eTiYgiKN6UXE6du/LAOM3DZ5McGqFtIyduDTQx/6H+YE7Mx3VkPXhzSEv0xYwVGQsTai3gYi4u8M28B30V9Lmnj11X5Qjc2nspZzk74EEbiWk9rwIDAQAB";
        GeotagApiClient geotagApiClient =new GeotagApiClient(
                apiUrl,businessNo,businessPublicKey,businessPrivateKey,platformPublicKey
        );
        try{
            DeviceResponse deviceResponse= geotagApiClient.getList(DeviceRequest.builder()
                    .page(1).pageSize(10).build());
            System.out.println(JSONObject.toJSONString(deviceResponse));
            HistoryResponse history= geotagApiClient.getHistory(HistoryRequest.builder()
                    .page(1).pageSize(10).sn("GeoTag-EQLRIDQK").build());
            System.out.println(JSONObject.toJSONString(history));
            DeviceResponse.ApiDevice apiDevice= geotagApiClient.updateStatus(UpdateStatusRequest.builder()
                    .status(1).sn("GeoTag-EQLRIDQK").build());
            System.out.println(JSONObject.toJSONString(apiDevice));
        } catch (BizException e) {
            System.out.printf("返回错误码:%s,错误内容:%s",e.getCode(),e.getMessage());
        }

    }
```

{% endtab %}
{% endtabs %}

### 📌 PHP

{% file src="/files/gwXHRLTOjmQEiAlauJpH" %}

[^1]:
