浏览代码

增加群控管理功能

xuzuoyun 5 年之前
父节点
当前提交
c99848c86e
共有 31 个文件被更改,包括 3379 次插入5 次删除
  1. 1 1
      jeecg-boot-module-system/src/main/resources/jeecg/jeecg_config.properties
  2. 253 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumDeviceController.java
  3. 253 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskController.java
  4. 253 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskItemController.java
  5. 67 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumDevice.java
  6. 67 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTask.java
  7. 139 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTaskItem.java
  8. 18 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumDeviceMapper.java
  9. 18 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskItemMapper.java
  10. 18 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskMapper.java
  11. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumDeviceMapper.xml
  12. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskItemMapper.xml
  13. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskMapper.xml
  14. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumDeviceService.java
  15. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskItemService.java
  16. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskService.java
  17. 20 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumDeviceServiceImpl.java
  18. 20 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskItemServiceImpl.java
  19. 20 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskServiceImpl.java
  20. 173 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/AppiumDeviceList.vue
  21. 243 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/AppiumTaskItemList.vue
  22. 173 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/AppiumTaskList.vue
  23. 138 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumDeviceModal.vue
  24. 145 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumDeviceModal__Style#Drawer.vue
  25. 224 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskItemModal.vue
  26. 231 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskItemModal__Style#Drawer.vue
  27. 138 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskModal.vue
  28. 145 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskModal__Style#Drawer.vue
  29. 23 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/test/AppiumTask.java
  30. 530 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/test/AppiumTest.java
  31. 9 4
      pom.xml

+ 1 - 1
jeecg-boot-module-system/src/main/resources/jeecg/jeecg_config.properties

@@ -1,7 +1,7 @@
 #code_generate_project_path
 project_path=D:\\module
 #bussi_package[User defined]
-bussi_package=org.jeecg.modules
+bussi_package=cn.com.ctop.crawler.modules
 #default code path
 #source_root_package=src
 #webroot_package=WebRoot

+ 253 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumDeviceController.java

@@ -0,0 +1,253 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumDevice;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumDeviceService;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 手机设备表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Slf4j
+@Api(tags = "手机设备表")
+@RestController
+@RequestMapping("/appium/appiumDevice")
+public class AppiumDeviceController {
+    @Autowired
+    private IAppiumDeviceService appiumDeviceService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param appiumDevice
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "手机设备表-分页列表查询")
+    @ApiOperation(value = "手机设备表-分页列表查询", notes = "手机设备表-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AppiumDevice>> queryPageList(AppiumDevice appiumDevice,
+                                                     @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                     HttpServletRequest req) {
+        Result<IPage<AppiumDevice>> result = new Result<IPage<AppiumDevice>>();
+        QueryWrapper<AppiumDevice> queryWrapper = QueryGenerator.initQueryWrapper(appiumDevice, req.getParameterMap());
+        Page<AppiumDevice> page = new Page<AppiumDevice>(pageNo, pageSize);
+        IPage<AppiumDevice> pageList = appiumDeviceService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param appiumDevice
+     * @return
+     */
+    @AutoLog(value = "手机设备表-添加")
+    @ApiOperation(value = "手机设备表-添加", notes = "手机设备表-添加")
+    @PostMapping(value = "/add")
+    public Result<AppiumDevice> add(@RequestBody AppiumDevice appiumDevice) {
+        Result<AppiumDevice> result = new Result<AppiumDevice>();
+        try {
+            appiumDeviceService.save(appiumDevice);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param appiumDevice
+     * @return
+     */
+    @AutoLog(value = "手机设备表-编辑")
+    @ApiOperation(value = "手机设备表-编辑", notes = "手机设备表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AppiumDevice> edit(@RequestBody AppiumDevice appiumDevice) {
+        Result<AppiumDevice> result = new Result<AppiumDevice>();
+        AppiumDevice appiumDeviceEntity = appiumDeviceService.getById(appiumDevice.getId());
+        if (appiumDeviceEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = appiumDeviceService.updateById(appiumDevice);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "手机设备表-通过id删除")
+    @ApiOperation(value = "手机设备表-通过id删除", notes = "手机设备表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            appiumDeviceService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "手机设备表-批量删除")
+    @ApiOperation(value = "手机设备表-批量删除", notes = "手机设备表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<AppiumDevice> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AppiumDevice> result = new Result<AppiumDevice>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.appiumDeviceService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "手机设备表-通过id查询")
+    @ApiOperation(value = "手机设备表-通过id查询", notes = "手机设备表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<AppiumDevice> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AppiumDevice> result = new Result<AppiumDevice>();
+        AppiumDevice appiumDevice = appiumDeviceService.getById(id);
+        if (appiumDevice == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(appiumDevice);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<AppiumDevice> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                AppiumDevice appiumDevice = JSON.parseObject(deString, AppiumDevice.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(appiumDevice, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<AppiumDevice> pageList = appiumDeviceService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "手机设备表列表");
+        mv.addObject(NormalExcelConstants.CLASS, AppiumDevice.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("手机设备表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<AppiumDevice> listAppiumDevices = ExcelImportUtil.importExcel(file.getInputStream(), AppiumDevice.class, params);
+                appiumDeviceService.saveBatch(listAppiumDevices);
+                return Result.ok("文件导入成功!数据行数:" + listAppiumDevices.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 253 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskController.java

@@ -0,0 +1,253 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTask;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskService;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 手机任务表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Slf4j
+@Api(tags = "手机任务表")
+@RestController
+@RequestMapping("/appium/appiumTask")
+public class AppiumTaskController {
+    @Autowired
+    private IAppiumTaskService appiumTaskService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param appiumTask
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "手机任务表-分页列表查询")
+    @ApiOperation(value = "手机任务表-分页列表查询", notes = "手机任务表-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AppiumTask>> queryPageList(AppiumTask appiumTask,
+                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                   HttpServletRequest req) {
+        Result<IPage<AppiumTask>> result = new Result<IPage<AppiumTask>>();
+        QueryWrapper<AppiumTask> queryWrapper = QueryGenerator.initQueryWrapper(appiumTask, req.getParameterMap());
+        Page<AppiumTask> page = new Page<AppiumTask>(pageNo, pageSize);
+        IPage<AppiumTask> pageList = appiumTaskService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param appiumTask
+     * @return
+     */
+    @AutoLog(value = "手机任务表-添加")
+    @ApiOperation(value = "手机任务表-添加", notes = "手机任务表-添加")
+    @PostMapping(value = "/add")
+    public Result<AppiumTask> add(@RequestBody AppiumTask appiumTask) {
+        Result<AppiumTask> result = new Result<AppiumTask>();
+        try {
+            appiumTaskService.save(appiumTask);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param appiumTask
+     * @return
+     */
+    @AutoLog(value = "手机任务表-编辑")
+    @ApiOperation(value = "手机任务表-编辑", notes = "手机任务表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AppiumTask> edit(@RequestBody AppiumTask appiumTask) {
+        Result<AppiumTask> result = new Result<AppiumTask>();
+        AppiumTask appiumTaskEntity = appiumTaskService.getById(appiumTask.getId());
+        if (appiumTaskEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = appiumTaskService.updateById(appiumTask);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "手机任务表-通过id删除")
+    @ApiOperation(value = "手机任务表-通过id删除", notes = "手机任务表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            appiumTaskService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "手机任务表-批量删除")
+    @ApiOperation(value = "手机任务表-批量删除", notes = "手机任务表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<AppiumTask> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AppiumTask> result = new Result<AppiumTask>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.appiumTaskService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "手机任务表-通过id查询")
+    @ApiOperation(value = "手机任务表-通过id查询", notes = "手机任务表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<AppiumTask> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AppiumTask> result = new Result<AppiumTask>();
+        AppiumTask appiumTask = appiumTaskService.getById(id);
+        if (appiumTask == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(appiumTask);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<AppiumTask> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                AppiumTask appiumTask = JSON.parseObject(deString, AppiumTask.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(appiumTask, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<AppiumTask> pageList = appiumTaskService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "手机任务表列表");
+        mv.addObject(NormalExcelConstants.CLASS, AppiumTask.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("手机任务表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<AppiumTask> listAppiumTasks = ExcelImportUtil.importExcel(file.getInputStream(), AppiumTask.class, params);
+                appiumTaskService.saveBatch(listAppiumTasks);
+                return Result.ok("文件导入成功!数据行数:" + listAppiumTasks.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 253 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskItemController.java

@@ -0,0 +1,253 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskItemService;
+
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 手机任务步骤表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Slf4j
+@Api(tags = "手机任务步骤表")
+@RestController
+@RequestMapping("/appium/appiumTaskItem")
+public class AppiumTaskItemController {
+    @Autowired
+    private IAppiumTaskItemService appiumTaskItemService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param appiumTaskItem
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "手机任务步骤表-分页列表查询")
+    @ApiOperation(value = "手机任务步骤表-分页列表查询", notes = "手机任务步骤表-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AppiumTaskItem>> queryPageList(AppiumTaskItem appiumTaskItem,
+                                                       @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                       @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                       HttpServletRequest req) {
+        Result<IPage<AppiumTaskItem>> result = new Result<IPage<AppiumTaskItem>>();
+        QueryWrapper<AppiumTaskItem> queryWrapper = QueryGenerator.initQueryWrapper(appiumTaskItem, req.getParameterMap());
+        Page<AppiumTaskItem> page = new Page<AppiumTaskItem>(pageNo, pageSize);
+        IPage<AppiumTaskItem> pageList = appiumTaskItemService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param appiumTaskItem
+     * @return
+     */
+    @AutoLog(value = "手机任务步骤表-添加")
+    @ApiOperation(value = "手机任务步骤表-添加", notes = "手机任务步骤表-添加")
+    @PostMapping(value = "/add")
+    public Result<AppiumTaskItem> add(@RequestBody AppiumTaskItem appiumTaskItem) {
+        Result<AppiumTaskItem> result = new Result<AppiumTaskItem>();
+        try {
+            appiumTaskItemService.save(appiumTaskItem);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param appiumTaskItem
+     * @return
+     */
+    @AutoLog(value = "手机任务步骤表-编辑")
+    @ApiOperation(value = "手机任务步骤表-编辑", notes = "手机任务步骤表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AppiumTaskItem> edit(@RequestBody AppiumTaskItem appiumTaskItem) {
+        Result<AppiumTaskItem> result = new Result<AppiumTaskItem>();
+        AppiumTaskItem appiumTaskItemEntity = appiumTaskItemService.getById(appiumTaskItem.getId());
+        if (appiumTaskItemEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = appiumTaskItemService.updateById(appiumTaskItem);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "手机任务步骤表-通过id删除")
+    @ApiOperation(value = "手机任务步骤表-通过id删除", notes = "手机任务步骤表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            appiumTaskItemService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "手机任务步骤表-批量删除")
+    @ApiOperation(value = "手机任务步骤表-批量删除", notes = "手机任务步骤表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<AppiumTaskItem> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AppiumTaskItem> result = new Result<AppiumTaskItem>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.appiumTaskItemService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "手机任务步骤表-通过id查询")
+    @ApiOperation(value = "手机任务步骤表-通过id查询", notes = "手机任务步骤表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<AppiumTaskItem> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AppiumTaskItem> result = new Result<AppiumTaskItem>();
+        AppiumTaskItem appiumTaskItem = appiumTaskItemService.getById(id);
+        if (appiumTaskItem == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(appiumTaskItem);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<AppiumTaskItem> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                AppiumTaskItem appiumTaskItem = JSON.parseObject(deString, AppiumTaskItem.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(appiumTaskItem, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<AppiumTaskItem> pageList = appiumTaskItemService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "手机任务步骤表列表");
+        mv.addObject(NormalExcelConstants.CLASS, AppiumTaskItem.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("手机任务步骤表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<AppiumTaskItem> listAppiumTaskItems = ExcelImportUtil.importExcel(file.getInputStream(), AppiumTaskItem.class, params);
+                appiumTaskItemService.saveBatch(listAppiumTaskItems);
+                return Result.ok("文件导入成功!数据行数:" + listAppiumTaskItems.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 67 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumDevice.java

@@ -0,0 +1,67 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 手机设备表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Data
+@TableName("ctop_appium_device")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_device对象", description = "手机设备表")
+public class AppiumDevice {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.INPUT)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * ip
+     */
+    @Excel(name = "ip", width = 15)
+    @ApiModelProperty(value = "ip")
+    private String ip;
+    /**
+     * port
+     */
+    @Excel(name = "port", width = 15)
+    @ApiModelProperty(value = "port")
+    private String port;
+    /**
+     * status
+     */
+    @Excel(name = "status", width = 15)
+    @ApiModelProperty(value = "status")
+    private Integer status;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 67 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTask.java

@@ -0,0 +1,67 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 手机任务表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Data
+@TableName("ctop_appium_task")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_task对象", description = "手机任务表")
+public class AppiumTask {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.INPUT)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * taskName
+     */
+    @Excel(name = "taskName", width = 15)
+    @ApiModelProperty(value = "taskName")
+    private String taskName;
+    /**
+     * appPackage
+     */
+    @Excel(name = "appPackage", width = 15)
+    @ApiModelProperty(value = "appPackage")
+    private String appPackage;
+    /**
+     * appActivity
+     */
+    @Excel(name = "appActivity", width = 15)
+    @ApiModelProperty(value = "appActivity")
+    private String appActivity;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 139 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTaskItem.java

@@ -0,0 +1,139 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 手机任务步骤表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Data
+@TableName("ctop_appium_task_item")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_task_item对象", description = "手机任务步骤表")
+public class AppiumTaskItem {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.INPUT)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * taskId
+     */
+    @Excel(name = "taskId", width = 15)
+    @ApiModelProperty(value = "taskId")
+    private Integer taskId;
+    /**
+     * parentId
+     */
+    @Excel(name = "parentId", width = 15)
+    @ApiModelProperty(value = "parentId")
+    private Integer parentId;
+    /**
+     * seq
+     */
+    @Excel(name = "seq", width = 15)
+    @ApiModelProperty(value = "seq")
+    private Integer seq;
+    /**
+     * findType
+     */
+    @Excel(name = "findType", width = 15)
+    @ApiModelProperty(value = "findType")
+    private String findType;
+    /**
+     * findKey
+     */
+    @Excel(name = "findKey", width = 15)
+    @ApiModelProperty(value = "findKey")
+    private String findKey;
+    /**
+     * clickType
+     */
+    @Excel(name = "clickType", width = 15)
+    @ApiModelProperty(value = "clickType")
+    private String clickType;
+    /**
+     * offsiteX
+     */
+    @Excel(name = "offsiteX", width = 15)
+    @ApiModelProperty(value = "offsiteX")
+    private Integer offsiteX;
+    /**
+     * offsiteY
+     */
+    @Excel(name = "offsiteY", width = 15)
+    @ApiModelProperty(value = "offsiteY")
+    private Integer offsiteY;
+    /**
+     * loopRate
+     */
+    @Excel(name = "loopRate", width = 15)
+    @ApiModelProperty(value = "loopRate")
+    private Integer loopRate;
+    /**
+     * isMust
+     */
+    @Excel(name = "isMust", width = 15)
+    @ApiModelProperty(value = "isMust")
+    private Boolean isMust;
+    /**
+     * textEqualType
+     */
+    @Excel(name = "textEqualType", width = 15)
+    @ApiModelProperty(value = "textEqualType")
+    private String textEqualType;
+    /**
+     * textEqualKey
+     */
+    @Excel(name = "textEqualKey", width = 15)
+    @ApiModelProperty(value = "textEqualKey")
+    private String textEqualKey;
+    /**
+     * swapType
+     */
+    @Excel(name = "swapType", width = 15)
+    @ApiModelProperty(value = "swapType")
+    private String swapType;
+    /**
+     * waitTime
+     */
+    @Excel(name = "waitTime", width = 15)
+    @ApiModelProperty(value = "waitTime")
+    private Integer waitTime;
+    /**
+     * isClose
+     */
+    @Excel(name = "isClose", width = 15)
+    @ApiModelProperty(value = "isClose")
+    private Boolean isClose;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 18 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumDeviceMapper.java

@@ -0,0 +1,18 @@
+package cn.com.ctop.crawler.modules.appium.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumDevice;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 手机设备表
+ *
+ * @author: jeecg-boot
+ * @date: 2019-10-30
+ * @cersion: V1.0
+ */
+public interface AppiumDeviceMapper extends BaseMapper<AppiumDevice> {
+
+}

+ 18 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskItemMapper.java

@@ -0,0 +1,18 @@
+package cn.com.ctop.crawler.modules.appium.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 手机任务步骤表
+ *
+ * @author: jeecg-boot
+ * @date: 2019-10-30
+ * @cersion: V1.0
+ */
+public interface AppiumTaskItemMapper extends BaseMapper<AppiumTaskItem> {
+
+}

+ 18 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskMapper.java

@@ -0,0 +1,18 @@
+package cn.com.ctop.crawler.modules.appium.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTask;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 手机任务表
+ *
+ * @author: jeecg-boot
+ * @date: 2019-10-30
+ * @cersion: V1.0
+ */
+public interface AppiumTaskMapper extends BaseMapper<AppiumTask> {
+
+}

+ 5 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumDeviceMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.crawler.modules.appium.mapper.AppiumDeviceMapper">
+
+</mapper>

+ 5 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskItemMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskItemMapper">
+
+</mapper>

+ 5 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskMapper">
+
+</mapper>

+ 15 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumDeviceService.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumDevice;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 手机设备表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+public interface IAppiumDeviceService extends IService<AppiumDevice> {
+
+}

+ 15 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskItemService.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 手机任务步骤表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+public interface IAppiumTaskItemService extends IService<AppiumTaskItem> {
+
+}

+ 15 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskService.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTask;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 手机任务表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+public interface IAppiumTaskService extends IService<AppiumTask> {
+
+}

+ 20 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumDeviceServiceImpl.java

@@ -0,0 +1,20 @@
+package cn.com.ctop.crawler.modules.appium.service.impl;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumDevice;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumDeviceMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumDeviceService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 手机设备表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Service
+public class AppiumDeviceServiceImpl extends ServiceImpl<AppiumDeviceMapper, AppiumDevice> implements IAppiumDeviceService {
+
+}

+ 20 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskItemServiceImpl.java

@@ -0,0 +1,20 @@
+package cn.com.ctop.crawler.modules.appium.service.impl;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskItemMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskItemService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 手机任务步骤表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Service
+public class AppiumTaskItemServiceImpl extends ServiceImpl<AppiumTaskItemMapper, AppiumTaskItem> implements IAppiumTaskItemService {
+
+}

+ 20 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskServiceImpl.java

@@ -0,0 +1,20 @@
+package cn.com.ctop.crawler.modules.appium.service.impl;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTask;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 手机任务表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-10-30
+ */
+@Service
+public class AppiumTaskServiceImpl extends ServiceImpl<AppiumTaskMapper, AppiumTask> implements IAppiumTaskService {
+
+}

+ 173 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/AppiumDeviceList.vue

@@ -0,0 +1,173 @@
+<template>
+    <a-card :bordered="false">
+
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline">
+                <a-row :gutter="24">
+
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="ip">
+                            <a-input placeholder="请输入ip" v-model="queryParam.ip"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="port">
+                            <a-input placeholder="请输入port" v-model="queryParam.port"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <template v-if="toggleSearchStatus">
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="status">
+                                <a-input placeholder="请输入status" v-model="queryParam.status"></a-input>
+                            </a-form-item>
+                        </a-col>
+                    </template>
+                    <a-col :md="6" :sm="8">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+                    </a-col>
+
+                </a-row>
+            </a-form>
+        </div>
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+            <a-button type="primary" icon="download" @click="handleExportXls('手机设备表')">导出</a-button>
+            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader"
+                      :action="importExcelUrl" @change="handleImportExcel">
+                <a-button type="primary" icon="import">导入</a-button>
+            </a-upload>
+            <a-dropdown v-if="selectedRowKeys.length > 0">
+                <a-menu slot="overlay">
+                    <a-menu-item key="1" @click="batchDel">
+                        <a-icon type="delete"/>
+                        删除
+                    </a-menu-item>
+                </a-menu>
+                <a-button style="margin-left: 8px"> 批量操作
+                    <a-icon type="down"/>
+                </a-button>
+            </a-dropdown>
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
+                selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </div>
+
+            <a-table
+                    ref="table"
+                    size="middle"
+                    bordered
+                    rowKey="id"
+                    :columns="columns"
+                    :dataSource="dataSource"
+                    :pagination="ipagination"
+                    :loading="loading"
+                    :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+                    @change="handleTableChange">
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical"/>
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+            </a-table>
+        </div>
+        <!-- table区域-end -->
+
+        <!-- 表单区域 -->
+        <appiumDevice-modal ref="modalForm" @ok="modalFormOk"></appiumDevice-modal>
+    </a-card>
+</template>
+
+<script>
+    import AppiumDeviceModal from './modules/AppiumDeviceModal'
+    import {JeecgListMixin} from '@/mixins/JeecgListMixin'
+
+    export default {
+        name: "AppiumDeviceList",
+        mixins: [JeecgListMixin],
+        components: {
+            AppiumDeviceModal
+        },
+        data() {
+            return {
+                description: '手机设备表管理页面',
+                // 表头
+                columns: [
+                    {
+                        title: '#',
+                        dataIndex: '',
+                        key: 'rowIndex',
+                        width: 60,
+                        align: "center",
+                        customRender: function (t, r, index) {
+                            return parseInt(index) + 1;
+                        }
+                    },
+                    {
+                        title: 'ip',
+                        align: "center",
+                        dataIndex: 'ip'
+                    },
+                    {
+                        title: 'port',
+                        align: "center",
+                        dataIndex: 'port'
+                    },
+                    {
+                        title: 'status',
+                        align: "center",
+                        dataIndex: 'status'
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align: "center",
+                        scopedSlots: {customRender: 'action'},
+                    }
+                ],
+                url: {
+                    list: "/appium/appiumDevice/list",
+                    delete: "/appium/appiumDevice/delete",
+                    deleteBatch: "/appium/appiumDevice/deleteBatch",
+                    exportXlsUrl: "appium/appiumDevice/exportXls",
+                    importExcelUrl: "appium/appiumDevice/importExcel",
+                },
+            }
+        },
+        computed: {
+            importExcelUrl: function () {
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            }
+        },
+        methods: {}
+    }
+</script>
+<style scoped>
+    @import '~@assets/less/common.less'
+</style>

+ 243 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/AppiumTaskItemList.vue

@@ -0,0 +1,243 @@
+<template>
+    <a-card :bordered="false">
+
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline">
+                <a-row :gutter="24">
+
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="taskId">
+                            <a-input placeholder="请输入taskId" v-model="queryParam.taskId"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="parentId">
+                            <a-input placeholder="请输入parentId" v-model="queryParam.parentId"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <template v-if="toggleSearchStatus">
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="seq">
+                                <a-input placeholder="请输入seq" v-model="queryParam.seq"></a-input>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="findType">
+                                <a-input placeholder="请输入findType" v-model="queryParam.findType"></a-input>
+                            </a-form-item>
+                        </a-col>
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="findKey">
+                                <a-input placeholder="请输入findKey" v-model="queryParam.findKey"></a-input>
+                            </a-form-item>
+                        </a-col>
+                    </template>
+                    <a-col :md="6" :sm="8">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+                    </a-col>
+
+                </a-row>
+            </a-form>
+        </div>
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+            <a-button type="primary" icon="download" @click="handleExportXls('手机任务步骤表')">导出</a-button>
+            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader"
+                      :action="importExcelUrl" @change="handleImportExcel">
+                <a-button type="primary" icon="import">导入</a-button>
+            </a-upload>
+            <a-dropdown v-if="selectedRowKeys.length > 0">
+                <a-menu slot="overlay">
+                    <a-menu-item key="1" @click="batchDel">
+                        <a-icon type="delete"/>
+                        删除
+                    </a-menu-item>
+                </a-menu>
+                <a-button style="margin-left: 8px"> 批量操作
+                    <a-icon type="down"/>
+                </a-button>
+            </a-dropdown>
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
+                selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </div>
+
+            <a-table
+                    ref="table"
+                    size="middle"
+                    bordered
+                    rowKey="id"
+                    :columns="columns"
+                    :dataSource="dataSource"
+                    :pagination="ipagination"
+                    :loading="loading"
+                    :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+                    @change="handleTableChange">
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical"/>
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+            </a-table>
+        </div>
+        <!-- table区域-end -->
+
+        <!-- 表单区域 -->
+        <appiumTaskItem-modal ref="modalForm" @ok="modalFormOk"></appiumTaskItem-modal>
+    </a-card>
+</template>
+
+<script>
+    import AppiumTaskItemModal from './modules/AppiumTaskItemModal'
+    import {JeecgListMixin} from '@/mixins/JeecgListMixin'
+
+    export default {
+        name: "AppiumTaskItemList",
+        mixins: [JeecgListMixin],
+        components: {
+            AppiumTaskItemModal
+        },
+        data() {
+            return {
+                description: '手机任务步骤表管理页面',
+                // 表头
+                columns: [
+                    {
+                        title: '#',
+                        dataIndex: '',
+                        key: 'rowIndex',
+                        width: 60,
+                        align: "center",
+                        customRender: function (t, r, index) {
+                            return parseInt(index) + 1;
+                        }
+                    },
+                    {
+                        title: 'taskId',
+                        align: "center",
+                        dataIndex: 'taskId'
+                    },
+                    {
+                        title: 'parentId',
+                        align: "center",
+                        dataIndex: 'parentId'
+                    },
+                    {
+                        title: 'seq',
+                        align: "center",
+                        dataIndex: 'seq'
+                    },
+                    {
+                        title: 'findType',
+                        align: "center",
+                        dataIndex: 'findType'
+                    },
+                    {
+                        title: 'findKey',
+                        align: "center",
+                        dataIndex: 'findKey'
+                    },
+                    {
+                        title: 'clickType',
+                        align: "center",
+                        dataIndex: 'clickType'
+                    },
+                    {
+                        title: 'offsiteX',
+                        align: "center",
+                        dataIndex: 'offsiteX'
+                    },
+                    {
+                        title: 'offsiteY',
+                        align: "center",
+                        dataIndex: 'offsiteY'
+                    },
+                    {
+                        title: 'loopRate',
+                        align: "center",
+                        dataIndex: 'loopRate'
+                    },
+                    {
+                        title: 'isMust',
+                        align: "center",
+                        dataIndex: 'isMust'
+                    },
+                    {
+                        title: 'textEqualType',
+                        align: "center",
+                        dataIndex: 'textEqualType'
+                    },
+                    {
+                        title: 'textEqualKey',
+                        align: "center",
+                        dataIndex: 'textEqualKey'
+                    },
+                    {
+                        title: 'swapType',
+                        align: "center",
+                        dataIndex: 'swapType'
+                    },
+                    {
+                        title: 'waitTime',
+                        align: "center",
+                        dataIndex: 'waitTime'
+                    },
+                    {
+                        title: 'isClose',
+                        align: "center",
+                        dataIndex: 'isClose'
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align: "center",
+                        scopedSlots: {customRender: 'action'},
+                    }
+                ],
+                url: {
+                    list: "/appium/appiumTaskItem/list",
+                    delete: "/appium/appiumTaskItem/delete",
+                    deleteBatch: "/appium/appiumTaskItem/deleteBatch",
+                    exportXlsUrl: "appium/appiumTaskItem/exportXls",
+                    importExcelUrl: "appium/appiumTaskItem/importExcel",
+                },
+            }
+        },
+        computed: {
+            importExcelUrl: function () {
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            }
+        },
+        methods: {}
+    }
+</script>
+<style scoped>
+    @import '~@assets/less/common.less'
+</style>

+ 173 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/AppiumTaskList.vue

@@ -0,0 +1,173 @@
+<template>
+    <a-card :bordered="false">
+
+        <!-- 查询区域 -->
+        <div class="table-page-search-wrapper">
+            <a-form layout="inline">
+                <a-row :gutter="24">
+
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="taskName">
+                            <a-input placeholder="请输入taskName" v-model="queryParam.taskName"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <a-col :md="6" :sm="8">
+                        <a-form-item label="appPackage">
+                            <a-input placeholder="请输入appPackage" v-model="queryParam.appPackage"></a-input>
+                        </a-form-item>
+                    </a-col>
+                    <template v-if="toggleSearchStatus">
+                        <a-col :md="6" :sm="8">
+                            <a-form-item label="appActivity">
+                                <a-input placeholder="请输入appActivity" v-model="queryParam.appActivity"></a-input>
+                            </a-form-item>
+                        </a-col>
+                    </template>
+                    <a-col :md="6" :sm="8">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+                    </a-col>
+
+                </a-row>
+            </a-form>
+        </div>
+
+        <!-- 操作按钮区域 -->
+        <div class="table-operator">
+            <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+            <a-button type="primary" icon="download" @click="handleExportXls('手机任务表')">导出</a-button>
+            <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader"
+                      :action="importExcelUrl" @change="handleImportExcel">
+                <a-button type="primary" icon="import">导入</a-button>
+            </a-upload>
+            <a-dropdown v-if="selectedRowKeys.length > 0">
+                <a-menu slot="overlay">
+                    <a-menu-item key="1" @click="batchDel">
+                        <a-icon type="delete"/>
+                        删除
+                    </a-menu-item>
+                </a-menu>
+                <a-button style="margin-left: 8px"> 批量操作
+                    <a-icon type="down"/>
+                </a-button>
+            </a-dropdown>
+        </div>
+
+        <!-- table区域-begin -->
+        <div>
+            <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+                <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{
+                selectedRowKeys.length }}</a>项
+                <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+            </div>
+
+            <a-table
+                    ref="table"
+                    size="middle"
+                    bordered
+                    rowKey="id"
+                    :columns="columns"
+                    :dataSource="dataSource"
+                    :pagination="ipagination"
+                    :loading="loading"
+                    :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+                    @change="handleTableChange">
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical"/>
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+            </a-table>
+        </div>
+        <!-- table区域-end -->
+
+        <!-- 表单区域 -->
+        <appiumTask-modal ref="modalForm" @ok="modalFormOk"></appiumTask-modal>
+    </a-card>
+</template>
+
+<script>
+    import AppiumTaskModal from './modules/AppiumTaskModal'
+    import {JeecgListMixin} from '@/mixins/JeecgListMixin'
+
+    export default {
+        name: "AppiumTaskList",
+        mixins: [JeecgListMixin],
+        components: {
+            AppiumTaskModal
+        },
+        data() {
+            return {
+                description: '手机任务表管理页面',
+                // 表头
+                columns: [
+                    {
+                        title: '#',
+                        dataIndex: '',
+                        key: 'rowIndex',
+                        width: 60,
+                        align: "center",
+                        customRender: function (t, r, index) {
+                            return parseInt(index) + 1;
+                        }
+                    },
+                    {
+                        title: 'taskName',
+                        align: "center",
+                        dataIndex: 'taskName'
+                    },
+                    {
+                        title: 'appPackage',
+                        align: "center",
+                        dataIndex: 'appPackage'
+                    },
+                    {
+                        title: 'appActivity',
+                        align: "center",
+                        dataIndex: 'appActivity'
+                    },
+                    {
+                        title: '操作',
+                        dataIndex: 'action',
+                        align: "center",
+                        scopedSlots: {customRender: 'action'},
+                    }
+                ],
+                url: {
+                    list: "/appium/appiumTask/list",
+                    delete: "/appium/appiumTask/delete",
+                    deleteBatch: "/appium/appiumTask/deleteBatch",
+                    exportXlsUrl: "appium/appiumTask/exportXls",
+                    importExcelUrl: "appium/appiumTask/importExcel",
+                },
+            }
+        },
+        computed: {
+            importExcelUrl: function () {
+                return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+            }
+        },
+        methods: {}
+    }
+</script>
+<style scoped>
+    @import '~@assets/less/common.less'
+</style>

+ 138 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumDeviceModal.vue

@@ -0,0 +1,138 @@
+<template>
+    <a-modal
+            :title="title"
+            :width="800"
+            :visible="visible"
+            :confirmLoading="confirmLoading"
+            @ok="handleOk"
+            @cancel="handleCancel"
+            cancelText="关闭">
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="ip">
+                    <a-input placeholder="请输入ip" v-decorator="['ip', validatorRules.ip ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="port">
+                    <a-input placeholder="请输入port" v-decorator="['port', validatorRules.port ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="status">
+                    <a-input placeholder="请输入status" v-decorator="['status', validatorRules.status ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+    </a-modal>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "AppiumDeviceModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    ip: {rules: [{required: true, message: '请输入ip!'}]},
+                    port: {rules: [{required: true, message: '请输入port!'}]},
+                    status: {rules: [{required: true, message: '请输入status!'}]},
+                },
+                url: {
+                    add: "/appium/appiumDevice/add",
+                    edit: "/appium/appiumDevice/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'ip', 'port', 'status'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 145 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumDeviceModal__Style#Drawer.vue

@@ -0,0 +1,145 @@
+<template>
+    <a-drawer
+            :title="title"
+            :width="800"
+            placement="right"
+            :closable="false"
+            @close="close"
+            :visible="visible"
+    >
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="ip">
+                    <a-input placeholder="请输入ip" v-decorator="['ip', validatorRules.ip ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="port">
+                    <a-input placeholder="请输入port" v-decorator="['port', validatorRules.port ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="status">
+                    <a-input placeholder="请输入status" v-decorator="['status', validatorRules.status ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+        <a-button type="primary" @click="handleOk">确定</a-button>
+        <a-button type="primary" @click="handleCancel">取消</a-button>
+    </a-drawer>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "AppiumDeviceModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    ip: {rules: [{required: true, message: '请输入ip!'}]},
+                    port: {rules: [{required: true, message: '请输入port!'}]},
+                    status: {rules: [{required: true, message: '请输入status!'}]},
+                },
+                url: {
+                    add: "/appium/appiumDevice/add",
+                    edit: "/appium/appiumDevice/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'ip', 'port', 'status'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    /** Button按钮间距 */
+    .ant-btn {
+        margin-left: 30px;
+        margin-bottom: 30px;
+        float: right;
+    }
+</style>

+ 224 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskItemModal.vue

@@ -0,0 +1,224 @@
+<template>
+    <a-modal
+            :title="title"
+            :width="800"
+            :visible="visible"
+            :confirmLoading="confirmLoading"
+            @ok="handleOk"
+            @cancel="handleCancel"
+            cancelText="关闭">
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="taskId">
+                    <a-input placeholder="请输入taskId" v-decorator="['taskId', validatorRules.taskId ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="parentId">
+                    <a-input placeholder="请输入parentId" v-decorator="['parentId', validatorRules.parentId ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="seq">
+                    <a-input-number v-decorator="[ 'seq', validatorRules.seq ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="findType">
+                    <a-input placeholder="请输入findType" v-decorator="['findType', validatorRules.findType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="findKey">
+                    <a-input placeholder="请输入findKey" v-decorator="['findKey', validatorRules.findKey ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="clickType">
+                    <a-input placeholder="请输入clickType" v-decorator="['clickType', validatorRules.clickType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="offsiteX">
+                    <a-input-number v-decorator="[ 'offsiteX', validatorRules.offsiteX ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="offsiteY">
+                    <a-input-number v-decorator="[ 'offsiteY', validatorRules.offsiteY ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="loopRate">
+                    <a-input placeholder="请输入loopRate" v-decorator="['loopRate', validatorRules.loopRate ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="isMust">
+                    <a-input placeholder="请输入isMust" v-decorator="['isMust', validatorRules.isMust ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="textEqualType">
+                    <a-input placeholder="请输入textEqualType"
+                             v-decorator="['textEqualType', validatorRules.textEqualType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="textEqualKey">
+                    <a-input placeholder="请输入textEqualKey"
+                             v-decorator="['textEqualKey', validatorRules.textEqualKey ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="swapType">
+                    <a-input placeholder="请输入swapType" v-decorator="['swapType', validatorRules.swapType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="waitTime">
+                    <a-input placeholder="请输入waitTime" v-decorator="['waitTime', validatorRules.waitTime ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="isClose">
+                    <a-input placeholder="请输入isClose" v-decorator="['isClose', validatorRules.isClose ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+    </a-modal>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "AppiumTaskItemModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    taskId: {rules: [{required: true, message: '请输入taskId!'}]},
+                    parentId: {rules: [{required: true, message: '请输入parentId!'}]},
+                    seq: {rules: [{required: true, message: '请输入seq!'}]},
+                    findType: {rules: [{required: true, message: '请输入findType!'}]},
+                    findKey: {rules: [{required: true, message: '请输入findKey!'}]},
+                    clickType: {rules: [{required: true, message: '请输入clickType!'}]},
+                    offsiteX: {rules: [{required: true, message: '请输入offsiteX!'}]},
+                    offsiteY: {rules: [{required: true, message: '请输入offsiteY!'}]},
+                    loopRate: {rules: [{required: true, message: '请输入loopRate!'}]},
+                    isMust: {rules: [{required: true, message: '请输入isMust!'}]},
+                    textEqualType: {rules: [{required: true, message: '请输入textEqualType!'}]},
+                    textEqualKey: {rules: [{required: true, message: '请输入textEqualKey!'}]},
+                    swapType: {rules: [{required: true, message: '请输入swapType!'}]},
+                    waitTime: {rules: [{required: true, message: '请输入waitTime!'}]},
+                    isClose: {rules: [{required: true, message: '请输入isClose!'}]},
+                },
+                url: {
+                    add: "/appium/appiumTaskItem/add",
+                    edit: "/appium/appiumTaskItem/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'taskId', 'parentId', 'seq', 'findType', 'findKey', 'clickType', 'offsiteX', 'offsiteY', 'loopRate', 'isMust', 'textEqualType', 'textEqualKey', 'swapType', 'waitTime', 'isClose'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 231 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskItemModal__Style#Drawer.vue

@@ -0,0 +1,231 @@
+<template>
+    <a-drawer
+            :title="title"
+            :width="800"
+            placement="right"
+            :closable="false"
+            @close="close"
+            :visible="visible"
+    >
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="taskId">
+                    <a-input placeholder="请输入taskId" v-decorator="['taskId', validatorRules.taskId ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="parentId">
+                    <a-input placeholder="请输入parentId" v-decorator="['parentId', validatorRules.parentId ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="seq">
+                    <a-input-number v-decorator="[ 'seq', validatorRules.seq ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="findType">
+                    <a-input placeholder="请输入findType" v-decorator="['findType', validatorRules.findType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="findKey">
+                    <a-input placeholder="请输入findKey" v-decorator="['findKey', validatorRules.findKey ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="clickType">
+                    <a-input placeholder="请输入clickType" v-decorator="['clickType', validatorRules.clickType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="offsiteX">
+                    <a-input-number v-decorator="[ 'offsiteX', validatorRules.offsiteX ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="offsiteY">
+                    <a-input-number v-decorator="[ 'offsiteY', validatorRules.offsiteY ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="loopRate">
+                    <a-input placeholder="请输入loopRate" v-decorator="['loopRate', validatorRules.loopRate ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="isMust">
+                    <a-input placeholder="请输入isMust" v-decorator="['isMust', validatorRules.isMust ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="textEqualType">
+                    <a-input placeholder="请输入textEqualType"
+                             v-decorator="['textEqualType', validatorRules.textEqualType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="textEqualKey">
+                    <a-input placeholder="请输入textEqualKey"
+                             v-decorator="['textEqualKey', validatorRules.textEqualKey ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="swapType">
+                    <a-input placeholder="请输入swapType" v-decorator="['swapType', validatorRules.swapType ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="waitTime">
+                    <a-input placeholder="请输入waitTime" v-decorator="['waitTime', validatorRules.waitTime ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="isClose">
+                    <a-input placeholder="请输入isClose" v-decorator="['isClose', validatorRules.isClose ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+        <a-button type="primary" @click="handleOk">确定</a-button>
+        <a-button type="primary" @click="handleCancel">取消</a-button>
+    </a-drawer>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "AppiumTaskItemModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    taskId: {rules: [{required: true, message: '请输入taskId!'}]},
+                    parentId: {rules: [{required: true, message: '请输入parentId!'}]},
+                    seq: {rules: [{required: true, message: '请输入seq!'}]},
+                    findType: {rules: [{required: true, message: '请输入findType!'}]},
+                    findKey: {rules: [{required: true, message: '请输入findKey!'}]},
+                    clickType: {rules: [{required: true, message: '请输入clickType!'}]},
+                    offsiteX: {rules: [{required: true, message: '请输入offsiteX!'}]},
+                    offsiteY: {rules: [{required: true, message: '请输入offsiteY!'}]},
+                    loopRate: {rules: [{required: true, message: '请输入loopRate!'}]},
+                    isMust: {rules: [{required: true, message: '请输入isMust!'}]},
+                    textEqualType: {rules: [{required: true, message: '请输入textEqualType!'}]},
+                    textEqualKey: {rules: [{required: true, message: '请输入textEqualKey!'}]},
+                    swapType: {rules: [{required: true, message: '请输入swapType!'}]},
+                    waitTime: {rules: [{required: true, message: '请输入waitTime!'}]},
+                    isClose: {rules: [{required: true, message: '请输入isClose!'}]},
+                },
+                url: {
+                    add: "/appium/appiumTaskItem/add",
+                    edit: "/appium/appiumTaskItem/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'taskId', 'parentId', 'seq', 'findType', 'findKey', 'clickType', 'offsiteX', 'offsiteY', 'loopRate', 'isMust', 'textEqualType', 'textEqualKey', 'swapType', 'waitTime', 'isClose'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    /** Button按钮间距 */
+    .ant-btn {
+        margin-left: 30px;
+        margin-bottom: 30px;
+        float: right;
+    }
+</style>

+ 138 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskModal.vue

@@ -0,0 +1,138 @@
+<template>
+    <a-modal
+            :title="title"
+            :width="800"
+            :visible="visible"
+            :confirmLoading="confirmLoading"
+            @ok="handleOk"
+            @cancel="handleCancel"
+            cancelText="关闭">
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="taskName">
+                    <a-input placeholder="请输入taskName" v-decorator="['taskName', validatorRules.taskName ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="appPackage">
+                    <a-input placeholder="请输入appPackage" v-decorator="['appPackage', validatorRules.appPackage ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="appActivity">
+                    <a-input placeholder="请输入appActivity" v-decorator="['appActivity', validatorRules.appActivity ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+    </a-modal>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "AppiumTaskModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    taskName: {rules: [{required: true, message: '请输入taskName!'}]},
+                    appPackage: {rules: [{required: true, message: '请输入appPackage!'}]},
+                    appActivity: {rules: [{required: true, message: '请输入appActivity!'}]},
+                },
+                url: {
+                    add: "/appium/appiumTask/add",
+                    edit: "/appium/appiumTask/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'taskName', 'appPackage', 'appActivity'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+
+</style>

+ 145 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/vue/modules/AppiumTaskModal__Style#Drawer.vue

@@ -0,0 +1,145 @@
+<template>
+    <a-drawer
+            :title="title"
+            :width="800"
+            placement="right"
+            :closable="false"
+            @close="close"
+            :visible="visible"
+    >
+
+        <a-spin :spinning="confirmLoading">
+            <a-form :form="form">
+
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="taskName">
+                    <a-input placeholder="请输入taskName" v-decorator="['taskName', validatorRules.taskName ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="appPackage">
+                    <a-input placeholder="请输入appPackage" v-decorator="['appPackage', validatorRules.appPackage ]"/>
+                </a-form-item>
+                <a-form-item
+                        :labelCol="labelCol"
+                        :wrapperCol="wrapperCol"
+                        label="appActivity">
+                    <a-input placeholder="请输入appActivity" v-decorator="['appActivity', validatorRules.appActivity ]"/>
+                </a-form-item>
+
+            </a-form>
+        </a-spin>
+        <a-button type="primary" @click="handleOk">确定</a-button>
+        <a-button type="primary" @click="handleCancel">取消</a-button>
+    </a-drawer>
+</template>
+
+<script>
+    import {httpAction} from '@/api/manage'
+    import pick from 'lodash.pick'
+    import moment from "moment"
+
+    export default {
+        name: "AppiumTaskModal",
+        data() {
+            return {
+                title: "操作",
+                visible: false,
+                model: {},
+                labelCol: {
+                    xs: {span: 24},
+                    sm: {span: 5},
+                },
+                wrapperCol: {
+                    xs: {span: 24},
+                    sm: {span: 16},
+                },
+
+                confirmLoading: false,
+                form: this.$form.createForm(this),
+                validatorRules: {
+                    taskName: {rules: [{required: true, message: '请输入taskName!'}]},
+                    appPackage: {rules: [{required: true, message: '请输入appPackage!'}]},
+                    appActivity: {rules: [{required: true, message: '请输入appActivity!'}]},
+                },
+                url: {
+                    add: "/appium/appiumTask/add",
+                    edit: "/appium/appiumTask/edit",
+                },
+            }
+        },
+        created() {
+        },
+        methods: {
+            add() {
+                this.edit({});
+            },
+            edit(record) {
+                this.form.resetFields();
+                this.model = Object.assign({}, record);
+                this.visible = true;
+                this.$nextTick(() => {
+                    this.form.setFieldsValue(pick(this.model, 'taskName', 'appPackage', 'appActivity'))
+                    //时间格式化
+                });
+
+            },
+            close() {
+                this.$emit('close');
+                this.visible = false;
+            },
+            handleOk() {
+                const that = this;
+                // 触发表单验证
+                this.form.validateFields((err, values) => {
+                    if (!err) {
+                        that.confirmLoading = true;
+                        let httpurl = '';
+                        let method = '';
+                        if (!this.model.id) {
+                            httpurl += this.url.add;
+                            method = 'post';
+                        } else {
+                            httpurl += this.url.edit;
+                            method = 'put';
+                        }
+                        let formData = Object.assign(this.model, values);
+                        //时间格式化
+
+                        console.log(formData)
+                        httpAction(httpurl, formData, method).then((res) => {
+                            if (res.success) {
+                                that.$message.success(res.message);
+                                that.$emit('ok');
+                            } else {
+                                that.$message.warning(res.message);
+                            }
+                        }).finally(() => {
+                            that.confirmLoading = false;
+                            that.close();
+                        })
+
+
+                    }
+                })
+            },
+            handleCancel() {
+                this.close()
+            },
+
+
+        }
+    }
+</script>
+
+<style lang="less" scoped>
+    /** Button按钮间距 */
+    .ant-btn {
+        margin-left: 30px;
+        margin-bottom: 30px;
+        float: right;
+    }
+</style>

+ 23 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/test/AppiumTask.java

@@ -0,0 +1,23 @@
+package cn.com.ctop.crawler.modules.test;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AppiumTask {
+    private String findType;
+    private String findKey;
+    private String clickType;
+    private Integer offsiteX;
+    private Integer offsiteY;
+    private String loopType;
+    private Long loopRate;
+    private Boolean isMust;
+    private String textEqualType;
+    private String textEqualKey;
+    private String swapType;
+    private Long waitTime;
+    private List<AppiumTask> subTask;
+    private Boolean isClose;
+}

+ 530 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/test/AppiumTest.java

@@ -0,0 +1,530 @@
+package cn.com.ctop.crawler.modules.test;
+
+import com.google.gson.Gson;
+import io.appium.java_client.TouchAction;
+import io.appium.java_client.android.AndroidDriver;
+import io.appium.java_client.touch.WaitOptions;
+import io.appium.java_client.touch.offset.PointOption;
+import lombok.Data;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class AppiumTest {
+    private Boolean isLoop = true;
+    private Duration duration = Duration.ofSeconds(1);
+
+    public void swipeToUp(AndroidDriver driver) {
+        int width = driver.manage().window().getSize().width;
+        int height = driver.manage().window().getSize().height;
+        TouchAction action1 = new TouchAction(driver).press(PointOption.point(width / 2, height * 3 / 4)).waitAction(WaitOptions.waitOptions(duration))
+                .moveTo(PointOption.point(width / 2, height / 4)).release();
+        action1.perform();
+    }
+
+
+    public void swipeToDown(AndroidDriver driver) {
+        int width = driver.manage().window().getSize().width;
+        int height = driver.manage().window().getSize().height;
+        TouchAction action2 = new TouchAction(driver).press(PointOption.point(width / 2, height / 4)).waitAction(WaitOptions.waitOptions(duration))
+                .moveTo(PointOption.point(width / 2, height * 3 / 4)).release();
+        action2.perform();
+    }
+
+    public void swipeToLeft(AndroidDriver driver) {
+        int width = driver.manage().window().getSize().width;
+        int height = driver.manage().window().getSize().height;
+        TouchAction action3 = new TouchAction(driver).press(PointOption.point(width * 3 / 4, height / 2)).waitAction(WaitOptions.waitOptions(duration))
+                .moveTo(PointOption.point(width / 4, height / 2)).release();
+        action3.perform();
+    }
+
+    public void tapPoint(AndroidDriver driver, Integer x, Integer y) {
+        TouchAction action = new TouchAction(driver).tap(PointOption.point(x, y)).release();
+        action.perform();
+    }
+
+
+    public void swipeToRight(AndroidDriver driver) {
+        int width = driver.manage().window().getSize().width;
+        int height = driver.manage().window().getSize().height;
+        TouchAction action4 = new TouchAction(driver).press(PointOption.point(width / 4, height / 2)).waitAction(WaitOptions.waitOptions(duration))
+                .moveTo(PointOption.point(width * 3 / 4, height / 2)).release();
+        action4.perform();
+    }
+
+    //    "http://39.106.184.70:4723/wd/hub"
+    public AndroidDriver initAndroidDriver(String serverUrl, String deviceName, String appPackage, String appActivity) throws Exception {
+        return new AndroidDriver(new URL(serverUrl), initCapabilities(deviceName, appPackage, appActivity));
+    }
+
+    public DesiredCapabilities initCapabilities(String deviceName, String appPackage, String appActivity) {
+        DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
+        //指定测试设备的名称
+//        desiredCapabilities.setCapability("deviceName", "127.0.0.1:62001");
+//        desiredCapabilities.setCapability("deviceName", "183.131.157.66:10005");
+        desiredCapabilities.setCapability("deviceName", deviceName);
+        //添加操作系统配置
+        desiredCapabilities.setCapability("platformName", "Android");
+        //添加操作系统版本设置
+//        desiredCapabilities.setCapability("platformVersion", "4.4.2");
+        //指定想要测试应用的包名
+//        desiredCapabilities.setCapability("appPackage", "com.smile.gifmaker");
+        desiredCapabilities.setCapability("appPackage", appPackage);
+        desiredCapabilities.setCapability("noReset", true);
+        desiredCapabilities.setCapability("unicodeKeyboard", true);
+        desiredCapabilities.setCapability("resetKeyboard", true);
+        //指定想要测试应用的入口activity
+//        desiredCapabilities.setCapability("appActivity", "com.yxcorp.gifshow.HomeActivity");
+        desiredCapabilities.setCapability("appActivity", appActivity);
+        return desiredCapabilities;
+    }
+
+    public List<AppiumTask> initTask() {
+        List<AppiumTask> list = new ArrayList<>();
+        AppiumTask appiumTask1 = new AppiumTask();
+        appiumTask1.setFindType("class");
+        appiumTask1.setFindKey("android.widget.CheckedTextView");
+        appiumTask1.setClickType("element");
+        appiumTask1.setLoopType("noloop");
+        appiumTask1.setIsMust(true);
+        appiumTask1.setWaitTime(3000L);
+
+        AppiumTask appiumTask2 = new AppiumTask();
+        appiumTask2.setFindType("xpath");
+        appiumTask2.setFindKey("//android.view.View[@content-desc=\"发现\"]");
+        appiumTask2.setClickType("element");
+        appiumTask2.setLoopType("noloop");
+        appiumTask2.setIsMust(true);
+        appiumTask2.setWaitTime(3000L);
+
+        AppiumTask appiumTask3 = new AppiumTask();
+        appiumTask3.setFindType("id");
+        appiumTask3.setFindKey("com.smile.gifmaker:id/subject");
+        appiumTask3.setClickType("no");
+        appiumTask3.setLoopType("loop");
+        appiumTask3.setIsMust(true);
+        appiumTask3.setSwapType("up");
+
+        AppiumTask appiumTask31 = new AppiumTask();
+        appiumTask31.setFindType("loop");
+        appiumTask31.setClickType("point");
+        appiumTask31.setLoopType("noloop");
+        appiumTask31.setIsMust(false);
+        appiumTask31.setTextEqualType("eq");
+        appiumTask31.setTextEqualKey("广告");
+        appiumTask31.setOffsiteX(-100);
+        appiumTask31.setOffsiteY(-100);
+        appiumTask31.setWaitTime(2000L);
+
+//        AppiumTask appiumTask32 = new AppiumTask();
+//        appiumTask32.setFindType("loop");
+//        appiumTask32.setClickType("no");
+//        appiumTask32.setLoopType("noloop");
+//        appiumTask32.setIsMust(false);
+//        appiumTask32.setTextEqualType("neq");
+//        appiumTask32.setTextEqualKey("广告");
+//
+//        AppiumTask appiumTask321 = new AppiumTask();
+//        appiumTask321.setFindType("id");
+//        appiumTask321.setFindKey("com.smile.gifmaker:id/back_btn");
+//        appiumTask321.setClickType("element");
+//        appiumTask321.setLoopType("noloop");
+//        appiumTask321.setIsMust(false);
+
+        AppiumTask appiumTask311 = new AppiumTask();
+        appiumTask311.setFindType("loop");
+        appiumTask311.setClickType("no");
+        appiumTask311.setLoopType("noloop");
+        appiumTask311.setIsMust(true);
+        appiumTask311.setSwapType("up");
+
+        AppiumTask appiumTask312 = new AppiumTask();
+        appiumTask312.setFindType("id");
+        appiumTask312.setWaitTime(5000L);
+        appiumTask312.setFindKey("com.smile.gifmaker:id/ad_simplified_style_enhanced_ad_install_text");
+        appiumTask312.setClickType("element");
+        appiumTask312.setLoopType("noloop");
+        appiumTask312.setIsMust(false);
+
+
+        AppiumTask appiumTask3121 = new AppiumTask();
+        appiumTask3121.setFindType("id");
+        appiumTask3121.setFindKey("com.android.packageinstaller:id/ok_button");
+        appiumTask3121.setClickType("element");
+        appiumTask3121.setLoopType("noloop");
+        appiumTask3121.setIsMust(true);
+        appiumTask3121.setLoopRate(3000L);
+
+        AppiumTask appiumTask3122 = new AppiumTask();
+        appiumTask3122.setFindType("id");
+        appiumTask3122.setFindKey("com.android.packageinstaller:id/launch_button");
+        appiumTask3122.setClickType("element");
+        appiumTask3122.setLoopType("noloop");
+        appiumTask3122.setIsMust(true);
+        appiumTask3121.setLoopRate(3000L);
+
+        AppiumTask appiumTask3124 = new AppiumTask();
+        appiumTask3124.setFindType("id");
+        appiumTask3124.setFindKey("com.android.packageinstaller:id/permission_allow_button");
+        appiumTask3124.setClickType("element");
+        appiumTask3124.setLoopType("noloop");
+        appiumTask3124.setIsMust(false);
+        appiumTask3124.setWaitTime(3000L);
+
+        AppiumTask appiumTask3125 = new AppiumTask();
+        appiumTask3125.setFindType("id");
+        appiumTask3125.setFindKey("com.android.packageinstaller:id/permission_allow_button");
+        appiumTask3125.setClickType("element");
+        appiumTask3125.setLoopType("noloop");
+        appiumTask3125.setIsMust(false);
+        appiumTask3125.setWaitTime(3000L);
+
+        AppiumTask appiumTask3126 = new AppiumTask();
+        appiumTask3126.setFindType("id");
+        appiumTask3126.setFindKey("com.android.packageinstaller:id/permission_allow_button");
+        appiumTask3126.setClickType("element");
+        appiumTask3126.setLoopType("noloop");
+        appiumTask3126.setIsMust(false);
+        appiumTask3126.setWaitTime(3000L);
+
+        AppiumTask appiumTask3127 = new AppiumTask();
+        appiumTask3127.setFindType("id");
+        appiumTask3127.setFindKey("com.android.packageinstaller:id/permission_allow_button");
+        appiumTask3127.setClickType("element");
+        appiumTask3127.setLoopType("noloop");
+        appiumTask3127.setIsMust(false);
+        appiumTask3127.setWaitTime(3000L);
+        appiumTask3127.setIsClose(true);
+
+        List<AppiumTask> subList4 = new ArrayList<>();
+        subList4.add(appiumTask3121);
+        subList4.add(appiumTask3122);
+//        subList4.add(appiumTask3123);
+        subList4.add(appiumTask3124);
+        subList4.add(appiumTask3125);
+        subList4.add(appiumTask3126);
+        subList4.add(appiumTask3127);
+        appiumTask312.setSubTask(subList4);
+
+        List<AppiumTask> subList3 = new ArrayList<>();
+        subList3.add(appiumTask311);
+        subList3.add(appiumTask312);
+        appiumTask31.setSubTask(subList3);
+
+//        List<AppiumTask> subList2 = new ArrayList<>();
+//        subList2.add(appiumTask321);
+//        appiumTask32.setSubTask(subList2);
+
+        List<AppiumTask> subList1 = new ArrayList<>();
+        subList1.add(appiumTask31);
+//        subList1.add(appiumTask32);
+        appiumTask3.setSubTask(subList1);
+
+        list.add(appiumTask1);
+        list.add(appiumTask2);
+        list.add(appiumTask3);
+        return list;
+    }
+
+    public void t() {
+        try {
+//            AndroidDriver androidDriver = initAndroidDriver("http://39.106.184.70:4723/wd/hub","183.131.157.66:10005","com.smile.gifmaker","com.yxcorp.gifshow.HomeActivity");
+            AndroidDriver androidDriver = initAndroidDriver("http://127.0.0.1:4723/wd/hub", "127.0.0.1:62001", "com.smile.gifmaker", "com.yxcorp.gifshow.HomeActivity");
+
+            List<AppiumTask> list = initTask();
+            for (AppiumTask task : list) {
+                runTask(androidDriver, task, null);
+            }
+            androidDriver.quit();
+            System.out.println("task success");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+    }
+
+    public void runTask(AndroidDriver androidDriver, AppiumTask appiumTask, WebElement loopElement) throws Exception {
+        if (appiumTask != null) {
+            System.out.println(new Gson().toJson(appiumTask));
+            if (appiumTask.getWaitTime() != null && appiumTask.getWaitTime() > 0) {
+                Thread.sleep(appiumTask.getWaitTime());
+            }
+            if (appiumTask.getLoopType() != null && appiumTask.getLoopType().equals("noloop")) {
+                if (appiumTask.getFindType() != null) {
+                    WebElement element = null;
+                    if (appiumTask.getFindType().equals("id")) {
+                        element = getElementById(androidDriver, appiumTask.getFindKey());
+                    } else if (appiumTask.getFindType().equals("class")) {
+                        element = getElementByClass(androidDriver, appiumTask.getFindKey());
+                    } else if (appiumTask.getFindType().equals("xpath")) {
+                        element = getElementByXpath(androidDriver, appiumTask.getFindKey());
+                    } else if (appiumTask.getFindType().equals("loop")) {
+                        element = loopElement;
+                    }
+                    if (element != null) {
+                        if (appiumTask.getTextEqualType() != null) {
+                            if (appiumTask.getTextEqualType().equals("eq")) {
+                                if (!element.getText().equals(appiumTask.getTextEqualKey())) {
+                                    return;
+                                }
+                            } else if (appiumTask.getTextEqualType().equals("neq")) {
+                                if (element.getText() == null || element.getText().equals(appiumTask.getTextEqualKey())) {
+                                    return;
+                                }
+                            }
+                        }
+                        if (appiumTask.getClickType() != null) {
+                            if (appiumTask.getClickType().equals("element")) {
+                                element.click();
+                            } else if (appiumTask.getClickType().equals("point")) {
+                                Point point = element.getLocation();
+                                tapPoint(androidDriver, point.getX() + appiumTask.getOffsiteX(), point.getY() + appiumTask.getOffsiteY());
+                            }
+                        }
+                        List<AppiumTask> subTask = appiumTask.getSubTask();
+                        if (subTask != null && subTask.size() > 0) {
+                            for (AppiumTask task : subTask) {
+                                runTask(androidDriver, task, element);
+                            }
+                        }
+                    } else {
+                        if (appiumTask.getIsMust() != null && appiumTask.getIsMust() == true) {
+                            if (appiumTask.getLoopRate() != null && appiumTask.getLoopRate() > 0) {
+                                Thread.sleep(appiumTask.getLoopRate());
+                            }
+                            runTask(androidDriver, appiumTask, element);
+                            return;
+                        }
+                    }
+                }
+                if (appiumTask.getSwapType() != null) {
+                    if (appiumTask.getSwapType().equals("up")) {
+                        this.swipeToUp(androidDriver);
+                    } else if (appiumTask.getSwapType().equals("down")) {
+                        this.swipeToDown(androidDriver);
+                    } else if (appiumTask.getSwapType().equals("left")) {
+                        this.swipeToLeft(androidDriver);
+                    } else if (appiumTask.getSwapType().equals("right")) {
+                        this.swipeToRight(androidDriver);
+                    }
+                }
+            } else if (appiumTask.getLoopType() != null && appiumTask.getLoopType().equals("loop")) {
+                while (isLoop) {
+                    System.out.println("loop:" + isLoop);
+                    if (appiumTask.getFindType() != null) {
+                        List<WebElement> list = null;
+                        if (appiumTask.getFindType().equals("id")) {
+                            list = androidDriver.findElementsById(appiumTask.getFindKey());
+                        } else if (appiumTask.getFindType().equals("class")) {
+                            list = androidDriver.findElementsByClassName(appiumTask.getFindKey());
+                        } else if (appiumTask.getFindType().equals("xpath")) {
+                            list = androidDriver.findElementsByXPath(appiumTask.getFindKey());
+                        }
+                        if (list != null && list.size() > 0) {
+                            for (WebElement element : list) {
+                                if (!isLoop) {
+                                    break;
+                                }
+                                if (appiumTask.getLoopRate() != null && appiumTask.getLoopRate() > 0) {
+                                    Thread.sleep(appiumTask.getLoopRate());
+                                }
+                                List<AppiumTask> subTask = appiumTask.getSubTask();
+                                if (subTask != null && subTask.size() > 0) {
+                                    for (AppiumTask task : subTask) {
+                                        runTask(androidDriver, task, element);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (appiumTask.getSwapType() != null) {
+                        if (appiumTask.getSwapType().equals("up")) {
+                            this.swipeToUp(androidDriver);
+                        } else if (appiumTask.getSwapType().equals("down")) {
+                            this.swipeToDown(androidDriver);
+                        } else if (appiumTask.getSwapType().equals("left")) {
+                            this.swipeToLeft(androidDriver);
+                        } else if (appiumTask.getSwapType().equals("right")) {
+                            this.swipeToRight(androidDriver);
+                        }
+                    }
+                }
+
+            }
+            if (appiumTask.getIsClose() != null && appiumTask.getIsClose()) {
+                this.isLoop = false;
+            }
+        }
+    }
+
+    public static void main(String[] args) throws MalformedURLException, InterruptedException {
+        // TODO Auto-generated method stub
+        //1.添加配置,创建DesiredCapabilities对象
+        AppiumTest appiumTest = new AppiumTest();
+        appiumTest.t();
+        //2.创建驱动...URL是appium的固定地址;指定appium通讯的地址,将相对应的配置传入到驱动里边
+
+//        com.longene.lglocation/.activity.MainActivity
+//        com.longene.setcardproperty/.MainActivity
+        //打开地图后点击同意继续
+//        androidDriver.findElementById("com.smile.gifmaker:id/button").click();
+        //点击进入地图
+        //加线程等待
+//        Thread.sleep(5000);
+//        while (true){
+//            try {
+//                AndroidDriver androidDriver = appiumTest.initAndroidDriver("http://39.106.184.70:4723/wd/hub","","","");
+//
+//                List<WebElement> list = androidDriver.findElementsByClassName("android.widget.CheckedTextView");
+//                if(list != null && list.size() > 0){
+//                    list.get(0).click();
+//                }
+//
+//                List<WebElement> list1 = androidDriver.findElementsByXPath("//android.view.View[@content-desc=\"发现\"]");
+//                if(list1 != null && list1.size() > 0){
+//                    list1.get(0).click();
+//                }
+//                appiumTest.swipeToUp(androidDriver);
+//
+//                Thread.sleep(2000);
+//                List<WebElement> webElementList = androidDriver.findElementsById("com.smile.gifmaker:id/subject");
+//                if(webElementList != null && webElementList.size() > 0){
+//                    for(WebElement element : webElementList){
+//                        if(element.getText().equals("广告")){
+//                            Point point = element.getLocation();
+//                            appiumTest.tapPoint(androidDriver,point.getX()-100,point.getY()-100);
+////                            Thread.sleep(1000);
+////                            androidDriver.findElementById("com.smile.gifmaker:id/like_button").click();
+////                            Thread.sleep(1000);
+//                            appiumTest.swipeToUp(androidDriver);
+//                            Thread.sleep(5000);
+////                            String text = androidDriver.findElementById("com.smile.gifmaker:id/label").getText();
+////                            System.out.println(text);
+////                            String title = text.split(":")[1].trim();
+//
+////                            if(title.startsWith("超级有趣的小游戏")){
+////                                Thread.sleep(1000);
+////                                androidDriver.findElementById("com.smile.gifmaker:id/editor_holder_text").click();
+////                                Thread.sleep(1000);
+////                                androidDriver.findElementById("com.smile.gifmaker:id/editor").sendKeys("这个广告看着很吸引人!");
+////                                Thread.sleep(1000);
+////                                androidDriver.findElementById("com.smile.gifmaker:id/finish_button").click();
+//                                Thread.sleep(5000);
+//                                List<WebElement> webElement = androidDriver.findElementsById("com.smile.gifmaker:id/ad_simplified_style_enhanced_ad_install_text");
+//                                if (webElement != null && webElement.size() > 0){
+//                                    webElement.get(0).click();
+//                                    while (true){
+//                                    Thread.sleep(5000);
+//                                        List<WebElement> element1 = androidDriver.findElementsById("com.android.packageinstaller:id/ok_button");
+//                                        if(element1 != null && element1.size() > 0){
+//                                            System.out.println(element1.get(0).getText());
+//                                            element1.get(0).click();
+//                                            break;
+//                                        }
+//                                    }
+//                                    while (true){
+//                                        Thread.sleep(5000);
+//                                        List<WebElement> element1 = androidDriver.findElementsById("com.android.packageinstaller:id/launch_button");
+//                                        if(element1 != null && element1.size() > 0){
+//                                            System.out.println(element1.get(0).getText());
+//                                            element1.get(0).click();
+//                                            break;
+//                                        }
+//                                    }
+//                                    while (true){
+//                                        Thread.sleep(5000);
+//                                        List<WebElement> element1 = androidDriver.findElementsById("com.android.packageinstaller:id/permission_allow_button");
+//                                        if (element1 != null && element1.size() > 0){
+//                                            element1.get(0).click();
+//                                        }else {
+//                                            break;
+//                                        }
+//                                    }
+//                                    Thread.sleep(5000);
+//                                    List<WebElement> element1 = androidDriver.findElementsById("com.game.matrix_pixelpaint:id/nr");
+//                                    if(element1 != null && element1.size() > 0){
+//                                        element1.get(0).click();
+//                                    }
+//                                    for(int i = 0; i < 10;i++){
+//                                        Thread.sleep(2000);
+//                                        appiumTest.swipeToUp(androidDriver);
+//                                    }
+//                                    System.out.println("操作完成");
+//                                }else {
+//                                    androidDriver.findElementById("com.smile.gifmaker:id/back_btn").click();
+//                                }
+//                                //按钮  com.smile.gifmaker:id/ad_simplified_style_enhanced_ad_install_text
+//                                //转化  com.smile.gifmaker:id/ad_simplified_style_enhanced_app_name_text
+//                                //喜欢  com.smile.gifmaker:id/like_button
+//                                //举报  com.smile.gifmaker:id/inform_button
+//                                //分享  com.smile.gifmaker:id/forward_button
+//                                //头像  com.smile.gifmaker:id/avatar
+//                                //返回  com.smile.gifmaker:id/back_btn
+//                                //昵称标题 com.smile.gifmaker:id/label
+//                                //评论数 com.smile.gifmaker:id/more_comments
+//                                //点赞数 com.smile.gifmaker:id/number_like
+//                                //播放数 com.smile.gifmaker:id/number_review
+//                                //新增评论 com.smile.gifmaker:id/text_top
+//                                //评论内容 com.smile.gifmaker:id/editor
+//                                //评论提交 com.smile.gifmaker:id/finish_button
+//
+////                            }else {
+////                                System.out.println(title);
+////                                androidDriver.findElementById("com.smile.gifmaker:id/back_btn").click();
+////                            }
+//
+//
+////                            Thread.sleep(5000);
+////                            androidDriver.findElementById("com.smile.gifmaker:id/back_btn").click();
+////                            System.out.println("广告坐标为:"+point.getX()+","+point.getY());
+//                        }
+//                    }
+//                }
+//            }catch (Exception e){
+//                e.printStackTrace();
+//            }
+//
+//        }
+
+//        androidDriver.findElementById("com.smile.gifmaker:id/player_cover").click();
+//        Thread.sleep(5000);
+//        //退出
+//        androidDriver.quit();
+    }
+
+    public WebElement getElementById(AndroidDriver androidDriver, String id) {
+        WebElement element = null;
+        List<WebElement> elements = androidDriver.findElementsById(id);
+        if (elements != null && elements.size() > 0) {
+            element = elements.get(0);
+        }
+        return element;
+    }
+
+    public WebElement getElementByClass(AndroidDriver androidDriver, String className) {
+        WebElement element = null;
+        List<WebElement> elements = androidDriver.findElementsByClassName(className);
+        if (elements != null && elements.size() > 0) {
+            element = elements.get(0);
+        }
+        return element;
+    }
+
+    public WebElement getElementByXpath(AndroidDriver androidDriver, String xpath) {
+        WebElement element = null;
+        List<WebElement> elements = androidDriver.findElementsByXPath(xpath);
+        if (elements != null && elements.size() > 0) {
+            element = elements.get(0);
+        }
+        return element;
+    }
+}

+ 9 - 4
pom.xml

@@ -320,10 +320,15 @@
             <version>2.36.0</version>
         </dependency>
         <dependency>
-            <groupId>io.aexp.nodes.graphql</groupId>
-            <artifactId>nodes</artifactId>
-            <version>0.4.0</version>
-        </dependency>
+            <groupId>io.appium</groupId>
+            <artifactId>java-client</artifactId>
+            <version>7.2.0</version>
+        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>io.aexp.nodes.graphql</groupId>-->
+        <!--            <artifactId>nodes</artifactId>-->
+        <!--            <version>0.4.0</version>-->
+        <!--        </dependency>-->
         <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>