harmony滑动解锁、滑动查找组件、识别验证码、if存在控件执行点击、点击返回键、点击多任务键、if存在控件执行输入、击指定文字指定方向第几个指定内容的文本

hz_1122
yineng.huang 2025-06-20 14:30:42 +08:00
parent a3330deff9
commit 394185218f
10 changed files with 790 additions and 29 deletions

View File

@ -48,6 +48,10 @@ public interface AutomationRequestCmd {
String PRESS_HOME_KEY = "press_home_key"; //点击home键
String PRESS_BACK_KEY = "press_back_key"; //点击返回键
String PRESS_APP_SWITCH_KEY = "press_app_switch_key"; //点击多任务键
String INPUT_PASSWORD_BY_OCR = "input_password_by_ocr"; //输入密码ocr
String GET_ELEMENT_MONEY_TEXT = "get_element_money_text"; //识别金额

View File

@ -48,6 +48,10 @@ public interface AutomationRequestCmd {
String PRESS_HOME_KEY = "press_home_key"; //点击home键
String PRESS_BACK_KEY = "press_back_key"; //点击返回键
String PRESS_APP_SWITCH_KEY = "press_app_switch_key"; //点击多任务键
String INPUT_PASSWORD_BY_OCR = "input_password_by_ocr"; //输入密码ocr
String GET_ELEMENT_MONEY_TEXT = "get_element_money_text"; //识别金额

View File

@ -2,6 +2,7 @@ package net.northking.cctp.upperComputer.automation.handler;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.automation.constants.AutomationRequestCmd;
import net.northking.cctp.upperComputer.automation.constants.UpperParamKey;
@ -22,6 +23,7 @@ import net.northking.cctp.upperComputer.utils.deviceHepler.DeviceHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import javax.imageio.ImageIO;
import javax.websocket.Session;
@ -104,6 +106,10 @@ public abstract class AbstractAutomationHandler implements AutomationMessageHand
handleApp(request);
} else if (AutomationRequestCmd.PRESS_HOME_KEY.equals(cmd)) {
pressHomeKey(request);
} else if (AutomationRequestCmd.PRESS_BACK_KEY.equals(cmd)){
pressBack(request);
}else if (AutomationRequestCmd.PRESS_APP_SWITCH_KEY.equals(cmd)){
pressAppSwitch(request);
} else if (AutomationRequestCmd.INPUT_PASSWORD_BY_OCR.equals(cmd)) {
inputPasswordByOcr(request);
} else if (AutomationRequestCmd.GET_ELEMENT_MONEY_TEXT.equals(cmd)) {
@ -486,4 +492,94 @@ public abstract class AbstractAutomationHandler implements AutomationMessageHand
}
}
@Override
public void getTextDirectionText(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "获取指定文字指定方向的内容失败");
String value = "";
try {
Map<String, Object> data = request.getData();
String text = (String) data.get(UpperParamKey.INPUT_TEXT);
Integer index = (Integer) data.get(UpperParamKey.INDEX);
String direction = (String) data.get(UpperParamKey.DIRECTION);
String imgBase64 = getClickTextOcrAreaToBase64(request);
if (StringUtils.isBlank(imgBase64)) {
response = CmdAutomationResponse.builderFailure(request, "未获取到ocr区域");
}
JSONObject ocrResultMap = ocrHelper.getTextDirectionText(imgBase64, text, direction, index);
if (null != ocrResultMap) {
JSONObject target_boxes = ocrResultMap.getJSONObject("target_boxes");
logger.info("target_boxes为{}", JSON.toJSONString(target_boxes));
if ("右".equals(direction) || "左".equals(direction)) {
if (null != target_boxes) {
String targetText = (String) target_boxes.get("text");
if (StringUtils.isNotBlank(targetText)) {
int targetIndex = targetText.indexOf(text);
if ("右".equals(direction) && targetIndex < (targetText.length() - text.length())) {
value = targetText.substring(targetIndex + text.length());
} else if ("左".equals(direction) && targetIndex > 0) {
value = targetText.substring(0, targetIndex);
}
}
}
}
if (StringUtils.isBlank(value)) {
try {
JSONObject neighbor_boxes = ocrResultMap.getJSONObject("neighbor_boxes");
logger.info("neighbor_boxes为{}", JSON.toJSONString(neighbor_boxes));
if (null != neighbor_boxes) {
String neighborText = (String) neighbor_boxes.get("text");
value = neighborText;
}
} catch (Exception e) {
JSONArray neighbor_boxes = ocrResultMap.getJSONArray("neighbor_boxes");
if (!CollectionUtils.isEmpty(neighbor_boxes)) {
value = (String) ((Map<String, Object>) neighbor_boxes.get(0)).get("text");
}
}
}
}
logger.info("获取指定文字指定方向的内容为:{}", value);
response = CmdAutomationResponse.builderSuccess(request, "获取指定文字指定方向的内容成功").withData(value);
} catch (Exception e) {
logger.error("识别失败,原因:", e);
response = CmdAutomationResponse.builderFailure(request, e.getMessage());
} finally {
sendResultToEngine(response);
}
}
@Override
public void getVerificationCodeByOcr(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取验证码失败").withData(null);
try {
String value = null;
Map<String, Object> requestData = request.getData();
String targetBase64 = "";
if (requestData.get(UpperParamKey.X) != null) {
targetBase64 = getOcrAreaToBase64(request);
} else {
targetBase64 = getClickTextOcrAreaToBase64(request);
}
if (StringUtils.isBlank(targetBase64)) {
response = CmdAutomationResponse.builderSuccess(request, "未获取到ocr区域").withData(null);
return;
}
Map<String, Object> data = request.getData();
Integer codeType = (Integer) data.get(UpperParamKey.CODE_TYPE);
value = ocrHelper.getVerificationCodeByBase64(targetBase64, codeType);
if (StringUtils.isNotBlank(value)) {
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值成功").withData(value);
} else {
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值失败").withData(null);
}
} catch (Exception e) {
logger.error("根据ocr获取验证码失败原因", e);
response = CmdAutomationResponse.builderSuccess(request, e.getMessage()).withData(null);
} finally {
sendResultToEngine(response);
}
}
}

View File

@ -111,11 +111,6 @@ public class AndroidAutomationHandler extends AbstractAutomationHandler{
}
@Override
public void getVerificationCodeByOcr(CmdAutomationRequest request) {
}
@Override
public void longPress(CmdAutomationRequest request) {
@ -202,7 +197,12 @@ public class AndroidAutomationHandler extends AbstractAutomationHandler{
}
@Override
public void getTextDirectionText(CmdAutomationRequest request) {
public void pressBack(CmdAutomationRequest request) {
}
@Override
public void pressAppSwitch(CmdAutomationRequest request) {
}

View File

@ -72,6 +72,10 @@ public interface AutomationMessageHandler {
void pressHomeKey(CmdAutomationRequest request); //点击home键
void pressBack(CmdAutomationRequest request); //点击home键
void pressAppSwitch(CmdAutomationRequest request); //点击home键
void inputPasswordByOcr(CmdAutomationRequest request); //密码输入ocr
void getElementMoneyText(CmdAutomationRequest request); //识别金额

View File

@ -1,5 +1,8 @@
package net.northking.cctp.upperComputer.automation.handler;
import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.automation.constants.Command;
import net.northking.cctp.upperComputer.automation.constants.UpperParamKey;
import net.northking.cctp.upperComputer.automation.entity.CmdAutomationRequest;
@ -20,6 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@ -30,6 +34,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -381,12 +386,41 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
@Override
public void getVerificationCodeByNode(CmdAutomationRequest request) {
}
@Override
public void getVerificationCodeByOcr(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderSuccess(request, "根据ui节点获取验证码失败").withData(null);
try {
String value = null;
String targetBase64 = "";
NodeList nodeList = findElementByXml(request);
if (null == nodeList || nodeList.getLength() <= 0 ) {
response = CmdAutomationResponse.builderSuccess(request, "验证码元素不存在").withData(null);
} else {
Element item = (Element) nodeList.item(0);
Integer width = Integer.parseInt(item.getAttribute("width"));
Integer height = Integer.parseInt(item.getAttribute("height"));
Integer realityX = Integer.parseInt(item.getAttribute("x"));
Integer realityY = Integer.parseInt(item.getAttribute("y"));
logger.debug("设备:{},步骤:{}找到验证码元素->x:{},y:{},width:{},height:{}",this.serial,request.getStepToken(),realityX,realityY,width,height);
File screenShotFile = deviceHandleHelper.getScreenShotFile(this.serial, realityX, realityY, width, height);
targetBase64 = Base64.encode(screenShotFile);
}
if (StringUtils.isBlank(targetBase64)) {
response = CmdAutomationResponse.builderSuccess(request, "未获取到ocr区域").withData(null);
return;
}
Map<String, Object> data = request.getData();
Integer codeType = (Integer) data.get(UpperParamKey.CODE_TYPE);
value = ocrHelper.getVerificationCodeByBase64(targetBase64, codeType);
if (StringUtils.isNotBlank(value)) {
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值成功").withData(value);
} else {
response = CmdAutomationResponse.builderSuccess(request, "根据ocr获取控件值失败").withData(null);
}
} catch (Exception e) {
logger.error("根据ocr获取验证码失败原因", e);
response = CmdAutomationResponse.builderSuccess(request, e.getMessage()).withData(null);
} finally {
sendResultToEngine(response);
}
}
@Override
@ -674,6 +708,10 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "点击home键失败").withData(false);
try {
HarmonyProvider harmonyProvider = getHarmonyProvider();
if (null == harmonyProvider) {
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
return;
}
boolean success = harmonyProvider.pressHome();
if (success) {
response = CmdAutomationResponse.builderSuccess(request, "点击home键成功").withData(true);
@ -688,18 +726,184 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
}
}
@Override
public void pressBack(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "点击返回键失败").withData(false);
try {
HarmonyProvider harmonyProvider = getHarmonyProvider();
if (null == harmonyProvider) {
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
return;
}
boolean success = harmonyProvider.pressBack();
if (success) {
response = CmdAutomationResponse.builderSuccess(request, "点击返回键成功").withData(true);
} else {
response = CmdAutomationResponse.builderFailure(request, "点击返回键失败");
}
} catch (Exception e) {
logger.error("点击返回键失败,原因:", e);
response = CmdAutomationResponse.builderFailure(request, e.getMessage());
} finally {
sendResultToEngine(response);
}
}
@Override
public void pressAppSwitch(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "点击多任务键失败").withData(false);
try {
HarmonyProvider harmonyProvider = getHarmonyProvider();
if (null == harmonyProvider) {
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
return;
}
int height = this.screenInfo.getHeight();
harmonyProvider.touchDown(200, height-10);
Thread.sleep(200);
for (float i = 0.01f; i <= 1; i +=0.01) {
Float y = height - 10 - i * 300;
harmonyProvider.touchMove(200, y.intValue());
Thread.sleep(5);
}
Thread.sleep(200);
boolean success = harmonyProvider.touchUp(200, height - 10 - 300);
if (success) {
response = CmdAutomationResponse.builderSuccess(request, "点击多任务键成功").withData(true);
} else {
response = CmdAutomationResponse.builderFailure(request, "点击多任务键失败");
}
} catch (Exception e) {
logger.error("点击多任务键失败,原因:", e);
response = CmdAutomationResponse.builderFailure(request, e.getMessage());
} finally {
sendResultToEngine(response);
}
}
@Override
public void pressAndSwipe(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "滑动解锁失败").withData(false);
boolean success = false;
Map<String, Object> data = request.getData();
try {
String[] pointXpath = new String[3];
JSONObject xpathObject = JSON.parseObject((String) data.get(UpperParamKey.FIRST_POINT), JSONObject.class);
pointXpath[0] = xpathObject.getString("selector");
xpathObject = JSON.parseObject((String) data.get(UpperParamKey.SECOND_POINT), JSONObject.class);
pointXpath[1] = xpathObject.getString("selector");
xpathObject = JSON.parseObject((String) data.get(UpperParamKey.THIRD_POINT), JSONObject.class);
pointXpath[2] = xpathObject.getString("selector");
Integer num = (Integer) data.get(UpperParamKey.POINT_NUM);
List<Integer> passPoint = (List<Integer>) data.get(UpperParamKey.SWIPE_POINT);
Integer waitTimeOut = (Integer) data.get(UpperParamKey.WAIT_TIMEOUT);
logger.debug("拿到的左上角的点:{}", pointXpath[0]);
logger.debug("拿到的左上角的右边点:{}", pointXpath[1]);
logger.debug("拿到的左上角的下边点:{}", pointXpath[2]);
logger.debug("拿到的每行每列的点数:{}", num);
logger.debug("拿到的经过的点:{}", JSON.toJSONString(passPoint));
long startTime = System.currentTimeMillis();
long endTime = startTime;
logger.debug("步骤:{}开始查找控件,超时时间:{}", request.getStepToken(), waitTimeOut);
Map<String, Integer>[] point = new Map[3];
int index = 0;
int findIndex = 1;
HarmonyProvider harmonyProvider = getHarmonyProvider();
if (null == harmonyProvider) {
response = CmdAutomationResponse.builderFailure(request, "设备与上位机连接断开");
return;
}
NodeList nodeList = null;
do {
UiComponent uiComponent = harmonyProvider.captureLayout();
Document document = builder.newDocument();
Node xmlElement = uiComponent.createXMLElement(document);
document.appendChild(xmlElement);
try {
nodeList = findNode(pointXpath[index], document);
} catch (XPathExpressionException e) {
logger.error("步骤:{}xpath格式不对{}",request.getStepToken(),pointXpath[index]);
}
logger.debug("步骤:{},第{}次开始查找第{}个元素", request.getStepToken(), findIndex, index + 1);
endTime = System.currentTimeMillis();
findIndex++;
if (null != nodeList) {
Element node = (Element) nodeList.item(0);
logger.debug("步骤:{},第{}次开始查找第{}个元素已经找到", request.getStepToken(), findIndex, index + 1);
int x = Integer.parseInt(node.getAttribute("x"));
int y = Integer.parseInt(node.getAttribute("y"));
Integer width = Integer.parseInt(node.getAttribute("width"));
Integer height = Integer.parseInt(node.getAttribute("height"));
Map<String, Integer> perPoint = new HashMap<>();
perPoint.put("x", x + width / 2);
perPoint.put("y", y + height / 2);
point[index] = perPoint;
index++;
findIndex = 1;
}
} while ((endTime - startTime) < waitTimeOut * 1000 && index < 3);
for (int i = 0; i < 3; i++) {
if (point[i] == null) {
response = CmdAutomationResponse.builderFailure(request, "定位解锁区域的点不全").withData(false);
return;
}
}
//计算每个点的坐标
int perWidth = point[1].get("x") - point[0].get("x");
int perHeight = point[2].get("y") - point[0].get("y");
List<Map<String, Integer>> pointList = new ArrayList<>();
int n = 1;
for (int i = 0; i < num; i++) {
int pointY = point[0].get("y") + i * perHeight; //每一行的y坐标
for (int j = 0; j < num; j++) {
int pointX = point[0].get("x") + j * perWidth;
logger.info("第{}个点的坐标x:{},y:{}", n, pointX, pointY);
Map<String, Integer> perPoint = new HashMap<>();
perPoint.put("x", pointX);
perPoint.put("y", pointY);
pointList.add(n - 1, perPoint);
n++;
}
}
logger.info("token:{},滑动解锁的所有坐标集合:{}", request.getStepToken(), JSON.toJSONString(pointList));
//开始滑动
if (!CollectionUtils.isEmpty(passPoint)) {
Integer startIndex = passPoint.get(0);
Map<String, Integer> startPoint = pointList.get(startIndex - 1);
harmonyProvider.touchDown(startPoint.get("x"), startPoint.get("y"));
for (int i = 1; i < passPoint.size(); i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
return;
}
Integer passIndex = passPoint.get(i);
Map<String, Integer> pointMessage = pointList.get(passIndex - 1);
harmonyProvider.touchMove(pointMessage.get("x"), pointMessage.get("y"));
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
return;
}
Integer endIndex = passPoint.get(passPoint.size() - 1);
Map<String, Integer> endPoint = pointList.get(endIndex - 1);
success = harmonyProvider.touchUp(endPoint.get("x"), endPoint.get("y"));
} else {
logger.warn("token:{},没有滑动通过的坐标", request.getStepToken());
}
logger.info("token:{},滑动解锁的结果:{}", request.getStepToken(), success);
if (success) {
response = CmdAutomationResponse.builderSuccess(request, "滑动解锁成功").withData(success);
} else {
response = CmdAutomationResponse.builderFailure(request, "滑动解锁失败").withData(success);
}
} finally {
sendResultToEngine(response);
}
}
@Override
public void getTextDirectionText(CmdAutomationRequest request) {
}
@Override
public void inputPasswordByOcr(CmdAutomationRequest request) {
@ -821,9 +1025,6 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
private HarmonyProvider getHarmonyProvider() {
HarmonyProvider provider = HarmonyDeviceManager.getInstance().getCurrentDeviceProvider(this.serial);
if (null == provider) {
throw new ExecuteException("当前设备已经掉线,请检查设备");
}
return provider;
}
@ -902,11 +1103,14 @@ public class HarmonyAutomationHandler extends AbstractAutomationHandler {
boolean alreadyFind = false;
int screenIndex = 1;
NodeList nodeList = null;
HarmonyProvider harmonyProvider = getHarmonyProvider();
if (null == harmonyProvider) {
return null;
}
while (!alreadyFind) {
int findIndex = 1;
do {
logger.debug("步骤:{},第{}屏,第{}次开始查找元素", request.getStepToken(), screenIndex, findIndex);
HarmonyProvider harmonyProvider = getHarmonyProvider();
UiComponent uiComponent = harmonyProvider.captureLayout();
Document document = builder.newDocument();
Node xmlElement = uiComponent.createXMLElement(document);

View File

@ -1699,6 +1699,16 @@ public class IosAutomationHandler extends AbstractAutomationHandler {
}
@Override
public void pressBack(CmdAutomationRequest request) {
}
@Override
public void pressAppSwitch(CmdAutomationRequest request) {
}
@Override
public void inputPasswordByOcr(CmdAutomationRequest request) {
CmdAutomationResponse response = CmdAutomationResponse.builderFailure(request, "密码输入ocr失败").withData(false);

View File

@ -243,7 +243,7 @@ public class HarmonyMessageHandlerThread extends AbstractMessageHandler{
success = harmonyProvider.pressHome();
break;
case "appSwitch":
success = harmonyProvider.pressRecentApp();
success = pressRecentApp(harmonyProvider);
break;
case "back":
success = harmonyProvider.pressBack();
@ -267,6 +267,24 @@ public class HarmonyMessageHandlerThread extends AbstractMessageHandler{
logger.warn("设备【{}】热键【{}】操控失败............................",this.serial,key);
}
}
private boolean pressRecentApp(HarmonyProvider harmonyProvider) {
boolean success = false;
int height = catchParam.getRealHeight();
try {
harmonyProvider.touchDown(200, height-10);
Thread.sleep(200);
for (float i = 0.01f; i <= 1; i +=0.01) {
Float y = height - 10 - i * 300;
harmonyProvider.touchMove(200, y.intValue());
Thread.sleep(5);
}
Thread.sleep(200);
success = harmonyProvider.touchUp(200, height - 10 - 300);
} catch (InterruptedException e) {
}
return success;
}
@Override
public void inputType(CmdRequest request) {

View File

@ -601,5 +601,392 @@ public class HnosTools {
return success;
}
/**
* <p>if</p>
*
* @param deviceDriver
* @param targets
* @param waitTimeout
* @param waitStatusStr
* @param swipe
* @param swipeCount
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "if存在控件执行点击", category = "0", attributes = "7", commonlyUse = true)
@Return(name = "result", comment = "点击结果", type = DataType.BOOLEAN)
public boolean clickIfExistElement(IExecuteContext context,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
@Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, required = false, defaultValue = "0", inputType = InputType.select, defaultDisplay = false) String swipe,
@Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
// @Argument(name = "xMove", scope = ParamScope.ARGS, comment = "水平偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer xMove,
// @Argument(name = "yMove", scope = ParamScope.ARGS, comment = "垂直偏移量", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer yMove,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait,
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "", required = false) String value
) {
// 前端如果不选择元素,抛出异常
if (CollectionUtils.isEmpty(targets)) {
throw new ExecuteException("元素属性值为空!");
}
Boolean success = false;
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.withTargets(targets)
.waitTimeout(waitTimeout)
.searchSwipeDirection(swipe)
.withSwipeCount(swipeCount)
.waitStatus(waitStatus);
success = AutomationHandleUtil.clickElement(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
}
if (success != null && !StringUtils.isEmpty(value)) {
CommonUtils.setParamValue(context,value,success.toString());
}
return success;
}
/**
* <p>if</p>
*
* @param text
* @param cleanStr 0-1-
* @param deviceDriver
* @param targets
* @param waitTimeout
* @param waitStatusStr
* @param swipe 0-up-down-left-,right-
* @param swipeCount
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "if存在控件执行输入文本", category = "0", attributes = "7", commonlyUse = true)
@Return(name = "result", comment = "输入的结果", type = DataType.BOOLEAN)
public boolean inputIfExistElement(IExecuteContext context,
@Argument(name = "text", scope = ParamScope.VARIABLES, comment = "输入的文本", type = DataType.STRING) String text,
@Argument(name = "clean", scope = ParamScope.ARGS, comment = "是否清空输入框", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String cleanStr,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
@Argument(name = "swipe", scope = ParamScope.ARGS, comment = "滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "0", required = false, defaultDisplay = false) String swipe,
@Argument(name = "swipeCount", scope = ParamScope.ARGS, comment = "滑动次数", type = DataType.INTEGER, required = false, defaultValue = "0", defaultDisplay = false) Integer swipeCount,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait,
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "", required = false) String value
) {
// 前端如果不选择元素,抛出异常
if (CollectionUtils.isEmpty(targets)) {
throw new ExecuteException("元素属性值为空!");
}
Boolean success = false;
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
boolean clear = "1".equals(cleanStr); //是否清除文本框
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.withTargets(targets)
.waitTimeout(waitTimeout)
.searchSwipeDirection(swipe)
.withSwipeCount(swipeCount)
.clear(clear)
.withInputTextValue(text)
.waitStatus(waitStatus);
success = AutomationHandleUtil.elementInput(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
}
if (success != null && !StringUtils.isEmpty(value)) {
CommonUtils.setParamValue(context,value,success.toString());
}
return success;
}
/**
*
* @param context
* @param direction
* @param deviceDriver
* @param targets
* @param referencesStr
* @param waitTimeout
* @param index
* @param waitStatusStr
* @param value
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "滑动查找控件", category = "0", attributes = "7",commonlyUse = true)
@Return(name = "result", comment = "滑动的结果", type = DataType.OBJECT)
public boolean swipeAndFindTargetElement(IExecuteContext context,
@Argument(name = "direction", scope = ParamScope.ARGS, comment = "控件滑动方向", type = DataType.ENUM, enumValues = SwipeDirection.class, inputType = InputType.select, defaultValue = "up") String direction,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "targets", scope = ParamScope.STEP, comment = "目标元素", type = DataType.LIST, defaultDisplay = false,inputType = InputType.element) List<IStepTarget> targets,
@Argument(name = "references", scope = ParamScope.ARGS, comment = "滑动元素", type = DataType.LIST, defaultDisplay = false, required = false,inputType = InputType.element) String referencesStr,
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
@Argument(name = "index", scope = ParamScope.ARGS, comment = "多个时定位第几个", type = DataType.INTEGER, defaultValue = "1",defaultDisplay = false) Integer index,
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值",required = false, type = DataType.STRING, defaultValue = "") String value,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
logger.debug("拿到的reference为{}",referencesStr);
Boolean result = null;
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.withTargets(targets)
.waitTimeout(waitTimeout)
.searchSwipeDirection("0") //不滑动
.withSwipeCount(1)
.waitStatus(waitStatus)
.swipeDirection(direction)
.withIndex(index)
.withReferences(referencesStr);
result = AutomationHandleUtil.swipeAndFindTargetElement(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
if (result != null && !StringUtils.isEmpty(value)) {
CommonUtils.setParamValue(context,value,result.toString());
}
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
throw new ExecuteException(e.getMessage());
}
return result;
}
/**
* <p></p>
*
* @param context
* @param deviceDriver
* @param firstPointStr
* @param secondPointStr
* @param thirdPointStr
* @param pointNum
* @param passingPoints [1,3,5,6]
* @param waitTime
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "滑动解锁", category = "0", attributes = "7", commonlyUse = true)
@Return(name = "result", comment = "是否滑动成功", type = DataType.BOOLEAN)
public Boolean pressAndSwipe(
IExecuteContext context,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "firstPoint", scope = ParamScope.ARGS, comment = "第一排第一个点", type = DataType.LIST, defaultDisplay = true,inputType = InputType.element) String firstPointStr,
@Argument(name = "secondPoint", scope = ParamScope.ARGS, comment = "第一排第二个点", type = DataType.LIST, defaultDisplay = true,inputType = InputType.element) String secondPointStr,
@Argument(name = "thirdPoint", scope = ParamScope.ARGS, comment = "第二排第一个点", type = DataType.LIST, defaultDisplay = true,inputType = InputType.element) String thirdPointStr,
@Argument(name = "pointNum", scope = ParamScope.ARGS, comment = "每一行、列的点数", type = DataType.INTEGER, defaultDisplay = false,defaultValue = "3") Integer pointNum,
@Argument(name = "passingPoints", scope = ParamScope.ARGS, comment = "经过的点", type = DataType.LIST, defaultDisplay = true) List<Integer> passingPoints,
@Argument(name = "waitTime", scope = ParamScope.ARGS, comment = "等待时间(单位s)", type = DataType.INTEGER, defaultValue = "30") Integer waitTime,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
) {
Boolean result = false;
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.waitTimeout(waitTime)
.withPassingPoints(passingPoints)
.withPointData(firstPointStr, secondPointStr, thirdPointStr)
.withPointNum(pointNum);
result = AutomationHandleUtil.pressAndSwipe(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
throw new ExecuteException(e.getMessage());
}
return result;
}
/**
* <p></p>
*
* @param direction
* @param deviceDriver
* @param waitTimeout
* @param text
* @param direction
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "获取指定文字指定方向的内容", category = "0", attributes = "7")
@Return(name = "result", comment = "返回的结果", type = DataType.BOOLEAN)
public String getTextDirectionText(IExecuteContext context,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
@Argument(name = "index", scope = ParamScope.ARGS, comment = "第几个", type = DataType.INTEGER, defaultValue = "1") Integer index,
@Argument(name = "text", comment = "指定文本", scope = ParamScope.ARGS, type = DataType.STRING) String text,
@Argument(name = "direction", scope = ParamScope.ARGS, comment = "指定方向", type = DataType.ENUM, enumValues = TextDirection.class, inputType = InputType.select, defaultValue = "右") String direction,
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait) {
String result = "";
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.withText(text)
.withIndex(index)
.waitTimeout(waitTimeout)
.withDirection(direction);
result = AutomationHandleUtil.getTextDirectionText(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
CommonUtils.setParamValue(context, value, result);
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
throw new ExecuteException(e.getMessage());
}
return result;
}
/**
* <p></p>
*
* @param deviceDriver
* @param targets
* @param waitTimeout
* @param value
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "识别验证码", category = "0", attributes = "7")
@Return(name = "result", comment = "验证码识别", type = DataType.STRING)
public String getCodeByOcr(
IExecuteContext context,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "targets", scope = ParamScope.STEP, comment = "控件位置", type = DataType.LIST, defaultDisplay = false) List<IStepTarget> targets,
@Argument(name = "codeType", scope = ParamScope.ARGS, comment = "验证码类型", type = DataType.INTEGER, required = false, defaultValue = "1", defaultDisplay = false) Integer codeType,
@Argument(name = "timeout", scope = ParamScope.ARGS, comment = "默认超时时间", type = DataType.INTEGER, required = false, defaultValue = "30", defaultDisplay = false) Integer waitTimeout,
@Argument(name = "value", scope = ParamScope.OUTPUT, comment = "组件返回值", type = DataType.STRING, defaultValue = "") String value,
@Argument(name = "waitStatus", scope = ParamScope.ARGS, comment = "等待界面稳定", type = DataType.ENUM, enumValues = WhetherOrNotEnum.class, inputType = InputType.select, defaultValue = "1", defaultDisplay = false) String waitStatusStr,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "1.0", defaultDisplay = false) Float sufExecuteWait
) {
String result = "";
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
boolean waitStatus = "1".equals(waitStatusStr); //是否等待界面稳定
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.withTargets(targets)
.waitTimeout(waitTimeout)
.codeType(codeType)
.searchSwipeDirection("0") //不滑动
.withSwipeCount(1)
.waitStatus(waitStatus);
result = AutomationHandleUtil.getVerificationCode(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
CommonUtils.setParamValue(context, value, result);
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
throw new ExecuteException(e.getMessage());
}
return result;
}
/**
* <p></p>
*
* @param deviceDriver
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "点击返回键", category = "0", attributes = "7", commonlyUse = true)
@Return(name = "result", comment = "点击返回键", type = DataType.BOOLEAN)
public boolean pressKeyBack(IExecuteContext context,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait) {
boolean success = false;
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.waitTimeout(30);
success = AutomationHandleUtil.pressBack(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
throw new ExecuteException(e.getMessage());
}
return success;
}
/**
* <p></p>
*
* @param deviceDriver
* @param preExecuteWait
* @param sufExecuteWait
* @return
*/
@Keyword(alias = "点击多任务", category = "0", attributes = "7", commonlyUse = true)
@Return(name = "result", comment = "点击多任务", type = DataType.BOOLEAN)
public boolean pressKeyMenu(IExecuteContext context,
@Argument(name = "__deviceDriver", scope = ParamScope.CONTEXT, comment = "设备连接", type = DataType.OBJECT) DeviceDriver deviceDriver,
@Argument(name = "preExecuteWait", scope = ParamScope.ARGS, comment = "执行前等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float preExecuteWait,
@Argument(name = "sufExecuteWait", scope = ParamScope.ARGS, comment = "执行后等待(单位:s)", type = DataType.INTEGER, required = false, defaultValue = "0.0", defaultDisplay = false) Float sufExecuteWait) {
boolean success = false;
try {
CommonUtils.handlePreExecuteWait(preExecuteWait); //执行前等待
ElementHandleParam param = ElementHandleParam.builder(deviceDriver)
.useContext(context)
.waitTimeout(30);
success = AutomationHandleUtil.pressAppSwitch(param);
CommonUtils.handleSufExecuteWait(sufExecuteWait); //执行后等待
} catch (InterruptedException ie) {
logger.warn("用户取消查询元素");
throw new ExecuteException("取消操作");
} catch (Exception e) {
logger.error("出现了其他的问题。。。。", e);
throw new ExecuteException(e.getMessage());
}
return success;
}
}

View File

@ -428,6 +428,10 @@ public class AutomationHandleUtil {
logger.warn("不支持的查找元素方式:{}", target.getUsing());
break;
}
if (null != point) {
logger.debug("使用【{}】方式找到了控件",target.getUsing());
break;
}
}
return point;
}
@ -799,6 +803,30 @@ public class AutomationHandleUtil {
return success;
}
public static boolean pressBack(ElementHandleParam param) throws Exception {
Boolean success = false;
String token = UUID.randomUUID().toString();
CmdAutomationRequest builder = CmdAutomationRequest.builder(AutomationRequestCmd.PRESS_BACK_KEY, token, new HashMap<>());
Object o = sendUpperMessageAndWaitReturn(param.getDeviceDriver(), builder, token, param.getWaitTimeout());
logger.debug("点击返回键的结果:{}",o);
if (null != o) {
success = JSONObject.parseObject(JSONObject.toJSONString(o), Boolean.class);
}
return success;
}
public static boolean pressAppSwitch(ElementHandleParam param) throws Exception {
Boolean success = false;
String token = UUID.randomUUID().toString();
CmdAutomationRequest builder = CmdAutomationRequest.builder(AutomationRequestCmd.PRESS_APP_SWITCH_KEY, token, new HashMap<>());
Object o = sendUpperMessageAndWaitReturn(param.getDeviceDriver(), builder, token, param.getWaitTimeout());
logger.debug("点击多任务键的结果:{}",o);
if (null != o) {
success = JSONObject.parseObject(JSONObject.toJSONString(o), Boolean.class);
}
return success;
}
private static boolean longPressElementByPoint(DeviceDriver deviceDriver, PointMessage point, Integer waitTimeout) throws Exception{
Boolean success = false;
String token = UUID.randomUUID().toString();
@ -1165,7 +1193,7 @@ public class AutomationHandleUtil {
if (null == waitTimeout || waitTimeout <= 0) {
param.setWaitTimeout(30);
}
long startTime = System.currentTimeMillis();
String referenceStr = param.getReferences();
logger.debug("执行滑动查找控件的操作,滑动控件:{}", referenceStr);
PointMessage point = null;
@ -1182,22 +1210,28 @@ public class AutomationHandleUtil {
}
}
logger.debug("找到要滑动的控件位置:{}",JSON.toJSONString(point));
PointMessage targetPoint = swipeToFindTargetElement(point, param.getContext(), param.getDeviceDriver(), param.getTargets(), param.getWaitTimeout(),
long endTime = System.currentTimeMillis();
long remainingTime = param.getWaitTimeout() * 1000 - (endTime - startTime);
PointMessage targetPoint = swipeToFindTargetElement(point, param.getContext(), param.getDeviceDriver(), param.getTargets(), remainingTime,
param.getSwipeDirection(), param);
getRedDotScreenShotWithPoint(param, point);
return targetPoint != null;
}
private static PointMessage swipeToFindTargetElement(PointMessage swipePoint, IExecuteContext context, DeviceDriver driver, List<IStepTarget> targets, Integer waitTimeout, String direction, ElementHandleParam param) throws Exception{
private static PointMessage swipeToFindTargetElement(PointMessage swipePoint, IExecuteContext context, DeviceDriver driver, List<IStepTarget> targets, Long waitTimeout, String direction, ElementHandleParam param) throws Exception{
logger.debug("执行滑动查找控件的操作,目标控件:{}", JSON.toJSONString(targets));
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis();
PointMessage targetPoint = null;
Double perWaiTimeOut = waitTimeout.doubleValue() / 1000 / 5;
if (perWaiTimeOut < 3) {
perWaiTimeOut = 3.0;
}
int num = 1;
do {
logger.debug("开始第{}次查找", num);
try {
targetPoint = findElementByTargetsForSwipe(param.getDeviceDriver(), param.getTargets(), 30, param.getSwipe(), param.getSwipeCount(), 1);
targetPoint = findElementByTargetsForSwipe(param.getDeviceDriver(), param.getTargets(), perWaiTimeOut.intValue(), param.getSwipe(), param.getSwipeCount(), 1);
} catch (Exception ignore) {
logger.error(ignore.getMessage());
}
@ -1208,7 +1242,7 @@ public class AutomationHandleUtil {
}
num++;
endTime = System.currentTimeMillis();
} while (targetPoint == null && endTime - startTime < waitTimeout * 1000);
} while (targetPoint == null && endTime - startTime < waitTimeout);
logger.debug("在规定的时间内查找的结果:{}", JSON.toJSONString(targetPoint));
return targetPoint;
}
@ -1227,8 +1261,8 @@ public class AutomationHandleUtil {
String token = UUID.randomUUID().toString();
Map<String, Object> paramMap = new HashMap<>();
if (swipePoint != null) {
Integer x = swipePoint.getXOriginal();
Integer y = swipePoint.getYOriginal();
Integer x = swipePoint.getX();
Integer y = swipePoint.getY();
paramMap.put(UpperParamKey.X, x);
paramMap.put(UpperParamKey.Y, y);
paramMap.put(UpperParamKey.SWIPE_DIRECTION, direction);