Bläddra i källkod

Dev yunapp (baidu)(百度云机)

tsurumure 4 månader sedan
förälder
incheckning
5f0e2d5ce4

+ 3 - 3
src/main/java/com/backendsys/modules/TestController.java

@@ -7,7 +7,9 @@ import cn.hutool.json.JSONUtil;
 
 import com.backendsys.aspect.RateLimiting;
 import com.backendsys.aspect.QueuingPoll;
-import com.backendsys.exception.CustException;
+import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ExecuteScriptParams;
+import com.backendsys.modules.sdk.baidu.yunapp.service.YunappService;
 import com.backendsys.service.TestService;
 import com.backendsys.utils.ResourceUtil;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -27,7 +29,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.http.MediaType;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.web.bind.annotation.*;
 
@@ -58,7 +59,6 @@ import java.util.concurrent.TimeUnit;
 
 import com.tencentcloudapi.common.CommonClient;
 import com.tencentcloudapi.common.exception.TencentCloudSDKException;
-import reactor.core.publisher.Flux;
 
 
 @RestController

+ 54 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/controller/YunappController.java

@@ -0,0 +1,54 @@
+package com.backendsys.modules.sdk.baidu.yunapp.controller;
+
+import com.backendsys.modules.common.config.security.annotations.Anonymous;
+import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ExecuteScriptParams;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.TaskParams;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ScreenshotParams;
+import com.backendsys.modules.sdk.baidu.yunapp.service.YunappService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RestController
+@Tag(name = "云手机")
+public class YunappController {
+
+    @Autowired
+    private YunappService yunappService;
+
+    @Anonymous
+    @Operation(summary = "实例执行脚本")
+    @PostMapping("/api/yunapp/executeScript")
+    public Result executeScript(@RequestBody ExecuteScriptParams executeScriptParams) {
+        return Result.success().put("data", yunappService.executeScript(executeScriptParams));
+    }
+
+    @Anonymous
+    @Operation(summary = "实例执行脚本查询")
+    @PostMapping("/api/yunapp/executeScriptInfo")
+    public Result executeScriptInfo(@RequestBody TaskParams taskParams) {
+        return Result.success().put("data", yunappService.executeScriptInfo(taskParams.getTask_ids()));
+    }
+
+    @Anonymous
+    @Operation(summary = "实例截图")
+    @PostMapping("/api/yunapp/screenshot")
+    public Result screenshot(@RequestBody ScreenshotParams screenshotParams) {
+        return Result.success().put("data", yunappService.screenshot(screenshotParams));
+    }
+
+    @Anonymous
+    @Operation(summary = "实例截图查询")
+    @PostMapping("/api/yunapp/screenshotInfo")
+    public Result screenshotInfo(@RequestBody TaskParams taskParams) {
+        return Result.success().put("data", yunappService.screenshotInfo(taskParams.getTask_ids()));
+    }
+
+
+
+}

+ 15 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/entity/ExecuteScriptParams.java

@@ -0,0 +1,15 @@
+package com.backendsys.modules.sdk.baidu.yunapp.entity;
+
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ExecuteScriptParams {
+    @NotNull(message = "pad_codes 不能为空")
+    private List<String> pad_codes;
+    @NotEmpty(message = "script_content 不能为空")
+    private String script_content;
+}

+ 13 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/entity/ScreenshotParams.java

@@ -0,0 +1,13 @@
+package com.backendsys.modules.sdk.baidu.yunapp.entity;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ScreenshotParams {
+    @NotNull(message = "pad_codes 不能为空")
+    private List<String> pad_codes;
+    private Integer quality;    // 默认:3,枚举值:1,2,3,表示截图质量。 其中,1:高质量,2:中质量,3低质量
+}

+ 12 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/entity/TaskParams.java

@@ -0,0 +1,12 @@
+package com.backendsys.modules.sdk.baidu.yunapp.entity;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class TaskParams {
+    @NotNull(message = "task_ids 不能为空")
+    private List<Long> task_ids;
+}

+ 21 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/entity/YuappSign.java

@@ -0,0 +1,21 @@
+package com.backendsys.modules.sdk.baidu.yunapp.entity;
+
+import lombok.Data;
+
+@Data
+public class YuappSign {
+    private String s;
+    private String app_key;
+    private Integer auth_ver;
+    private Long nonce;
+
+    public String toParams() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("?s=").append(s);
+        sb.append("&appkey=").append(app_key);
+        sb.append("&auth_ver=").append(auth_ver);
+        sb.append("&nonce=").append(nonce);
+        return sb.toString();
+    }
+
+}

+ 25 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/service/YunappService.java

@@ -0,0 +1,25 @@
+package com.backendsys.modules.sdk.baidu.yunapp.service;
+
+import cn.hutool.json.JSONArray;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ExecuteScriptParams;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ScreenshotParams;
+
+import java.util.List;
+
+public interface YunappService {
+
+    // 实例执行脚本
+    // https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_base_instance_execute_script
+    JSONArray executeScript(ExecuteScriptParams executeScriptParams);
+    // 实例执行脚本
+    // https://cloud.baidu.com/doc/ARMCM/s/2kei7tyr3#%E4%BB%BB%E5%8A%A1%E7%BB%93%E6%9E%9C%E6%9F%A5%E8%AF%A2
+    JSONArray executeScriptInfo(List<Long> task_ids);
+
+
+    // 实例截图
+    // https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_base_screenshot
+    JSONArray screenshot(ScreenshotParams screenshotParams);
+    // 实例截图 查询结果
+    // https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_base_screenshot_info
+    JSONArray screenshotInfo(List<Long> task_ids);
+}

+ 161 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/service/impl/YunappServiceImpl.java

@@ -0,0 +1,161 @@
+package com.backendsys.modules.sdk.baidu.yunapp.service.impl;
+
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONUtil;
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ExecuteScriptParams;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.ScreenshotParams;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.YuappSign;
+import com.backendsys.modules.sdk.baidu.yunapp.service.YunappService;
+import com.backendsys.modules.sdk.baidu.yunapp.utils.YunappUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 百度智能云 - ARM云手机
+ * https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_use
+ */
+@Service
+public class YunappServiceImpl implements YunappService {
+
+    @Autowired
+    private YunappUtil yunappUtil;
+
+    /**
+     * 实例执行脚本
+     * https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_base_instance_execute_script
+     */
+    @Override
+    public JSONArray executeScript(ExecuteScriptParams executeScriptParams) {
+        // 签名
+        YuappSign signEntity = yunappUtil.getSign();
+
+        // 接口参数
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("padCodes", executeScriptParams.getPad_codes());
+        params.put("scriptContent", executeScriptParams.getScript_content());
+        params.put("createTime", signEntity.getNonce());
+        params.put("msg", yunappUtil.getMsg(JSONUtil.toJsonStr(params), signEntity.getNonce()));
+
+        String url = "https://platform.armvm.com/command/pad/execute-script.html" + signEntity.toParams();
+        System.out.println("url = " + url);
+        System.out.println("params = " + params);
+
+        // 发起请求
+        try(HttpResponse response = HttpUtil.createPost(url)
+                .body(JSONUtil.toJsonStr(params))
+                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+                .execute()
+        ) {
+            System.out.println("response = " + response.body());
+            return yunappUtil.getResponseJSONArray(response.body());
+        } catch (Exception e) {
+            throw new CustException(e.getMessage());
+        }
+    }
+
+    /**
+     * 实例执行脚本
+     * https://cloud.baidu.com/doc/ARMCM/s/2kei7tyr3#%E4%BB%BB%E5%8A%A1%E7%BB%93%E6%9E%9C%E6%9F%A5%E8%AF%A2
+     */
+    @Override
+    public JSONArray executeScriptInfo(List<Long> task_ids) {
+        // 签名
+        YuappSign signEntity = yunappUtil.getSign();
+
+        // 接口参数
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("taskIds", task_ids);
+        params.put("createTime", signEntity.getNonce());
+        params.put("msg", yunappUtil.getMsg(JSONUtil.toJsonStr(params), signEntity.getNonce()));
+
+        String url = "https://platform.armvm.com/command/pad/execute-task-info.html" + signEntity.toParams();
+        System.out.println("url = " + url);
+        System.out.println("params = " + params);
+
+        // 发起请求
+        try(HttpResponse response = HttpUtil.createPost(url)
+                .body(JSONUtil.toJsonStr(params))
+                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+                .execute()
+        ) {
+            System.out.println("response = " + response.body());
+            return yunappUtil.getResponseJSONArray(response.body());
+        } catch (Exception e) {
+            throw new CustException(e.getMessage());
+        }
+    }
+
+    /**
+     * 实例截图
+     * https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_base_screenshot
+     */
+    @Override
+    public JSONArray screenshot(ScreenshotParams screenshotParams) {
+        // 签名
+        YuappSign signEntity = yunappUtil.getSign();
+
+        // 接口参数
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("padCodes", screenshotParams.getPad_codes());
+        params.put("quality", screenshotParams.getQuality());
+        params.put("createTime", signEntity.getNonce());
+        params.put("msg", yunappUtil.getMsg(JSONUtil.toJsonStr(params), signEntity.getNonce()));
+
+        String url = "https://platform.armvm.com/command/pad/screenshot.html" + signEntity.toParams();
+        System.out.println("url = " + url);
+        System.out.println("params = " + params);
+        System.out.println("paramsStr = " + JSONUtil.toJsonStr(params));
+
+        // 发起请求
+        try(HttpResponse response = HttpUtil.createPost(url)
+                .body(JSONUtil.toJsonStr(params))
+                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+                .execute()
+        ) {
+            System.out.println("response = " + response.body());
+            return yunappUtil.getResponseJSONArray(response.body());
+        } catch (Exception e) {
+            throw new CustException(e.getMessage());
+        }
+
+    }
+
+    /**
+     * 实例截图结果查询
+     * https://yunapp.baidu.com/console/bgs/doc/?d=bgs-phone&p=PHONE_API_base_screenshot_info
+     */
+    @Override
+    public JSONArray screenshotInfo(List<Long> task_ids) {
+        // 签名
+        YuappSign signEntity = yunappUtil.getSign();
+
+        // 接口参数
+        Map<String, Object> params = new LinkedHashMap<>();
+        params.put("taskIds", task_ids);
+        params.put("createTime", signEntity.getNonce());
+        params.put("msg", yunappUtil.getMsg(JSONUtil.toJsonStr(params), signEntity.getNonce()));
+
+        String url = "https://platform.armvm.com/command/pad/screenshot-info.html" + signEntity.toParams();
+        System.out.println("url = " + url);
+        System.out.println("params = " + params);
+
+        // 发起请求
+        try(HttpResponse response = HttpUtil.createPost(url)
+                .body(JSONUtil.toJsonStr(params))
+                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+                .execute()
+        ) {
+            System.out.println("response = " + response.body());
+            return yunappUtil.getResponseJSONArray(response.body());
+        } catch (Exception e) {
+            throw new CustException(e.getMessage());
+        }
+    }
+}

+ 98 - 0
src/main/java/com/backendsys/modules/sdk/baidu/yunapp/utils/YunappUtil.java

@@ -0,0 +1,98 @@
+package com.backendsys.modules.sdk.baidu.yunapp.utils;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.backendsys.exception.CustException;
+import com.backendsys.modules.sdk.baidu.yunapp.entity.YuappSign;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.*;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Base64;
+
+@Component
+public class YunappUtil {
+
+    private String DES_KEY = "df22190e23e1e3c139c26508f44526b6";
+    private String APP_KEY = "4988d7dcafdc46edbb15b141892d5986";
+    private String APP_SECRET = "dbd12e4165f8b81ed4866e392201bc4f";
+    private Integer AUTH_VER = 3;
+
+    /**
+     * 生成签名
+     */
+    public YuappSign getSign() {
+        Long nonce = System.currentTimeMillis();
+        String paramsStr = "appkey" + APP_KEY + "auth_ver" + AUTH_VER + "nonce" + nonce + APP_SECRET;
+        String sign = org.apache.commons.codec.digest.DigestUtils.md5Hex(paramsStr.getBytes(StandardCharsets.UTF_8));
+        YuappSign entity = new YuappSign();
+        entity.setS(sign);
+        entity.setApp_key(APP_KEY);
+        entity.setAuth_ver(AUTH_VER);
+        entity.setNonce(nonce);
+        return entity;
+    }
+
+    /**
+     * 加密参数
+     */
+    public String getMsg(String requestParam, Long nonce) {
+        try {
+
+            // 请求参数加密
+            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
+            SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");
+            SecretKey secretKey = skf.generateSecret(new DESedeKeySpec(DES_KEY.getBytes(StandardCharsets.UTF_8)));
+            ByteBuffer byteBuffer = ByteBuffer.allocate(8);
+            byteBuffer.order(ByteOrder.BIG_ENDIAN);
+            byteBuffer.putLong(nonce);
+            byte[] iv = byteBuffer.array();
+            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
+            byte[] cipherText = cipher.doFinal(requestParam.getBytes(StandardCharsets.UTF_8));
+            String msg = Base64.getEncoder().encodeToString(cipherText);
+            return msg;
+
+        } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException |
+                 InvalidAlgorithmParameterException | IllegalBlockSizeException |
+                 InvalidKeySpecException | BadPaddingException e) {
+            throw new CustException(e.getMessage());
+        }
+    }
+
+    /**
+     * 格式化返回值
+     * { data, code, msg, ts }
+     */
+    public JSONObject getResponseJSONObject(String body) {
+        JSONObject responseBody = JSONUtil.parseObj(body);
+        Integer code = Convert.toInt(responseBody.get("code"));
+        String msg = Convert.toStr(responseBody.get("msg"));
+        if (code == 0) {
+            return JSONUtil.parseObj(responseBody.get("data"));
+        } else {
+            throw new CustException(msg);
+        }
+    }
+    public JSONArray getResponseJSONArray(String body) {
+        JSONObject responseBody = JSONUtil.parseObj(body);
+        Integer code = Convert.toInt(responseBody.get("code"));
+        String msg = Convert.toStr(responseBody.get("msg"));
+        if (code == 0) {
+            return JSONUtil.parseArray(responseBody.get("data"));
+        } else {
+            throw new CustException(msg);
+        }
+    }
+
+}