syh hace 5 años
padre
commit
85f824792e
Se han modificado 37 ficheros con 2822 adiciones y 0 borrados
  1. 248 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumDeviceController.java
  2. 265 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumJobBindTaskInfoController.java
  3. 247 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumJobController.java
  4. 258 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskController.java
  5. 247 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskItemController.java
  6. 164 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/controller/AppiumTaskLogController.java
  7. 62 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumDevice.java
  8. 57 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumJob.java
  9. 63 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumJobBindTaskInfo.java
  10. 66 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTask.java
  11. 152 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTaskItem.java
  12. 83 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/entity/AppiumTaskLog.java
  13. 17 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumDeviceMapper.java
  14. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumJobBindTaskInfoMapper.java
  15. 21 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumJobMapper.java
  16. 18 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskItemMapper.java
  17. 18 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskLogMapper.java
  18. 17 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskMapper.java
  19. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumDeviceMapper.xml
  20. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumJobBindTaskInfoMapper.xml
  21. 11 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumJobMapper.xml
  22. 22 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskItemMapper.xml
  23. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskLogMapper.xml
  24. 5 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskMapper.xml
  25. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumDeviceService.java
  26. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumJobBindTaskInfoService.java
  27. 26 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumJobService.java
  28. 23 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskItemService.java
  29. 15 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskLogService.java
  30. 22 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/IAppiumTaskService.java
  31. 26 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumDeviceServiceImpl.java
  32. 19 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumJobBindTaskInfoServiceImpl.java
  33. 259 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumJobServiceImpl.java
  34. 41 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskItemServiceImpl.java
  35. 20 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskLogServiceImpl.java
  36. 90 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/service/impl/AppiumTaskServiceImpl.java
  37. 180 0
      module-crawler/src/main/java/cn/com/ctop/crawler/modules/core/util/AppiumUtil.java

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

@@ -0,0 +1,248 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumDevice;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumDeviceService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 手机设备表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@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("文件导入失败!");
+    }
+
+}
+

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

@@ -0,0 +1,265 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import cn.com.ctop.common.module.utils.ResultMapUtils;
+import cn.com.ctop.common.module.utils.StatusCode;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJobBindTaskInfo;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumJobBindTaskInfoService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.*;
+
+/**
+ * 爬虫调度任务绑定信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+@Slf4j
+@Api(tags = "爬虫调度任务绑定信息")
+@RestController
+@RequestMapping("/ctop/appiumJobBindTaskInfo")
+public class AppiumJobBindTaskInfoController {
+    @Autowired
+    private IAppiumJobBindTaskInfoService appiumJobBindTaskInfoService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param appiumJobBindTaskInfo
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "爬虫调度任务绑定信息-分页列表查询")
+    @ApiOperation(value = "爬虫调度任务绑定信息-分页列表查询", notes = "爬虫调度任务绑定信息-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AppiumJobBindTaskInfo>> queryPageList(AppiumJobBindTaskInfo appiumJobBindTaskInfo,
+                                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                              HttpServletRequest req) {
+        Result<IPage<AppiumJobBindTaskInfo>> result = new Result<>();
+        QueryWrapper<AppiumJobBindTaskInfo> queryWrapper = QueryGenerator.initQueryWrapper(appiumJobBindTaskInfo, req.getParameterMap());
+        Page<AppiumJobBindTaskInfo> page = new Page<>(pageNo, pageSize);
+        IPage<AppiumJobBindTaskInfo> pageList = appiumJobBindTaskInfoService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param appiumJobBindTaskInfo
+     * @return
+     */
+    @AutoLog(value = "爬虫调度任务绑定信息-添加")
+    @ApiOperation(value = "爬虫调度任务绑定信息-添加", notes = "爬虫调度任务绑定信息-添加")
+    @PostMapping(value = "/add")
+    public Result<AppiumJobBindTaskInfo> add(@RequestBody AppiumJobBindTaskInfo appiumJobBindTaskInfo) {
+        Result<AppiumJobBindTaskInfo> result = new Result<>();
+        try {
+            appiumJobBindTaskInfoService.save(appiumJobBindTaskInfo);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param appiumJobBindTaskInfo
+     * @return
+     */
+    @AutoLog(value = "爬虫调度任务绑定信息-编辑")
+    @ApiOperation(value = "爬虫调度任务绑定信息-编辑", notes = "爬虫调度任务绑定信息-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AppiumJobBindTaskInfo> edit(@RequestBody AppiumJobBindTaskInfo appiumJobBindTaskInfo) {
+        Result<AppiumJobBindTaskInfo> result = new Result<>();
+        AppiumJobBindTaskInfo appiumJobBindTaskInfoEntity = appiumJobBindTaskInfoService.getById(appiumJobBindTaskInfo.getId());
+        if (appiumJobBindTaskInfoEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = appiumJobBindTaskInfoService.updateById(appiumJobBindTaskInfo);
+            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 {
+            appiumJobBindTaskInfoService.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<AppiumJobBindTaskInfo> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AppiumJobBindTaskInfo> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.appiumJobBindTaskInfoService.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<AppiumJobBindTaskInfo> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AppiumJobBindTaskInfo> result = new Result<>();
+        AppiumJobBindTaskInfo appiumJobBindTaskInfo = appiumJobBindTaskInfoService.getById(id);
+        if (appiumJobBindTaskInfo == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(appiumJobBindTaskInfo);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<AppiumJobBindTaskInfo> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                AppiumJobBindTaskInfo appiumJobBindTaskInfo = JSON.parseObject(deString, AppiumJobBindTaskInfo.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(appiumJobBindTaskInfo, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<AppiumJobBindTaskInfo> pageList = appiumJobBindTaskInfoService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "爬虫调度任务绑定信息列表");
+        mv.addObject(NormalExcelConstants.CLASS, AppiumJobBindTaskInfo.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<AppiumJobBindTaskInfo> listAppiumJobBindTaskInfos = ExcelImportUtil.importExcel(file.getInputStream(), AppiumJobBindTaskInfo.class, params);
+                appiumJobBindTaskInfoService.saveBatch(listAppiumJobBindTaskInfos);
+                return Result.ok("文件导入成功!数据行数:" + listAppiumJobBindTaskInfos.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("文件导入失败!");
+    }
+
+    @PostMapping("bindInfo")
+    public Map<String, Object> bindInfo(Long jobId, Long taskId) {
+        Map<String, Object> result = new HashMap<>();
+        if (null == jobId || jobId == 0 || null == taskId || taskId == 0) {
+            ResultMapUtils.setResultMap(result, StatusCode.COMMON_PARAM_ERROR.getCode());
+            return result;
+        }
+        AppiumJobBindTaskInfo taskInfo = new AppiumJobBindTaskInfo();
+        taskInfo.setJobId(jobId);
+        taskInfo.setTaskId(taskId);
+        taskInfo.setStatus(1);
+        Date now = new Date();
+        taskInfo.setCreateTime(now);
+        taskInfo.setUpdateTime(now);
+        appiumJobBindTaskInfoService.save(taskInfo);
+        return result;
+    }
+}

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

@@ -0,0 +1,247 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJob;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumJobService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 爬虫调度任务
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+@Slf4j
+@Api(tags = "爬虫调度任务")
+@RestController
+@RequestMapping("/ctop/appiumJob")
+public class AppiumJobController {
+    @Autowired
+    private IAppiumJobService appiumJobService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param appiumJob
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "爬虫调度任务-分页列表查询")
+    @ApiOperation(value = "爬虫调度任务-分页列表查询", notes = "爬虫调度任务-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AppiumJob>> queryPageList(AppiumJob appiumJob,
+                                                  @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                  HttpServletRequest req) {
+        Result<IPage<AppiumJob>> result = new Result<>();
+        QueryWrapper<AppiumJob> queryWrapper = QueryGenerator.initQueryWrapper(appiumJob, req.getParameterMap());
+        Page<AppiumJob> page = new Page<>(pageNo, pageSize);
+        IPage<AppiumJob> pageList = appiumJobService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param appiumJob
+     * @return
+     */
+    @AutoLog(value = "爬虫调度任务-添加")
+    @ApiOperation(value = "爬虫调度任务-添加", notes = "爬虫调度任务-添加")
+    @PostMapping(value = "/add")
+    public Result<AppiumJob> add(@RequestBody AppiumJob appiumJob) {
+        Result<AppiumJob> result = new Result<>();
+        try {
+            appiumJobService.save(appiumJob);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param appiumJob
+     * @return
+     */
+    @AutoLog(value = "爬虫调度任务-编辑")
+    @ApiOperation(value = "爬虫调度任务-编辑", notes = "爬虫调度任务-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AppiumJob> edit(@RequestBody AppiumJob appiumJob) {
+        Result<AppiumJob> result = new Result<>();
+        AppiumJob appiumJobEntity = appiumJobService.getById(appiumJob.getId());
+        if (appiumJobEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = appiumJobService.updateById(appiumJob);
+            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 {
+            appiumJobService.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<AppiumJob> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AppiumJob> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.appiumJobService.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<AppiumJob> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AppiumJob> result = new Result<>();
+        AppiumJob appiumJob = appiumJobService.getById(id);
+        if (appiumJob == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(appiumJob);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<AppiumJob> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                AppiumJob appiumJob = JSON.parseObject(deString, AppiumJob.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(appiumJob, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<AppiumJob> pageList = appiumJobService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "爬虫调度任务列表");
+        mv.addObject(NormalExcelConstants.CLASS, AppiumJob.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<AppiumJob> listAppiumJobs = ExcelImportUtil.importExcel(file.getInputStream(), AppiumJob.class, params);
+                appiumJobService.saveBatch(listAppiumJobs);
+                return Result.ok("文件导入成功!数据行数:" + listAppiumJobs.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("文件导入失败!");
+    }
+}

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

@@ -0,0 +1,258 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTask;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 任务表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@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;
+    }
+
+    @RequestMapping(value = "/run/login", method = RequestMethod.POST)
+    public Result<?> runLogin(HttpServletRequest request, HttpServletResponse response, Integer taskId, Integer deviceId) {
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                appiumTaskService.runKuaishouLoginTask();
+            }
+        };
+        thread.start();
+        return Result.ok("任务已启动");
+    }
+    /**
+     * 通过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("文件导入失败!");
+    }
+
+}

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

@@ -0,0 +1,247 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskItemService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 任务内容表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@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 = "100") 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("文件导入失败!");
+    }
+
+}

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

@@ -0,0 +1,164 @@
+package cn.com.ctop.crawler.modules.appium.controller;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskLog;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskLogService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+
+/**
+ * 任务日志表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-01
+ */
+@Slf4j
+@Api(tags = "任务日志表")
+@RestController
+@RequestMapping("/appium/appiumTaskLog")
+public class AppiumTaskLogController {
+    @Autowired
+    private IAppiumTaskLogService appiumTaskLogService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param appiumTaskLog
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "任务日志表-分页列表查询")
+    @ApiOperation(value = "任务日志表-分页列表查询", notes = "任务日志表-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AppiumTaskLog>> queryPageList(AppiumTaskLog appiumTaskLog,
+                                                      @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                      HttpServletRequest req) {
+        Result<IPage<AppiumTaskLog>> result = new Result<>();
+        QueryWrapper<AppiumTaskLog> queryWrapper = QueryGenerator.initQueryWrapper(appiumTaskLog, req.getParameterMap());
+        Page<AppiumTaskLog> page = new Page<>(pageNo, pageSize);
+        IPage<AppiumTaskLog> pageList = appiumTaskLogService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param appiumTaskLog
+     * @return
+     */
+    @AutoLog(value = "任务日志表-添加")
+    @ApiOperation(value = "任务日志表-添加", notes = "任务日志表-添加")
+    @PostMapping(value = "/add")
+    public Result<AppiumTaskLog> add(@RequestBody AppiumTaskLog appiumTaskLog) {
+        Result<AppiumTaskLog> result = new Result<>();
+        try {
+            appiumTaskLogService.save(appiumTaskLog);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param appiumTaskLog
+     * @return
+     */
+    @AutoLog(value = "任务日志表-编辑")
+    @ApiOperation(value = "任务日志表-编辑", notes = "任务日志表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AppiumTaskLog> edit(@RequestBody AppiumTaskLog appiumTaskLog) {
+        Result<AppiumTaskLog> result = new Result<>();
+        AppiumTaskLog appiumTaskLogEntity = appiumTaskLogService.getById(appiumTaskLog.getId());
+        if (appiumTaskLogEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = appiumTaskLogService.updateById(appiumTaskLog);
+            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 {
+            appiumTaskLogService.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<AppiumTaskLog> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AppiumTaskLog> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.appiumTaskLogService.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<AppiumTaskLog> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AppiumTaskLog> result = new Result<>();
+        AppiumTaskLog appiumTaskLog = appiumTaskLogService.getById(id);
+        if (appiumTaskLog == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(appiumTaskLog);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+}

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

@@ -0,0 +1,62 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 手机设备表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_appium_device")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_device对象", description = "手机设备表")
+public class AppiumDevice {
+
+    /**
+     * 主键
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+    /**
+     * IP
+     */
+    @Excel(name = "IP", width = 15)
+    @ApiModelProperty(value = "IP")
+    private String ip;
+    /**
+     * 端口号
+     */
+    @Excel(name = "端口号", width = 15)
+    @ApiModelProperty(value = "端口号")
+    private String port;
+    /**
+     * 状态
+     */
+    @Excel(name = "状态", width = 15)
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

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

@@ -0,0 +1,57 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 爬虫调度任务
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+@Data
+@TableName("ctop_appium_job")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_job对象", description = "爬虫调度任务")
+public class AppiumJob {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 调度任务名称
+     */
+    @Excel(name = "调度任务名称", width = 15)
+    @ApiModelProperty(value = "调度任务名称")
+    private String jobName;
+    /**
+     * 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;
+}

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

@@ -0,0 +1,63 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 爬虫调度任务绑定信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+@Data
+@TableName("ctop_appium_job_bind_task_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_job_bind_task_info对象", description = "爬虫调度任务绑定信息")
+public class AppiumJobBindTaskInfo {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 任务号
+     */
+    @Excel(name = "任务号", width = 15)
+    @ApiModelProperty(value = "任务号")
+    private Long jobId;
+    /**
+     * 执行任务id
+     */
+    @Excel(name = "执行任务id", width = 15)
+    @ApiModelProperty(value = "执行任务id")
+    private Long taskId;
+    /**
+     * 任务绑定状态
+     */
+    @Excel(name = "任务绑定状态", width = 15)
+    @ApiModelProperty(value = "任务绑定状态")
+    private Integer status;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

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

@@ -0,0 +1,66 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 任务表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_appium_task")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_task对象", description = "任务表")
+public class AppiumTask {
+
+    /**
+     * 主键
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+    /**
+     * 任务名称
+     */
+    @Excel(name = "任务名称", width = 15)
+    @ApiModelProperty(value = "任务名称")
+    private String taskName;
+    /**
+     * APP包名
+     */
+    @Excel(name = "APP包名", width = 15)
+    @ApiModelProperty(value = "APP包名")
+    private String appPackage;
+    /**
+     * APP界面名
+     */
+    @Excel(name = "APP界面名", width = 15)
+    @ApiModelProperty(value = "APP界面名")
+    private String appActivity;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+    @TableField(exist = false)
+    private List<AppiumTask> subList;
+}

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

@@ -0,0 +1,152 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 任务内容表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_appium_task_item")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_task_item对象", description = "任务内容表")
+public class AppiumTaskItem {
+
+    /**
+     * 主键
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+    /**
+     * 任务ID
+     */
+    @Excel(name = "任务ID", width = 15)
+    @ApiModelProperty(value = "任务ID")
+    private Long taskId;
+    /**
+     * 父ID
+     */
+    @Excel(name = "父ID", width = 15)
+    @ApiModelProperty(value = "父ID")
+    private Integer parentId;
+    /**
+     * 顺序
+     */
+    @Excel(name = "顺序", width = 15)
+    @ApiModelProperty(value = "顺序")
+    private Integer seq;
+    /**
+     * 查找类型
+     */
+    @Excel(name = "查找类型", width = 15)
+    @ApiModelProperty(value = "查找类型")
+    private String findType;
+
+    @Excel(name = "名称", width = 15)
+    @ApiModelProperty(value = "名称")
+    private String name;
+    /**
+     * 查找关键字
+     */
+    @Excel(name = "查找关键字", width = 15)
+    @ApiModelProperty(value = "查找关键字")
+    private String findKey;
+    /**
+     * 点击类型
+     */
+    @Excel(name = "点击类型", width = 15)
+    @ApiModelProperty(value = "点击类型")
+    private String clickType;
+    /**
+     * 偏移量X
+     */
+    @Excel(name = "偏移量X", width = 15)
+    @ApiModelProperty(value = "偏移量X")
+    private Integer offsiteX;
+    /**
+     * 偏移量Y
+     */
+    @Excel(name = "偏移量Y", width = 15)
+    @ApiModelProperty(value = "偏移量Y")
+    private Integer offsiteY;
+    /**
+     * 循环间隔
+     */
+    @Excel(name = "循环间隔", width = 15)
+    @ApiModelProperty(value = "循环间隔")
+    private Integer loopRate;
+    /**
+     * 循环类型
+     */
+    @Excel(name = "循环类型", width = 15)
+    @ApiModelProperty(value = "循环类型")
+    private String loopType;
+    /**
+     * 是否必经执行
+     */
+    @Excel(name = "是否必经执行", width = 15)
+    @ApiModelProperty(value = "是否必经执行")
+    private Integer isMust;
+    /**
+     * 文本查找类型
+     */
+    @Excel(name = "文本查找类型", width = 15)
+    @ApiModelProperty(value = "文本查找类型")
+    private String textEqualType;
+    /**
+     * 文本查找关键字
+     */
+    @Excel(name = "文本查找关键字", width = 15)
+    @ApiModelProperty(value = "文本查找关键字")
+    private String textEqualKey;
+    /**
+     * 滑动类型
+     */
+    @Excel(name = "滑动类型", width = 15)
+    @ApiModelProperty(value = "滑动类型")
+    private String swapType;
+    /**
+     * 延迟时长
+     */
+    @Excel(name = "延迟时长", width = 15)
+    @ApiModelProperty(value = "延迟时长")
+    private Integer waitTime;
+    /**
+     * 是否执行完关闭
+     */
+    @Excel(name = "是否执行完关闭", width = 15)
+    @ApiModelProperty(value = "是否执行完关闭")
+    private Integer isClose;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "appPackage")
+    private String appPackage;
+    @ApiModelProperty(value = "appActivity")
+    private String appActivity;
+
+    @TableField(exist = false)
+    private List<AppiumTaskItem> subList;
+}

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

@@ -0,0 +1,83 @@
+package cn.com.ctop.crawler.modules.appium.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 任务日志表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-01
+ */
+@Data
+@TableName("ctop_appium_task_log")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_appium_task_log对象", description = "任务日志表")
+public class AppiumTaskLog {
+
+    /**
+     * 主键
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键")
+    private Long id;
+    /**
+     * 任务ID
+     */
+    @Excel(name = "任务ID", width = 15)
+    @ApiModelProperty(value = "任务ID")
+    private Long taskId;
+    /**
+     * 设备ID
+     */
+    @Excel(name = "设备ID", width = 15)
+    @ApiModelProperty(value = "设备ID")
+    private Integer deviceId;
+    /**
+     * 任务名称
+     */
+    @Excel(name = "任务名称", width = 15)
+    @ApiModelProperty(value = "任务名称")
+    private String taskName;
+    /**
+     * 设备IP
+     */
+    @Excel(name = "设备IP", width = 15)
+    @ApiModelProperty(value = "设备IP")
+    private String deviceIp;
+    /**
+     * 设备端口
+     */
+    @Excel(name = "设备端口", width = 15)
+    @ApiModelProperty(value = "设备端口")
+    private String devicePort;
+    /**
+     * 状态
+     */
+    @Excel(name = "状态", width = 15)
+    @Dict(dicCode = "appium_ks_log_status")
+    @ApiModelProperty(value = "状态")
+    private String status;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+}

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

@@ -0,0 +1,17 @@
+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-31
+ * @cersion: V1.0
+ */
+public interface AppiumDeviceMapper extends BaseMapper<AppiumDevice> {
+
+}

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

@@ -0,0 +1,15 @@
+package cn.com.ctop.crawler.modules.appium.mapper;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJobBindTaskInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 爬虫调度任务绑定信息
+ *
+ * @author: jeecg-boot
+ * @date: 2019-11-14
+ * @cersion: V1.0
+ */
+public interface AppiumJobBindTaskInfoMapper extends BaseMapper<AppiumJobBindTaskInfo> {
+
+}

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

@@ -0,0 +1,21 @@
+package cn.com.ctop.crawler.modules.appium.mapper;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJob;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTask;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 爬虫调度任务
+ *
+ * @author: jeecg-boot
+ * @date: 2019-11-14
+ * @cersion: V1.0
+ */
+public interface AppiumJobMapper extends BaseMapper<AppiumJob> {
+
+    List<AppiumTask> getTaskByJobId(@Param(value = "jobId") Long jobId);
+
+}

+ 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 cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 任务内容表
+ * @author: jeecg-boot
+ * @date: 2019-10-31
+ * @cersion: V1.0
+ */
+public interface AppiumTaskItemMapper extends BaseMapper<AppiumTaskItem> {
+
+    List<AppiumTaskItem> selectByParams(@Param(value = "package") String packageName, @Param(value = "activity") String activityName, @Param(value = "taskId") Long taskId);
+}

+ 18 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/AppiumTaskLogMapper.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.AppiumTaskLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 任务日志表
+ *
+ * @author: jeecg-boot
+ * @date: 2019-11-01
+ * @cersion: V1.0
+ */
+public interface AppiumTaskLogMapper extends BaseMapper<AppiumTaskLog> {
+
+}

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

@@ -0,0 +1,17 @@
+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-31
+ * @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/AppiumJobBindTaskInfoMapper.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.AppiumJobBindTaskInfoMapper">
+
+</mapper>

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

@@ -0,0 +1,11 @@
+<?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.AppiumJobMapper">
+    <select id="getTaskByJobId" resultType="cn.com.ctop.crawler.modules.appium.entity.AppiumTask">
+        select
+            *
+        from
+         ctop_appium_task task
+        left join ctop_appium_job_bind_task_info bindinfo on task.job_id = bindinfo.job_id
+    </select>
+</mapper>

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

@@ -0,0 +1,22 @@
+<?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">
+    <select id="selectByParams" resultType="cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem">
+        select
+        *
+        from
+        ctop_appium_task_item
+        where
+        1=1
+        <if test="null!=package">
+            and app_package = #{package}
+        </if>
+        <if test="null!=activity">
+            and app_activity = #{activity}
+        </if>
+        <if test="null!=taskId">
+            and task_id = #{taskId}
+        </if>
+        order by id desc
+    </select>
+</mapper>

+ 5 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/appium/mapper/xml/AppiumTaskLogMapper.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.AppiumTaskLogMapper">
+
+</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
+ * @date 2019-10-31
+ * @version V1.0
+ */
+public interface IAppiumDeviceService extends IService<AppiumDevice> {
+
+    AppiumDevice getEnabled();
+}

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

@@ -0,0 +1,15 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJobBindTaskInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 爬虫调度任务绑定信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+public interface IAppiumJobBindTaskInfoService extends IService<AppiumJobBindTaskInfo> {
+
+}

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

@@ -0,0 +1,26 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumDevice;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJob;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 爬虫调度任务
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+public interface IAppiumJobService extends IService<AppiumJob> {
+
+    String loginTask(Long taskId, AppiumDevice device);
+
+    boolean bindCreative(String account, String password, String creativeName, String ksId);
+
+    void loadTantanData();
+
+    boolean refreshWebPhone();
+
+    void updateStatus(AppiumDevice appiumDevice, AppiumTaskLog log, Integer logStatus, Integer deviceStatus);
+}

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

@@ -0,0 +1,23 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * 任务内容表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+public interface IAppiumTaskItemService extends IService<AppiumTaskItem> {
+    /**
+     * 查询任务列表
+     *
+     * @param taskId
+     * @param parentId
+     * @return
+     */
+    List<AppiumTaskItem> initTaskItemList(Long taskId, Integer parentId);
+}

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

@@ -0,0 +1,15 @@
+package cn.com.ctop.crawler.modules.appium.service;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 任务日志表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-01
+ */
+public interface IAppiumTaskLogService extends IService<AppiumTaskLog> {
+
+}

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

@@ -0,0 +1,22 @@
+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
+ * @date 2019-10-31
+ * @version V1.0
+ */
+public interface IAppiumTaskService extends IService<AppiumTask> {
+    /**
+     * 执行任务
+     *
+     * @param taskId
+     * @param deviceId
+     */
+    public void runTask(Long taskId, Integer deviceId, String publishName);
+
+    public void runKuaishouLoginTask();
+}

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

@@ -0,0 +1,26 @@
+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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 手机设备表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@Service
+public class AppiumDeviceServiceImpl extends ServiceImpl<AppiumDeviceMapper, AppiumDevice> implements IAppiumDeviceService {
+
+    @Override
+    public AppiumDevice getEnabled() {
+        QueryWrapper<AppiumDevice> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("status", 1).orderByDesc("id").last("limit 1");
+        return getOne(queryWrapper);
+    }
+}

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

@@ -0,0 +1,19 @@
+package cn.com.ctop.crawler.modules.appium.service.impl;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumJobBindTaskInfo;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumJobBindTaskInfoMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumJobBindTaskInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * 爬虫调度任务绑定信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+@Service
+public class AppiumJobBindTaskInfoServiceImpl extends ServiceImpl<AppiumJobBindTaskInfoMapper, AppiumJobBindTaskInfo> implements IAppiumJobBindTaskInfoService {
+
+}

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

@@ -0,0 +1,259 @@
+package cn.com.ctop.crawler.modules.appium.service.impl;
+
+import cn.com.ctop.common.module.utils.HttpUtils2;
+import cn.com.ctop.common.module.utils.ResultMapUtils;
+import cn.com.ctop.common.module.utils.StatusCode;
+import cn.com.ctop.crawler.modules.appium.entity.*;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumJobMapper;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskItemMapper;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskLogMapper;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumDeviceService;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumJobService;
+import cn.com.ctop.crawler.modules.core.util.AppiumUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.appium.java_client.android.AndroidDriver;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.jeecg.common.util.DateUtils;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 爬虫调度任务
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-14
+ */
+@Slf4j
+@Service
+public class AppiumJobServiceImpl extends ServiceImpl<AppiumJobMapper, AppiumJob> implements IAppiumJobService {
+    @Autowired
+    private AppiumTaskMapper taskMapper;
+    @Autowired
+    private AppiumTaskItemMapper taskItemMapper;
+    @Value("${jeecg.path.chrome-driver}")
+    private String chromeDriver;
+    @Autowired
+    private IAppiumDeviceService appiumDeviceService;
+    @Autowired
+    private AppiumTaskLogMapper appiumTaskLogMapper;
+
+    @Override
+    public String loginTask(Long taskId, AppiumDevice device) {
+        String kuaishouId = null;
+        try {
+            AppiumTask task = taskMapper.selectById(taskId);
+            AppiumUtil appiumUtil = new AppiumUtil();
+            AndroidDriver androidDriver = appiumUtil.initAndroidDriver("http://39.106.184.70:4723/wd/hub", device.getIp() + ":" + device.getPort(), task.getAppPackage(), task.getAppActivity());
+            Map<String, Object> result = new HashMap<>();
+            ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_SUCCESS.getCode());
+            boolean loop = true;
+            while (loop) {
+                Integer code = (Integer) result.get("code");
+                if (null != code && code != StatusCode.KUAISHOU_CRAWLER_APP_SUCCESS.getCode()) {
+                    kuaishouId = (String) result.get("kuaishouId");
+                    androidDriver.quit();
+                    break;
+                }
+                Thread.sleep(3000L);
+                String packageName = androidDriver.getCurrentPackage();
+                String activityName = androidDriver.currentActivity();
+                List<AppiumTaskItem> taskItems = taskItemMapper.selectByParams(packageName, activityName, taskId);
+                if (null != taskItems || taskItems.size() > 0) {
+                    for (AppiumTaskItem item : taskItems) {
+                        result = appiumUtil.runLoginTask(androidDriver, item, result);
+                    }
+                }
+                result = appiumUtil.checkMethod(androidDriver, activityName, result);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return kuaishouId;
+    }
+
+    @Override
+    public boolean bindCreative(String account, String password, String creativeName, String ksId) {
+        boolean isBind = false;
+        String url = "https://ad.e.kuaishou.com/#/welcome?redirectUrl=https%3A%2F%2Fad.e.kuaishou.com%2F%23%2Findex";
+        System.getProperties().setProperty("webdriver.chrome.driver", chromeDriver);
+        ChromeOptions chromeOptions = new ChromeOptions();
+        chromeOptions.addArguments("--headless");
+        chromeOptions.addArguments("--incognito");
+        chromeOptions.addArguments("--disable-gpu");
+//        chromeOptions.addArguments("--no-sandbox");
+        chromeOptions.addArguments("--window-size=1920,1080");
+        chromeOptions.addArguments("--user-agent=" + HttpUtils2.USER_AGENT);
+        chromeOptions.setAcceptInsecureCerts(true);
+        WebDriver webDriver = new ChromeDriver(chromeOptions);
+        try {
+            Thread.sleep(3000L);
+            HttpUtils2.cookieStore = new BasicCookieStore();
+            webDriver.manage().deleteAllCookies();
+            //获取登录页面
+            webDriver.get(url);
+            Thread.sleep(3000L);
+            WebElement accountElement = webDriver.findElement(By.xpath("//div[@class='phone ']/input[@type='text']"));
+            accountElement.sendKeys(account);
+            Thread.sleep(3000L);
+            WebElement passwordElement = webDriver.findElement(By.xpath("//div[@class='password ']/input[@type='password']"));
+            passwordElement.sendKeys(password);
+            WebElement loginElement = webDriver.findElement(By.xpath("//div[@class='foot']"));
+            Thread.sleep(3000L);
+            //点击登录
+            loginElement.click();
+            Thread.sleep(3000L);
+            //获取推广按钮
+            WebElement spreadElement = webDriver.findElement(By.linkText("推广"));
+            spreadElement.click();
+            Thread.sleep(3000L);
+            //选择广告创意
+            WebElement creativeElement = webDriver.findElement(By.xpath("//div[text()='广告创意']"));
+            creativeElement.click();
+            Thread.sleep(3000L);
+            //输入创意名称,点击搜索
+            WebElement searchElement = webDriver.findElement(By.xpath("//input[@type='text']"));
+            searchElement.sendKeys(creativeName);
+            Thread.sleep(3000L);
+            WebElement searchButton = webDriver.findElement(By.xpath("//button[@class='ant-btn ant-input-search-button ant-btn-primary']"));
+            searchButton.click();
+            Thread.sleep(3000L);
+            WebElement tiyanElement = webDriver.findElement(By.linkText("体验"));
+            tiyanElement.click();
+            Thread.sleep(2000L);
+            WebElement inputKsIdElement = webDriver.findElement(By.xpath("//textarea[@placeholder='请输入快手账号…']"));
+            inputKsIdElement.sendKeys(ksId);
+            Thread.sleep(2000L);
+            WebElement chufaElement = webDriver.findElement(By.xpath("//button[@class='creative-experience-btn-enable']"));
+            chufaElement.click();
+            isBind = true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("绑定体验快手账号失败");
+            isBind = false;
+        } finally {
+            webDriver.manage().deleteAllCookies();
+            webDriver.close();
+        }
+        return isBind;
+    }
+
+    public static final String GET_AGENT_DATA_URL = "https://marketing.tantanapp.com/platform/ad_statistic/channel_report/table?level=agent&interval=hour&";
+
+    @Override
+    public void loadTantanData() {
+        String url = "https://marketing.tantanapp.com/login";
+        System.getProperties().setProperty("webdriver.chrome.driver", chromeDriver);
+        ChromeOptions chromeOptions = new ChromeOptions();
+//        chromeOptions.addArguments("--headless");
+        chromeOptions.addArguments("--incognito");
+        chromeOptions.addArguments("--disable-gpu");
+        chromeOptions.addArguments("--no-sandbox");
+        chromeOptions.addArguments("--window-size=1920,1080");
+        chromeOptions.addArguments("--user-agent=" + HttpUtils2.USER_AGENT);
+        chromeOptions.setAcceptInsecureCerts(true);
+        WebDriver webDriver = new ChromeDriver(chromeOptions);
+        try {
+            HttpUtils2.cookieStore = new BasicCookieStore();
+            webDriver.manage().deleteAllCookies();
+            //获取登录页面
+            webDriver.get(url);
+            Thread.sleep(1000L);
+            WebElement accountElement = webDriver.findElement(By.xpath("//input[@class='form-control user_name']"));
+            accountElement.sendKeys("huichuang");
+            Thread.sleep(1000L);
+            WebElement passwordElement = webDriver.findElement(By.xpath("//input[@class='form-control user_password']"));
+            passwordElement.sendKeys("2PitTUSFG7AgBWVfbnIC");
+            WebElement loginElement = webDriver.findElement(By.xpath("//button[@class='btn btn-primary block full-width m-b user_button']"));
+            Thread.sleep(2000L);
+            //点击登录
+            loginElement.click();
+            Thread.sleep(2000L);
+            String nowDate = DateUtils.formatDate(new Date());
+            String stDate = nowDate + " 00:00:00";
+            String etDate = nowDate + " 23:59:59";
+            webDriver.get(GET_AGENT_DATA_URL + "st=" + stDate + "&et=" + etDate);
+            Thread.sleep(1000L);
+            String getData = webDriver.findElement(By.xpath("//pre[@style='word-wrap: break-word; white-space: pre-wrap;']")).getText();
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("爬取代理商数据异常");
+        } finally {
+            webDriver.manage().deleteAllCookies();
+            webDriver.close();
+        }
+    }
+
+    @Override
+    public boolean refreshWebPhone() {
+        boolean success = false;
+        String url = "https://lcloud.longene.com.cn/";
+        System.getProperties().setProperty("webdriver.chrome.driver", chromeDriver);
+        ChromeOptions chromeOptions = new ChromeOptions();
+        chromeOptions.addArguments("--headless");
+        chromeOptions.addArguments("--incognito");
+        chromeOptions.addArguments("--disable-gpu");
+//        chromeOptions.addArguments("--no-sandbox");
+        chromeOptions.addArguments("--window-size=1920,1080");
+        chromeOptions.addArguments("--user-agent=" + HttpUtils2.USER_AGENT);
+        chromeOptions.setAcceptInsecureCerts(true);
+        WebDriver webDriver = new ChromeDriver(chromeOptions);
+        try {
+            Thread.sleep(3000L);
+            HttpUtils2.cookieStore = new BasicCookieStore();
+            webDriver.manage().deleteAllCookies();
+            //获取登录页面
+            webDriver.get(url);
+            Thread.sleep(3000L);
+            WebElement accountElement = webDriver.findElement(By.id("username"));
+            accountElement.sendKeys("18600471989");
+            Thread.sleep(3000L);
+            WebElement passwordElement = webDriver.findElement(By.id("userpwd"));
+            passwordElement.sendKeys("0759125184xu");
+            WebElement loginElement = webDriver.findElement(By.xpath("//input[@class='quc-submit quc-button quc-button-primary quc-button-sign-in']"));
+            Thread.sleep(3000L);
+            //点击登录
+            loginElement.click();
+            Thread.sleep(3000L);
+            //选择华东二站
+            WebElement spreadElement = webDriver.findElement(By.xpath("//a[@href='javascript:gotobranch(2)']"));
+            spreadElement.click();
+            Thread.sleep(3000L);
+            //
+            webDriver.get("https://ecsite.longene.com.cn/userWeb!batchipswitch?ids=4293&groupid=8729&mode=5&ipbind=0&region=0&ipareas=");
+            Thread.sleep(5000L);
+            webDriver.get("https://ecsite.longene.com.cn/userWeb!batchnewphone?groupid=8729&pkgnames=com.smile.gifmaker&ids=4293");
+            Thread.sleep(5000L);
+            success = true;
+        } catch (Exception e) {
+            success = false;
+            e.printStackTrace();
+            log.error("一键新机操作失败");
+        } finally {
+            webDriver.manage().deleteAllCookies();
+            webDriver.close();
+        }
+        return success;
+    }
+
+    @Override
+    public void updateStatus(AppiumDevice appiumDevice, AppiumTaskLog log, Integer logStatus, Integer deviceStatus) {
+        log.setStatus(logStatus + "");
+        appiumTaskLogMapper.updateById(log);
+        appiumDevice.setStatus(deviceStatus);
+        appiumDeviceService.updateById(appiumDevice);
+    }
+}

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

@@ -0,0 +1,41 @@
+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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 任务内容表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@Service
+public class AppiumTaskItemServiceImpl extends ServiceImpl<AppiumTaskItemMapper, AppiumTaskItem> implements IAppiumTaskItemService {
+    @Override
+    public List<AppiumTaskItem> initTaskItemList(Long taskId, Integer parentId) {
+        QueryWrapper<AppiumTaskItem> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("task_id", taskId);
+        if (parentId == null) {
+            queryWrapper.isNull("parent_id");
+        } else {
+            queryWrapper.eq("parent_id", parentId);
+        }
+
+        queryWrapper.orderByAsc("seq");
+        List<AppiumTaskItem> list = this.list(queryWrapper);
+        if (list != null && list.size() > 0) {
+            for (int i = 0; i < list.size(); i++) {
+                AppiumTaskItem taskItem = list.get(i);
+                taskItem.setSubList(initTaskItemList(taskItem.getTaskId(), taskItem.getId()));
+                list.set(i, taskItem);
+            }
+        }
+        return list;
+    }
+}

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

@@ -0,0 +1,20 @@
+package cn.com.ctop.crawler.modules.appium.service.impl;
+
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskLog;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskLogMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskLogService;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 任务日志表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-01
+ */
+@Service
+public class AppiumTaskLogServiceImpl extends ServiceImpl<AppiumTaskLogMapper, AppiumTaskLog> implements IAppiumTaskLogService {
+
+}

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

@@ -0,0 +1,90 @@
+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.entity.AppiumTask;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskLog;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskLogMapper;
+import cn.com.ctop.crawler.modules.appium.mapper.AppiumTaskMapper;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumDeviceService;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskItemService;
+import cn.com.ctop.crawler.modules.appium.service.IAppiumTaskService;
+import cn.com.ctop.crawler.modules.core.util.AppiumUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.appium.java_client.android.AndroidDriver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 任务表
+ * @author jeecg-boot
+ * @date 2019-10-31
+ * @version V1.0
+ */
+@Service
+public class AppiumTaskServiceImpl extends ServiceImpl<AppiumTaskMapper, AppiumTask> implements IAppiumTaskService {
+    @Value("${kuaishou.group-control.path}")
+    private String groupControlPath;
+    @Value("${kuaishou.group-control.port}")
+    private String groupControlPort;
+    @Autowired
+    private IAppiumTaskItemService iAppiumTaskItemService;
+    @Autowired
+    private IAppiumDeviceService iAppiumDeviceService;
+    @Autowired
+    private AppiumTaskLogMapper appiumTaskLogMapper;
+
+    @Override
+    public void runKuaishouLoginTask() {
+        AppiumUtil appiumUtil = new AppiumUtil();
+        try {
+            AndroidDriver androidDriver = appiumUtil.initAndroidDriver("http://39.106.184.70:4723/wd/hub", "183.131.157.66:10005", "com.smile.gifmaker", "com.yxcorp.gifshow.HomeActivity");
+            appiumUtil.loginTask(androidDriver, null, null);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void runTask(Long taskId, Integer deviceId, String publishName) {
+        //获取当前需要执行的任务信息
+        AppiumTask task = this.getById(taskId);
+        //获取手机设备信息
+        AppiumDevice appiumDevice = iAppiumDeviceService.getById(deviceId);
+        appiumDevice.setStatus(2);
+        iAppiumDeviceService.updateById(appiumDevice);
+        AppiumTaskLog log = new AppiumTaskLog();
+        log.setDeviceId(deviceId);
+        log.setDeviceIp(appiumDevice.getIp());
+        log.setDevicePort(appiumDevice.getPort());
+        log.setStatus(1 + "");
+        log.setTaskId(taskId);
+        log.setTaskName(task.getTaskName());
+        appiumTaskLogMapper.insert(log);
+        log.setId(log.getId());
+        //查询所需运行的任务列表
+        List<AppiumTaskItem> taskItemList = iAppiumTaskItemService.initTaskItemList(taskId, null);
+        AppiumUtil appiumUtil = new AppiumUtil();
+        try {
+            AndroidDriver androidDriver = appiumUtil.initAndroidDriver(groupControlPath + ":" + groupControlPort + "/wd/hub", appiumDevice.getIp() + ":" + appiumDevice.getPort(), task.getAppPackage(), task.getAppActivity());
+            if (taskItemList != null && taskItemList.size() > 0) {
+                for (AppiumTaskItem appiumTaskItem : taskItemList) {
+                    appiumUtil.runTask(androidDriver, appiumTaskItem, null, publishName);
+                }
+                log.setStatus(2 + "");
+                appiumTaskLogMapper.updateById(log);
+                appiumDevice.setStatus(1);
+                iAppiumDeviceService.updateById(appiumDevice);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.setStatus(3 + "");
+            appiumTaskLogMapper.updateById(log);
+            appiumDevice.setStatus(1);
+            iAppiumDeviceService.updateById(appiumDevice);
+        }
+    }
+}

+ 180 - 0
module-crawler/src/main/java/cn/com/ctop/crawler/modules/core/util/AppiumUtil.java

@@ -2,11 +2,13 @@ package cn.com.ctop.crawler.modules.core.util;
 
 import cn.com.ctop.common.module.utils.ResultMapUtils;
 import cn.com.ctop.common.module.utils.StatusCode;
+import cn.com.ctop.crawler.modules.appium.entity.AppiumTaskItem;
 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.extern.slf4j.Slf4j;
+import org.openqa.selenium.Point;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.remote.DesiredCapabilities;
 
@@ -663,4 +665,182 @@ public class AppiumUtil {
         }
         return elements;
     }
+
+    public Map<String, Object> runLoginTask(AndroidDriver androidDriver, AppiumTaskItem appiumTaskItem, Map<String, Object> result) throws Exception {
+        Integer code = (Integer) result.get("code");
+        if (null != code && code != StatusCode.KUAISHOU_CRAWLER_APP_SUCCESS.getCode()) {
+            return result;
+        }
+        Thread.sleep(1000L);
+        String findKey = appiumTaskItem.getFindKey();
+        if ("exit".equals(findKey)) {
+            androidDriver.quit();
+            ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_EXIT.getCode());
+            log.error(StatusCode.KUAISHOU_CRAWLER_APP_EXIT.getDesc());
+            return result;
+        }
+        //1:获取元素信息
+        WebElement element = getElementByType(androidDriver, appiumTaskItem.getFindType(), appiumTaskItem.getFindKey());
+        if (null == element) {
+            ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_ELEMENT_IS_NULL.getCode());
+            log.error("元素获取异常==>activity:{},key:{}", appiumTaskItem.getAppActivity(), "com.smile.gifmaker:id/confirm_btn");
+            return result;
+        }
+        //(1):滑动效果
+        String swipeType = appiumTaskItem.getSwapType();
+        if (null != swipeType && !"".equals(swipeType.trim())) {
+            swipeByType(androidDriver, swipeType);
+            ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_SUCCESS.getCode());
+            return result;
+        }
+        //点击效果
+        String clickType = appiumTaskItem.getClickType();
+        if (null != clickType && !"".equals(clickType)) {
+            String getText = oprateElementByType(element, clickType, androidDriver, appiumTaskItem);
+            if (null != getText && !"".equals(getText)) {
+                ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_TASK_END.getCode());
+                result.put("kuaishouId", getText.replace("快手 ID:", ""));
+            } else {
+                ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_SUCCESS.getCode());
+            }
+            return result;
+        }
+        ResultMapUtils.setResultMap(result, StatusCode.KUAISHOU_CRAWLER_APP_SUCCESS.getCode());
+        return result;
+    }
+
+    private String oprateElementByType(WebElement element, String clickType, AndroidDriver androidDriver, AppiumTaskItem taskItem) {
+        String getText = null;
+        if ("element".equals(clickType)) {
+            element.click();
+        } else if ("point".equals(clickType)) {
+            Point point = element.getLocation();
+            Integer x = point.getX();
+            Integer y = point.getY();
+            if (null != taskItem.getOffsiteX()) {
+                x = taskItem.getOffsiteX();
+            }
+            if (null != taskItem.getOffsiteY()) {
+                y = taskItem.getOffsiteY();
+            }
+            tapPoint(androidDriver, x, y);
+        } else if ("send".equals(clickType)) {
+            String text = taskItem.getTextEqualKey();
+            element.sendKeys(text);
+        } else if ("text".equals(clickType)) {
+            getText = element.getText();
+        }
+        return getText;
+    }
+
+    public String runTask(AndroidDriver androidDriver, AppiumTaskItem appiumTaskItem, WebElement loopElement, String publishName) throws Exception {
+        String getText = null;
+        if (appiumTaskItem != null) {
+            if (appiumTaskItem.getWaitTime() != null && appiumTaskItem.getWaitTime() > 0) {
+                Thread.sleep(appiumTaskItem.getWaitTime());
+            }
+            checkActivity(androidDriver);
+            if (appiumTaskItem.getLoopType() != null && "noloop".equals(appiumTaskItem.getLoopType())) {
+                //非循环类型任务
+                if (appiumTaskItem.getFindType() != null) {
+                    WebElement element = null;
+                    if ("loop".equals(appiumTaskItem.getFindType())) {
+                        element = loopElement;
+                    } else {
+                        element = getElementByType(androidDriver, appiumTaskItem.getFindType(), appiumTaskItem.getFindKey());
+                    }
+                    if (element != null) {
+                        if (appiumTaskItem.getTextEqualType() != null) {
+                            if ("eq".equals(appiumTaskItem.getTextEqualType())) {
+                                if (!element.getText().equals(appiumTaskItem.getTextEqualKey())) {
+                                    return getText;
+                                }
+                            } else if ("neq".equals(appiumTaskItem.getTextEqualType())) {
+                                if (element.getText() == null || element.getText().equals(appiumTaskItem.getTextEqualKey())) {
+                                    return getText;
+                                }
+                            } else if ("start".equals(appiumTaskItem.getTextEqualType())) {
+                                boolean check = checkAdvertiser(androidDriver, publishName);
+                                if (!check) {
+                                    return getText;
+                                }
+                            }
+                        }
+                        if (appiumTaskItem.getClickType() != null) {
+                            if ("element".equals(appiumTaskItem.getClickType())) {
+                                element.click();
+                            } else if ("point".equals(appiumTaskItem.getClickType())) {
+                                Point point = element.getLocation();
+                                Integer x = point.getX();
+                                Integer y = point.getY();
+                                if (null != appiumTaskItem.getOffsiteX()) {
+                                    x += appiumTaskItem.getOffsiteX();
+                                }
+                                if (null != appiumTaskItem.getOffsiteY()) {
+                                    y += appiumTaskItem.getOffsiteY();
+                                }
+                                tapPoint(androidDriver, x, y);
+                            } else if ("send".equals(appiumTaskItem.getClickType())) {
+                                String text = appiumTaskItem.getTextEqualKey();
+                                element.sendKeys(text);
+                            } else if ("text".equals(appiumTaskItem.getClickType())) {
+                                getText = element.getText();
+                            }
+                        }
+                        List<AppiumTaskItem> subTask = appiumTaskItem.getSubList();
+                        if (subTask != null && subTask.size() > 0) {
+                            for (AppiumTaskItem task : subTask) {
+                                runTask(androidDriver, task, element, publishName);
+                            }
+                        }
+                    } else {
+                        //必须执行
+                        if (appiumTaskItem.getIsMust() != null && appiumTaskItem.getIsMust() == 1) {
+                            if (appiumTaskItem.getLoopRate() != null && appiumTaskItem.getLoopRate() > 0) {
+                                Thread.sleep(appiumTaskItem.getLoopRate());
+                            }
+                            runTask(androidDriver, appiumTaskItem, element, publishName);
+                        }
+                        //非必须执行情况下
+                        if (appiumTaskItem.getClickType() != null && "point".equals(appiumTaskItem.getClickType())) {
+                            tapPoint(androidDriver, appiumTaskItem.getOffsiteX(), appiumTaskItem.getOffsiteY());
+                        }
+                    }
+                }
+                if (appiumTaskItem.getSwapType() != null) {
+                    swipeByType(androidDriver, appiumTaskItem.getSwapType());
+                }
+            } else if (appiumTaskItem.getLoopType() != null && "loop".equals(appiumTaskItem.getLoopType())) {
+                while (isLoop) {
+                    if (appiumTaskItem.getFindType() != null) {
+                        List<WebElement> list = getElementsByType(androidDriver, appiumTaskItem.getFindType(), appiumTaskItem.getFindKey());
+                        if (list != null && list.size() > 0) {
+                            for (WebElement element : list) {
+                                if (!isLoop) {
+                                    break;
+                                }
+                                if (appiumTaskItem.getLoopRate() != null && appiumTaskItem.getLoopRate() > 0) {
+                                    Thread.sleep(appiumTaskItem.getLoopRate());
+                                }
+                                List<AppiumTaskItem> subTask = appiumTaskItem.getSubList();
+                                if (subTask != null && subTask.size() > 0) {
+                                    for (AppiumTaskItem task : subTask) {
+                                        runTask(androidDriver, task, element, publishName);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (appiumTaskItem.getSwapType() != null) {
+                        swipeByType(androidDriver, appiumTaskItem.getSwapType());
+                    }
+                }
+
+            }
+            if (appiumTaskItem.getIsClose() != null && appiumTaskItem.getIsClose() == 1) {
+                this.isLoop = false;
+            }
+        }
+        return getText;
+    }
 }