瀏覽代碼

FIX: merge conflicts when merging DEV branch

Zicong Liu 8 年之前
父節點
當前提交
0d5182224b
共有 72 個文件被更改,包括 2736 次插入2 次删除
  1. 5 0
      mooctest-site-server/pom.xml
  2. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/Application.java
  3. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/UrlConstants.java
  4. 67 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/AppPlatform.java
  5. 25 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/AppStatus.java
  6. 48 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/AppTestType.java
  7. 23 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/AppCreateEvent.java
  8. 7 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/Event.java
  9. 41 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/EventUtil.java
  10. 35 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/StatisEventsListener.java
  11. 37 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/ErrorResult.java
  12. 12 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/ResponseMessage.java
  13. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/ResponseWrapper.java
  14. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/StatusCode.java
  15. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/SuccessResult.java
  16. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/AppStatisDao.java
  17. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/ApplicationDao.java
  18. 15 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/CaseFromKibugDao.java
  19. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/IncrementIdDao.java
  20. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/MobileClientDao.java
  21. 9 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/CaseTaken.java
  22. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/AppStatis.java
  23. 170 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/Application.java
  24. 114 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/Bug.java
  25. 82 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/CaseFromKibug.java
  26. 12 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/CaseItem.java
  27. 92 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/CaseTake.java
  28. 25 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/IncrementId.java
  29. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/LaunchData.java
  30. 62 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/MobileClient.java
  31. 151 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/Report.java
  32. 14 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/ScoreRule.java
  33. 23 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/TaskFromKibug.java
  34. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/GroupService.java
  35. 0 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/impl/ApiServiceImpl.java
  36. 28 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/ApplicationService.java
  37. 23 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/KibugCaseService.java
  38. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/MobileClientService.java
  39. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/StatisService.java
  40. 198 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/ApplicationServiceImpl.java
  41. 111 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/KibugCaseServiceImpl.java
  42. 67 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/MobileClientServiceImpl.java
  43. 30 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/StatisServiceImpl.java
  44. 13 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GroupServiceImpl.java
  45. 5 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TaskController.java
  46. 158 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/ApplicationController.java
  47. 173 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/KibugCaseController.java
  48. 46 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/KibugTaskController.java
  49. 66 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/MobileClientController.java
  50. 41 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/StatisController.java
  51. 9 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/TaskVO.java
  52. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/AppStatisVO.java
  53. 34 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/ApplicationVO.java
  54. 19 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/AutoTestVO.java
  55. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/CaseCreateVO.java
  56. 21 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/CaseListItemVO.java
  57. 31 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/CreateMobileClientVO.java
  58. 34 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/KibugCaseVO.java
  59. 15 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/MobileClientVO.java
  60. 15 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/TakeCaseVO.java
  61. 14 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/UserVO.java
  62. 45 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/ValidateVO.java
  63. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/IllegalOperationException.java
  64. 34 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/ServerException.java
  65. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/TaskLogic.java
  66. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ManagerLogicImpl.java
  67. 26 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TaskLogicImpl.java
  68. 81 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/util/Converter.java
  69. 32 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/util/TimeUtils.java
  70. 3 0
      mooctest-site-server/src/main/resources/application.properties
  71. 1 1
      mooctest-site-server/src/main/resources/application.yaml
  72. 52 0
      mooctest-site-server/src/test/java/cn/iselab/mooctest/site/service/fromKibug/impl/ApplicationServiceImplTest.java

+ 5 - 0
mooctest-site-server/pom.xml

@@ -169,6 +169,11 @@
             <version>2.1.7</version>
         </dependency>
         <!-- OSS end -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.16.6</version>
+        </dependency>
 
     </dependencies>
 

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/Application.java

@@ -1,5 +1,6 @@
 package cn.iselab.mooctest.site;
 
+import cn.iselab.mooctest.site.common.event.StatisEventsListener;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.SpringBootApplication;

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/UrlConstants.java

@@ -15,6 +15,7 @@ public class UrlConstants {
     public static final String API_INTERNAL = "/api/internal/";
     public static final String API_WECHAT = "/api/wechat/";
     public static final String API_CLIENT = "/api/client/";
+    public static final String API_KIBUG = "/api/kibug/";
 
     public static final String HOSTNAME = "http://mooctest.net/";
 

+ 67 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/AppPlatform.java

@@ -0,0 +1,67 @@
+package cn.iselab.mooctest.site.common.enums;
+
+import lombok.Getter;
+
+public enum AppPlatform {
+
+    ANDROID("Android", (short) 1),
+    IOS("iOS", (short) 2),
+    JMETER("Jmeter", (short) 3),
+    SELENIUM("Selenium", (short) 4),
+    PC("PC", (short) 5),
+    APPIUM("Appium", (short) 6);
+
+    @Getter
+    private String platform;
+
+    @Getter
+    private short platformId;
+
+    AppPlatform(String platform, short platformId) {
+        this.platform = platform;
+        this.platformId = platformId;
+    }
+
+    public static AppPlatform fromShort(short value) throws IllegalArgumentException {
+        switch (value) {
+            case (short) 1:
+                return ANDROID;
+            case (short) 2:
+                return IOS;
+            case (short) 3:
+                return JMETER;
+            case (short) 4:
+                return SELENIUM;
+            case (short) 5:
+                return PC;
+            case (short) 6:
+                return APPIUM;
+        }
+        throw new IllegalArgumentException("unknown platform");
+    }
+
+    public static AppPlatform parse(String platform) throws IllegalArgumentException {
+        if (platform == null) return null;
+        switch (platform) {
+            case "Android":
+                return ANDROID;
+            case "iOS":
+                return IOS;
+            case "Jmeter":
+                return JMETER;
+            case "Selenium":
+                return SELENIUM;
+            case "PC":
+                return PC;
+            case "Appium":
+                return APPIUM;
+        }
+        throw new IllegalArgumentException("unknown platform");
+    }
+
+    @Override
+    public String toString() {
+        return this.platform;
+    }
+
+}

+ 25 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/AppStatus.java

@@ -0,0 +1,25 @@
+package cn.iselab.mooctest.site.common.enums;
+
+import lombok.Getter;
+
+/**
+ * Created by jessiechen on 16/3/7.
+ */
+public enum AppStatus {
+
+    DELETED((short) -1),
+
+    NEW((short) 0),
+    /**
+     * app信息完整
+     */
+    COMPLETE((short) 1);
+
+    @Getter
+    private short status;
+
+    AppStatus(short status) {
+        this.status = status;
+    }
+
+}

+ 48 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/AppTestType.java

@@ -0,0 +1,48 @@
+package cn.iselab.mooctest.site.common.enums;
+
+import lombok.Getter;
+
+public enum AppTestType {
+
+    /**
+     * 手动测试
+     */
+    MANUAL((short) 1),
+    /**
+     * 自动测试
+     */
+    AUTO((short) (1 << 1)),
+    /**
+     * 安全测试
+     */
+    SECURITY((short) (1 << 2)),
+
+    /**
+     * 请求服务器立刻进行自动测试
+     */
+    REQUESTAUTO((short) (1 << 9));
+
+
+    @Getter
+    private short type;
+
+    AppTestType(short type) {
+        this.type = type;
+    }
+
+    public static boolean isManual(short type) {
+        return (type & MANUAL.getType()) > 0;
+    }
+
+    public static boolean isAuto(short type) {
+        return (type & AUTO.getType()) > 0;
+    }
+
+    public static boolean isSecurity(short type) {
+        return (type & SECURITY.getType()) > 0;
+    }
+
+    public static short setRequestAuto(short type) {
+        return (short) (type | REQUESTAUTO.getType());
+    }
+}

+ 23 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/AppCreateEvent.java

@@ -0,0 +1,23 @@
+package cn.iselab.mooctest.site.common.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+@AllArgsConstructor
+public class AppCreateEvent implements Event {
+
+    private long applicationId;
+
+    public static AppCreateEvent create(long applicationId) {
+        return new AppCreateEvent(applicationId);
+    }
+
+    @Override
+    public String getDescription() {
+        return String.format("statistics id: %s", applicationId);
+    }
+
+}

+ 7 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/Event.java

@@ -0,0 +1,7 @@
+package cn.iselab.mooctest.site.common.event;
+
+public interface Event {
+
+    String getDescription();
+
+}

+ 41 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/EventUtil.java

@@ -0,0 +1,41 @@
+package cn.iselab.mooctest.site.common.event;
+
+import com.google.common.eventbus.AsyncEventBus;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.Executors;
+
+@Component
+public class EventUtil {
+
+    private static Logger logger = LoggerFactory.getLogger(EventUtil.class);
+    private EventBus eventBus;
+
+    public EventUtil() {
+        eventBus = new AsyncEventBus(Executors.newCachedThreadPool());
+        eventBus.register(this);
+    }
+
+    public void register(Object listener) {
+        eventBus.register(listener);
+    }
+
+    public void unregister(Object listener) {
+        eventBus.unregister(listener);
+    }
+
+    public void post(Event event) {
+        logger.info("event fired: {}", event.getDescription());
+        eventBus.post(event);
+    }
+
+    @Subscribe
+    public void logDeadEvent(Event deadEvent) {
+        logger.info("dead event captured: {}", deadEvent.getDescription());
+    }
+
+}

+ 35 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/StatisEventsListener.java

@@ -0,0 +1,35 @@
+package cn.iselab.mooctest.site.common.event;
+
+import cn.iselab.mooctest.site.service.fromKibug.StatisService;
+import com.google.common.eventbus.Subscribe;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StatisEventsListener implements InitializingBean {
+
+    @Autowired
+    private EventUtil eventUtil;
+
+    @Autowired
+    private StatisService statisService;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        eventUtil.register(this);
+    }
+
+    @Subscribe
+    public void statisApp(AppCreateEvent event) throws Exception {
+        statisService.create(event.getApplicationId());
+
+    }
+
+//    @Subscribe
+//    public void statisReport(ReportCreateEvent event) throws Exception {
+//        statisService.statAppTesterMobile(event.getApplicationId(), event.getModel(), event.getOs(), 1);
+//
+//    }
+
+}

+ 37 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/ErrorResult.java

@@ -0,0 +1,37 @@
+package cn.iselab.mooctest.site.common.web;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by luyanliang on 2015/7/7.
+ */
+public class ErrorResult extends HashMap<String, Object> {
+
+    private static Map<Integer, String> errorCodeMap = new HashMap<>();
+
+    static {
+        Field[] fields = StatusCode.class.getDeclaredFields();
+        for (Field field : fields) {
+            try {
+                errorCodeMap.put(field.getInt(StatusCode.class), field.getName());
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+
+
+    }
+
+    public ErrorResult(int errorCode) {
+        put(ResponseMessage.Error_Code, errorCode);
+
+        String msg = errorCodeMap.get(errorCode);
+        if (msg == null) {
+            msg = "Unknown error";
+        }
+
+        put(ResponseMessage.Error_MSG, msg);
+    }
+}

+ 12 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/ResponseMessage.java

@@ -0,0 +1,12 @@
+package cn.iselab.mooctest.site.common.web;
+
+/**
+ * Created by jessiechen on 2016/10/11.
+ */
+public interface ResponseMessage {
+    String Error_Code = "status";
+    String Error_MSG = "message";
+    String List_RESULT = "list";
+    String ID_RESULT = "id";
+    String ITEM_RESULT = "data";
+}

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/ResponseWrapper.java

@@ -0,0 +1,22 @@
+package cn.iselab.mooctest.site.common.web;
+
+
+import lombok.Data;
+
+@Data
+public class ResponseWrapper {
+
+    private int status;
+    private String message;
+    private String data;
+
+    @Override
+    public String toString() {
+        return "ResponseWrapper{" +
+                "status=" + status +
+                ", message='" + message + '\'' +
+                ", data='" + data + '\'' +
+                '}';
+    }
+
+}

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/StatusCode.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.common.web;
+
+/**
+ * Created by luyanliang on 15-7-7.
+ */
+public interface StatusCode {
+    int SUCCESS = 2000;   //成功操作返回
+    int INNER_ERROR = 5000; // 内部错误
+    int DATABASE_ERROR = 3001; // 数据库错误
+    int PARAMETER_ERROR = 3002; //参数错误
+    int ILLEGAL_OPERATION = 3003; //非法操作
+    int ILLEGAL_ACCESS = 3004; //无权限访问
+    int MOOC_ERROR = 3005;//mooc 错误
+    int DECRYPT_ERROR = 3006;//编解码错误
+    int USER_AUTH_SESSION_FAILED = 3007; // Session认证失败,可能失效,或未携带
+    int TASK_TIME_END = 3008; //
+    int TASK_TIME_NOT_BEGIN = 3009;
+    int PAYLOAD_MISS = 3010;
+    int PAYLOAD_INVALID = 3011;
+}

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/web/SuccessResult.java

@@ -0,0 +1,22 @@
+package cn.iselab.mooctest.site.common.web;
+
+import java.util.HashMap;
+
+/**
+ * Created by luyanliang on 2015/7/7.
+ */
+public class SuccessResult extends HashMap<String, Object> {
+    public SuccessResult() {
+        put(ResponseMessage.Error_Code, StatusCode.SUCCESS);
+    }
+
+    public static SuccessResult ok() {
+        return new SuccessResult();
+    }
+
+    public static SuccessResult ok(String key, Object value) {
+        SuccessResult result = new SuccessResult();
+        result.put(key, value);
+        return result;
+    }
+}

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/AppStatisDao.java

@@ -0,0 +1,11 @@
+package cn.iselab.mooctest.site.dao.fromKibug;
+
+
+import cn.iselab.mooctest.site.models.fromKibug.AppStatis;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+
+@Transactional
+public interface AppStatisDao  extends CrudRepository<AppStatis, Long> {
+}

+ 16 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/ApplicationDao.java

@@ -0,0 +1,16 @@
+package cn.iselab.mooctest.site.dao.fromKibug;
+
+import cn.iselab.mooctest.site.models.fromKibug.Application;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+
+@Transactional
+public interface ApplicationDao  extends PagingAndSortingRepository<Application, Long>,JpaSpecificationExecutor<Application> {
+
+}

+ 15 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/CaseFromKibugDao.java

@@ -0,0 +1,15 @@
+package cn.iselab.mooctest.site.dao.fromKibug;
+
+import cn.iselab.mooctest.site.models.fromKibug.CaseFromKibug;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * Created by NJUta on 2017/5/31.
+ */
+@Transactional
+public interface CaseFromKibugDao extends PagingAndSortingRepository<CaseFromKibug, Long> ,JpaSpecificationExecutor<CaseFromKibug> {
+}

+ 10 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/IncrementIdDao.java

@@ -0,0 +1,10 @@
+package cn.iselab.mooctest.site.dao.fromKibug;
+
+import cn.iselab.mooctest.site.models.fromKibug.IncrementId;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+
+@Transactional
+public interface IncrementIdDao extends CrudRepository<IncrementId, Long> {
+}

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/fromKibug/MobileClientDao.java

@@ -0,0 +1,22 @@
+package cn.iselab.mooctest.site.dao.fromKibug;
+
+import cn.iselab.mooctest.site.models.Case;
+import cn.iselab.mooctest.site.models.fromKibug.IncrementId;
+import cn.iselab.mooctest.site.models.fromKibug.MobileClient;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * Created by NJUta on 2017/6/1.
+ */
+@Transactional
+public interface MobileClientDao  extends CrudRepository<MobileClient, Long> {
+    @Query("SELECT m FROM MobileClient m WHERE m.platform = :platform order by version desc")
+    Page<MobileClient> getLastestMobileClient(@Param("platform") short platform, Pageable page);
+}

+ 9 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/CaseTaken.java

@@ -0,0 +1,9 @@
+package cn.iselab.mooctest.site.data;
+
+import lombok.Data;
+@Data
+public class CaseTaken {
+    private long caseId;
+    private long taskId;
+    private boolean taken;
+}

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/AppStatis.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Data
+@Entity
+@Table(name = "application_statis")
+public class AppStatis {
+    @Id
+    private long id;
+    @Column(name = "device_model_statis")
+    private String deviceModelStatis;
+    @Column(name = "device_os_statis")
+    private String deviceOsStatis;
+}

+ 170 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/Application.java

@@ -0,0 +1,170 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@JsonIgnoreProperties({"managerId", "createTimeMillis", "extra", "from"})
+@Entity
+@Table(name = "application")
+public class Application {
+    @Id
+    private long id;
+    @Column(name = "manager_id")
+    private long managerId;
+    /**
+     * 与慕测上传的原始需求相对应的外键
+     */
+    @Column(name = "uploaded_case_id")
+    private long uploadedCaseId;
+    @Column(name = "name")
+    private String name;
+    @Column(name = "platform")
+    private short platform;
+    @Column(name = "category")
+    private String category;
+    @Column(name = "icon_location")
+    private String iconLocation;
+    @Column(name = "app_location")
+    private String appLocation;
+    @Column(name = "require_location")
+    private String requireLocation;
+    @Column(name = "launch_data")
+    private String launchData;
+    @Column(name = "create_time_millis")
+    private long createTimeMillis;
+    @Column(name = "end_time_millis")
+    private long endTimeMillis;
+    @Column(name = "test_type")
+    private short testType;
+    @Column(name = "status")
+    private short status;
+    @Column(name = "from_cloud")
+    private int fromCloud;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getManagerId() {
+        return managerId;
+    }
+
+    public void setManagerId(long managerId) {
+        this.managerId = managerId;
+    }
+
+    public long getUploadedCaseId() {
+        return uploadedCaseId;
+    }
+
+    public void setUploadedCaseId(long uploadedCaseId) {
+        this.uploadedCaseId = uploadedCaseId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public short getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(short platform) {
+        this.platform = platform;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    public String getIconLocation() {
+        return iconLocation;
+    }
+
+    public void setIconLocation(String iconLocation) {
+        this.iconLocation = iconLocation;
+    }
+
+    public String getAppLocation() {
+        return appLocation;
+    }
+
+    public void setAppLocation(String appLocation) {
+        this.appLocation = appLocation;
+    }
+
+    public String getRequireLocation() {
+        return requireLocation;
+    }
+
+    public void setRequireLocation(String requireLocation) {
+        this.requireLocation = requireLocation;
+    }
+
+    public String getLaunchData() {
+        return launchData;
+    }
+
+    public void setLaunchData(String launchData) {
+        this.launchData = launchData;
+    }
+
+    public long getCreateTimeMillis() {
+        return createTimeMillis;
+    }
+
+    public void setCreateTimeMillis(long createTimeMillis) {
+        this.createTimeMillis = createTimeMillis;
+    }
+
+    public long getEndTimeMillis() {
+        return endTimeMillis;
+    }
+
+    public void setEndTimeMillis(long endTimeMillis) {
+        this.endTimeMillis = endTimeMillis;
+    }
+
+    public short getTestType() {
+        return testType;
+    }
+
+    public void setTestType(short testType) {
+        this.testType = testType;
+    }
+
+    public short getStatus() {
+        return status;
+    }
+
+    public void setStatus(short status) {
+        this.status = status;
+    }
+
+    public int getFromCloud() {
+        return fromCloud;
+    }
+
+    public void setFromCloud(int fromCloud) {
+        this.fromCloud = fromCloud;
+    }
+}

+ 114 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/Bug.java

@@ -0,0 +1,114 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@Entity
+@Table(name = "bug")
+public class Bug {
+    @Id
+    private long id;
+    @Column(name = "case_take_id")
+    private long caseTakeId;
+    @Column(name = "report_id")
+    private long reportId;
+    @Column(name = "create_time_millis")
+    private long createTimeMillis;
+    @Column(name = "bug_category")
+    private String bugCategory;
+    @Column(name = "description")
+    private String description;
+    @Column(name = "img_url")
+    private String imgUrl;
+    @Column(name = "severity")
+    private short severity;
+    @Column(name = "recurrent")
+    private short recurrent;
+    @Column(name = "from_cloud")
+    private int fromCloud;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getCaseTakeId() {
+        return caseTakeId;
+    }
+
+    public void setCaseTakeId(long caseTakeId) {
+        this.caseTakeId = caseTakeId;
+    }
+
+    public long getReportId() {
+        return reportId;
+    }
+
+    public void setReportId(long reportId) {
+        this.reportId = reportId;
+    }
+
+    public long getCreateTimeMillis() {
+        return createTimeMillis;
+    }
+
+    public void setCreateTimeMillis(long createTimeMillis) {
+        this.createTimeMillis = createTimeMillis;
+    }
+
+    public String getBugCategory() {
+        return bugCategory;
+    }
+
+    public void setBugCategory(String bugCategory) {
+        this.bugCategory = bugCategory;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getImgUrl() {
+        return imgUrl;
+    }
+
+    public void setImgUrl(String imgUrl) {
+        this.imgUrl = imgUrl;
+    }
+
+    public short getSeverity() {
+        return severity;
+    }
+
+    public void setSeverity(short severity) {
+        this.severity = severity;
+    }
+
+    public short getRecurrent() {
+        return recurrent;
+    }
+
+    public void setRecurrent(short recurrent) {
+        this.recurrent = recurrent;
+    }
+
+    public int getFromCloud() {
+        return fromCloud;
+    }
+
+    public void setFromCloud(int fromCloud) {
+        this.fromCloud = fromCloud;
+    }
+}

+ 82 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/CaseFromKibug.java

@@ -0,0 +1,82 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import javax.persistence.*;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@Entity
+@Table(name = "cases")
+public class CaseFromKibug {
+    @Id
+    @GeneratedValue
+    private long id;
+    @Column(name = "application_id")
+    private long applicationId;
+    @Column(name = "name")
+    private String name;
+    @Column(name = "category")
+    private String category;
+    @Column(name = "script_template_url")
+    private String scriptTemplateUrl;
+    @Column(name = "script_template_name")
+    private String scriptTemplateName;
+    @Column(name = "description")
+    private String description;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getApplicationId() {
+        return applicationId;
+    }
+
+    public void setApplicationId(long applicationId) {
+        this.applicationId = applicationId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    public String getScriptTemplateUrl() {
+        return scriptTemplateUrl;
+    }
+
+    public void setScriptTemplateUrl(String scriptTemplateUrl) {
+        this.scriptTemplateUrl = scriptTemplateUrl;
+    }
+
+    public String getScriptTemplateName() {
+        return scriptTemplateName;
+    }
+
+    public void setScriptTemplateName(String scriptTemplateName) {
+        this.scriptTemplateName = scriptTemplateName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}

+ 12 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/CaseItem.java

@@ -0,0 +1,12 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import lombok.Data;
+
+/**
+ * Created by jessiechen on 2016/10/13.
+ */
+@Data
+public class CaseItem {
+    private long id;
+    private boolean taken;
+}

+ 92 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/CaseTake.java

@@ -0,0 +1,92 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import javax.persistence.*;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@Entity
+@Table(name = "case_take")
+public class CaseTake {
+    @Id
+    @GeneratedValue
+    private long id;
+    @Column(name = "application_id")
+    private long applicationId;
+    @Column(name = "task_id")
+    private long taskId;
+    @Column(name = "case_id")
+    private long caseId;
+    @Column(name = "worker_id")
+    private long workerId;
+    @Column(name = "total")
+    private float total;
+    @Column(name = "manual")
+    private float manual;
+    @Column(name = "script")
+    private int script;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getApplicationId() {
+        return applicationId;
+    }
+
+    public void setApplicationId(long applicationId) {
+        this.applicationId = applicationId;
+    }
+
+    public long getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(long taskId) {
+        this.taskId = taskId;
+    }
+
+    public long getCaseId() {
+        return caseId;
+    }
+
+    public void setCaseId(long caseId) {
+        this.caseId = caseId;
+    }
+
+    public long getWorkerId() {
+        return workerId;
+    }
+
+    public void setWorkerId(long workerId) {
+        this.workerId = workerId;
+    }
+
+    public float getTotal() {
+        return total;
+    }
+
+    public void setTotal(float total) {
+        this.total = total;
+    }
+
+    public float getManual() {
+        return manual;
+    }
+
+    public void setManual(float manual) {
+        this.manual = manual;
+    }
+
+    public int getScript() {
+        return script;
+    }
+
+    public void setScript(int script) {
+        this.script = script;
+    }
+}

+ 25 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/IncrementId.java

@@ -0,0 +1,25 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@Entity
+@Table(name = "increment_id")
+public class IncrementId {
+    @Id
+    @GeneratedValue
+    private long id;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+}

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/LaunchData.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * Created by NJUta on 2017/5/30.
+ */
+@Data
+public class LaunchData {
+    private String activity;
+    @JsonProperty("package")
+    private String packageName;
+    private String driver;
+    private String schema;
+    private String rules;
+}

+ 62 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/MobileClient.java

@@ -0,0 +1,62 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import javax.persistence.*;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@Entity
+@Table(name = "mobile_client")
+public class MobileClient {
+    @Id
+    @GeneratedValue
+    private int id;
+    @Column(name = "platform")
+    private short platform;
+    @Column(name = "url")
+    private String url;
+    @Column(name = "version")
+    private float version;
+    @Column(name = "description")
+    private String description;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public short getPlatform() {
+        return platform;
+    }
+
+    public void setPlatform(short platform) {
+        this.platform = platform;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public float getVersion() {
+        return version;
+    }
+
+    public void setVersion(float version) {
+        this.version = version;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+}

+ 151 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/Report.java

@@ -0,0 +1,151 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import javax.persistence.*;
+
+/**
+ * Created by NJUta on 2017/5/26.
+ */
+@Entity
+@Table(name = "report")
+public class Report {
+    @Id
+    private long id;
+    @Column(name = "case_take_id")
+    private long caseTakeId;
+    @Column(name = "name")
+    private String name;
+    @Column(name = "create_time_millis")
+    private long createTimeMillis;
+    @Column(name = "bug_amount")
+    private int bugAmount;
+    @Column(name = "log_location")
+    private String logLocation;
+    @Column(name = "report_location")
+    private String reportLocation;
+    @Column(name = "script_location")
+    private String scriptLocation;
+    @Column(name = "device_brand")
+    private String deviceBrand;
+    @Column(name = "device_model")
+    private String deviceModel;
+    @Column(name = "device_os")
+    private String deviceOs;
+    @Column(name = "description")
+    private String description;
+    @Column(name = "status")
+    private short status;
+    @Column(name = "from_cloud")
+    private int fromCloud;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public long getCaseTakeId() {
+        return caseTakeId;
+    }
+
+    public void setCaseTakeId(long caseTakeId) {
+        this.caseTakeId = caseTakeId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public long getCreateTimeMillis() {
+        return createTimeMillis;
+    }
+
+    public void setCreateTimeMillis(long createTimeMillis) {
+        this.createTimeMillis = createTimeMillis;
+    }
+
+    public int getBugAmount() {
+        return bugAmount;
+    }
+
+    public void setBugAmount(int bugAmount) {
+        this.bugAmount = bugAmount;
+    }
+
+    public String getLogLocation() {
+        return logLocation;
+    }
+
+    public void setLogLocation(String logLocation) {
+        this.logLocation = logLocation;
+    }
+
+    public String getReportLocation() {
+        return reportLocation;
+    }
+
+    public void setReportLocation(String reportLocation) {
+        this.reportLocation = reportLocation;
+    }
+
+    public String getScriptLocation() {
+        return scriptLocation;
+    }
+
+    public void setScriptLocation(String scriptLocation) {
+        this.scriptLocation = scriptLocation;
+    }
+
+    public String getDeviceBrand() {
+        return deviceBrand;
+    }
+
+    public void setDeviceBrand(String deviceBrand) {
+        this.deviceBrand = deviceBrand;
+    }
+
+    public String getDeviceModel() {
+        return deviceModel;
+    }
+
+    public void setDeviceModel(String deviceModel) {
+        this.deviceModel = deviceModel;
+    }
+
+    public String getDeviceOs() {
+        return deviceOs;
+    }
+
+    public void setDeviceOs(String deviceOs) {
+        this.deviceOs = deviceOs;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public short getStatus() {
+        return status;
+    }
+
+    public void setStatus(short status) {
+        this.status = status;
+    }
+
+    public int getFromCloud() {
+        return fromCloud;
+    }
+
+    public void setFromCloud(int fromCloud) {
+        this.fromCloud = fromCloud;
+    }
+}

+ 14 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/ScoreRule.java

@@ -0,0 +1,14 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import lombok.Data;
+
+/**
+ * Created by jessiechen on 2017/3/13.
+ */
+@Data
+public class ScoreRule {
+    private long taskId;
+    private long caseId;
+    private int manual;
+    private int script;
+}

+ 23 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/fromKibug/TaskFromKibug.java

@@ -0,0 +1,23 @@
+package cn.iselab.mooctest.site.models.fromKibug;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * Created by NJUta on 2017/6/1.
+ */
+@Data
+public class TaskFromKibug {
+    private long id;
+    private String name;
+    private String information;
+    private int duration;
+    private String managerName;
+    private long managerId;
+    private String beginTime;
+    private String endTime;
+    private String subsite;
+    private List<String> groups;
+    private List<CaseItem> caseList;
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/GroupService.java

@@ -42,4 +42,6 @@ public interface GroupService {
     int getManagerGroupCount(long managerId);
 
     Group save(Group group);
+
+    List<Long> getGroupIdsByTaskId(long taskId);
 }

+ 0 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/impl/ApiServiceImpl.java

@@ -244,7 +244,6 @@ public class ApiServiceImpl implements ApiService {
         return result.toString();
     }
 
-
     /**
      * POST methods
      */

+ 28 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/ApplicationService.java

@@ -0,0 +1,28 @@
+package cn.iselab.mooctest.site.service.fromKibug;
+
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.models.fromKibug.Application;
+import cn.iselab.mooctest.site.web.data.fromKibug.ApplicationVO;
+import cn.iselab.mooctest.site.web.data.fromKibug.AutoTestVO;
+
+import java.util.List;
+
+/**
+ * Created by NJUta on 2017/5/27.
+ */
+public interface ApplicationService {
+    List<Application> search(Long managerId, String keyword, AppPlatform platform, Integer status, int page, int count) throws Exception;
+
+    long createApp(ApplicationVO vo, int from) throws Exception;
+
+    long createAutoTestApp(AutoTestVO vo) throws Exception;
+
+    Application getAppById(long id) throws Exception;
+
+    void updateApp(long appId, ApplicationVO vo) throws Exception;
+
+    void autoTestApp(Long appId) throws Exception;
+
+    List<String> getCategories() throws Exception;
+
+}

+ 23 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/KibugCaseService.java

@@ -0,0 +1,23 @@
+package cn.iselab.mooctest.site.service.fromKibug;
+
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.models.fromKibug.CaseFromKibug;
+import cn.iselab.mooctest.site.web.data.fromKibug.CaseCreateVO;
+import cn.iselab.mooctest.site.web.data.fromKibug.CaseListItemVO;
+
+import java.util.List;
+
+/**
+ * Created by NJUta on 2017/5/31.
+ */
+public interface KibugCaseService {
+    List<CaseFromKibug> getCaseByApplication(Long appId, int page, int count) throws Exception;
+
+    List<CaseListItemVO> getCaseByWorker(Long workerId, AppPlatform platform, int page, int count) throws Exception;
+
+    long create(CaseCreateVO vo) throws Exception;
+
+    void updateCase(Long caseId, CaseCreateVO dto) throws Exception;
+
+    boolean takeCase(long workerId, long caseId, long taskId) throws Exception;
+}

+ 16 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/MobileClientService.java

@@ -0,0 +1,16 @@
+package cn.iselab.mooctest.site.service.fromKibug;
+
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.models.fromKibug.MobileClient;
+import cn.iselab.mooctest.site.web.data.fromKibug.CreateMobileClientVO;
+
+import java.util.List;
+
+/**
+ * Created by NJUta on 2017/6/1.
+ */
+public interface MobileClientService {
+    List<MobileClient> getLastestMobileClients(AppPlatform platform) throws Exception;
+
+    int create(CreateMobileClientVO mobileClient) throws Exception;
+}

+ 10 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/StatisService.java

@@ -0,0 +1,10 @@
+package cn.iselab.mooctest.site.service.fromKibug;
+
+import cn.iselab.mooctest.site.models.fromKibug.AppStatis;
+
+public interface StatisService {
+    AppStatis getAppStatis(long applicationId) throws Exception;
+
+    void create(long applicationId) throws Exception;
+
+}

+ 198 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/ApplicationServiceImpl.java

@@ -0,0 +1,198 @@
+package cn.iselab.mooctest.site.service.fromKibug.impl;
+
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.common.enums.AppStatus;
+import cn.iselab.mooctest.site.common.enums.AppTestType;
+import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
+import cn.iselab.mooctest.site.dao.fromKibug.ApplicationDao;
+import cn.iselab.mooctest.site.dao.fromKibug.IncrementIdDao;
+import cn.iselab.mooctest.site.models.fromKibug.Application;
+import cn.iselab.mooctest.site.models.fromKibug.IncrementId;
+import cn.iselab.mooctest.site.models.fromKibug.LaunchData;
+import cn.iselab.mooctest.site.service.fromKibug.ApplicationService;
+import cn.iselab.mooctest.site.web.data.fromKibug.ApplicationVO;
+import cn.iselab.mooctest.site.web.data.fromKibug.AutoTestVO;
+import cn.iselab.mooctest.site.web.util.Converter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.domain.Specifications;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.util.Arrays;
+import java.util.List;
+
+@Service
+public class ApplicationServiceImpl implements ApplicationService {
+    @Autowired
+    private ApplicationDao applicationDao;
+    @Autowired
+    private IncrementIdDao incrementIdDao;
+
+    private ObjectMapper mapper = new ObjectMapper();
+
+    private static final long AUTO_TEST_APP_UPLOADED_ID = 0L;
+    private static final long MONTH_MILLIS = 30 * 24 * 60 * 60 * 1000;
+    private static final int LOCAL = 0;
+
+    @Override
+    public List<Application> search(Long managerId, String keyword, AppPlatform platform, Integer status, int page, int count) throws Exception {
+        Pageable pageable=new PageRequest(page*count,count);
+        Specifications<Application> where = Specifications.where(getWhereClause(managerId, keyword, platform, status));
+        return applicationDao.findAll(where, pageable).getContent();
+    }
+
+    @Override
+    public long createApp(ApplicationVO vo, int from) throws Exception {
+        IncrementId incrementId = incrementIdDao.save(new IncrementId());
+
+        Application application = Converter.convert(Application.class, vo);
+        application.setId(incrementId.getId());
+        application.setUploadedCaseId(vo.getUploadedCaseId());
+        application.setManagerId(vo.getManagerId());
+        application.setPlatform(AppPlatform.parse(vo.getPlatform()).getPlatformId());
+        application.setCreateTimeMillis(System.currentTimeMillis());
+        application.setFromCloud(from);
+        if (vo.getEndTimeMillis()==0) {
+            application.setEndTimeMillis(System.currentTimeMillis() + 2592000000l);
+        }
+        checkComplete(application);
+        applicationDao.save(application);
+        return incrementId.getId();
+    }
+
+    @Override
+    public long createAutoTestApp(AutoTestVO vo) throws Exception {
+        ApplicationVO applicationVo = new ApplicationVO();
+        applicationVo.setManagerId(vo.getManagerId());
+        applicationVo.setUploadedCaseId(AUTO_TEST_APP_UPLOADED_ID);
+        applicationVo.setName(vo.getName());
+        applicationVo.setAppLocation(vo.getAppLocation());
+        applicationVo.setIconLocation(vo.getIconLocation());
+        applicationVo.setPlatform(AppPlatform.ANDROID.toString());
+        applicationVo.setCategory("其他");
+        applicationVo.setEndTimeMillis(System.currentTimeMillis() + MONTH_MILLIS);
+        applicationVo.setTestType(AppTestType.AUTO.getType());
+        applicationVo.validate();
+        return createApp(applicationVo, LOCAL);
+    }
+
+    @Override
+    public Application getAppById(long id) throws Exception {
+        Application application = applicationDao.findOne(id);
+        if (application == null) throw new IllegalOperationException();
+        return application;
+    }
+
+    @Override
+    public void updateApp(long appId, ApplicationVO vo) throws Exception {
+        Application application = applicationDao.findOne(appId);
+        if (application != null) {
+            vo.setStatus(application.getStatus());//update app should not change application's status
+            Converter.copy(application, vo);
+            application.setPlatform(AppPlatform.parse(vo.getPlatform()).getPlatformId());
+            checkComplete(application);
+            applicationDao.save(application);
+        } else {
+            throw new IllegalOperationException();
+        }
+    }
+
+    @Override
+    public void autoTestApp(Long appId) throws Exception {
+        Application application = applicationDao.findOne(appId);
+        if (AppTestType.isAuto(application.getTestType())) {
+            application.setTestType((short) (application.getTestType() + 256));
+            applicationDao.save(application);
+        } else {
+            throw new IllegalOperationException("应用没有自动化测试权限");
+        }
+    }
+
+    @Override
+    public List<String> getCategories() throws Exception {
+        String[] categories = new String[]{"工具", "娱乐", "购物", "游戏", "教育",
+                "健康健美", "音乐", "新闻", "摄像与录影", "其他"};
+        return Arrays.asList(categories);
+    }
+
+    private void checkComplete(Application app) {
+        AppPlatform appPlatform = AppPlatform.fromShort(app.getPlatform());
+        LaunchData launchData;
+        try {
+            launchData = mapper.readValue(app.getLaunchData(), LaunchData.class);
+        } catch (Exception e) {
+            launchData = new LaunchData();
+        }
+
+        boolean incomplete = false;
+        boolean isAutoTest = AppTestType.isAuto(app.getTestType());
+        boolean isManualTest = AppTestType.isManual(app.getTestType());
+
+        if (isManualTest) {
+            //人工测试需要应用图标,应用安装文件,需求文件
+            incomplete = incomplete || org.springframework.util.StringUtils.isEmpty(app.getIconLocation()) || org.springframework.util.StringUtils.isEmpty(app.getAppLocation())
+                    || org.springframework.util.StringUtils.isEmpty(app.getRequireLocation());
+            //如果是安卓的话,则还需要activity,package,driver
+            if (appPlatform == AppPlatform.ANDROID) {
+                incomplete = incomplete || org.springframework.util.StringUtils.isEmpty(launchData.getActivity()) || org.springframework.util.StringUtils.isEmpty(launchData.getPackageName())
+                        || org.springframework.util.StringUtils.isEmpty(launchData.getDriver());
+            } else if (appPlatform == AppPlatform.IOS) {//ios需要schema
+                incomplete = incomplete || org.springframework.util.StringUtils.isEmpty(launchData.getSchema());
+            } else if (appPlatform == AppPlatform.JMETER) {//jmeter需要评分文件
+                incomplete = incomplete || org.springframework.util.StringUtils.isEmpty(launchData.getRules());
+            }
+        }
+
+        //如果只是自动测试的话,则只需要应用的安装文件和图标即可
+        if (!isManualTest && isAutoTest) {
+            incomplete = incomplete || org.springframework.util.StringUtils.isEmpty(app.getAppLocation()) || org.springframework.util.StringUtils.isEmpty(app.getIconLocation());
+        }
+
+        if (incomplete) {
+            app.setStatus(AppStatus.NEW.getStatus());
+        } else {
+            app.setStatus(AppStatus.COMPLETE.getStatus());
+            if (isAutoTest) {
+                app.setTestType(AppTestType.setRequestAuto(app.getTestType()));
+            }
+        }
+    }
+
+    private Specification<Application> getWhereClause(Long managerId, String keyword, AppPlatform platform, Integer status) {
+        return new Specification<Application>() {
+            @Override
+            public Predicate toPredicate(Root<Application> a, CriteriaQuery<?> q, CriteriaBuilder cb) {
+                Predicate predicate = cb.conjunction();
+                if (managerId!=null) {
+                    predicate.getExpressions().add(
+                            cb.equal(a.<Long>get("managerId"), managerId)
+                    );
+                }
+                if(keyword!=null) {
+                    predicate.getExpressions().add(
+                            cb.like(a.<String>get("name"), "%" + StringUtils.trim(keyword) + "%")
+                    );
+                }
+                if(platform!=null) {
+                    predicate.getExpressions().add(
+                            cb.equal(a.<Short>get("platform"), platform.getPlatformId())
+                    );
+                }
+                if(status!=null) {
+                    predicate.getExpressions().add(
+                            cb.equal(a.<Integer>get("status"), status)
+                    );
+                }
+                return predicate;
+            }
+        };
+    }
+}

+ 111 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/KibugCaseServiceImpl.java

@@ -0,0 +1,111 @@
+package cn.iselab.mooctest.site.service.fromKibug.impl;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.dao.fromKibug.CaseFromKibugDao;
+import cn.iselab.mooctest.site.data.CaseTaken;
+import cn.iselab.mooctest.site.models.fromKibug.Application;
+import cn.iselab.mooctest.site.models.fromKibug.CaseFromKibug;
+import cn.iselab.mooctest.site.service.application.ApiService;
+import cn.iselab.mooctest.site.service.fromKibug.ApplicationService;
+import cn.iselab.mooctest.site.service.fromKibug.KibugCaseService;
+import cn.iselab.mooctest.site.web.data.fromKibug.CaseCreateVO;
+import cn.iselab.mooctest.site.web.data.fromKibug.CaseListItemVO;
+import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
+import cn.iselab.mooctest.site.web.util.Converter;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.domain.Specifications;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.util.ArrayList;
+import java.util.List;
+@Service
+public class KibugCaseServiceImpl implements KibugCaseService {
+    @Autowired
+    private ApiService apiService;
+    @Autowired
+    private CaseFromKibugDao caseDao;
+    @Autowired
+    private ApplicationService applicationService;
+
+    @Value("${mooc.kiBugSecret}")
+    private String moocKiBugSecret;
+
+    private ObjectMapper mapper = new ObjectMapper();
+
+    @Override
+    public List<CaseFromKibug> getCaseByApplication(Long appId, int page, int count) throws Exception {
+        Pageable pageable=new PageRequest(page*count,count);
+        return caseDao.findAll(Specifications.where(getWhereClause(appId)),pageable).getContent();
+    }
+
+    @Override
+    public List<CaseListItemVO> getCaseByWorker(Long workerId, AppPlatform platform, int page, int count) throws Exception {
+        String sCaseItemList = apiService.getCases(workerId);
+        JavaType caseTakenListType = TypeFactory.defaultInstance().constructCollectionType(List.class, CaseTaken.class);
+        List<CaseTaken> caseItemList = mapper.readValue(sCaseItemList, caseTakenListType);
+        List<CaseListItemVO> caseList = new ArrayList<>();
+        for (CaseTaken caseTaken : caseItemList) {
+            CaseFromKibug temp = caseDao.findOne(caseTaken.getCaseId());
+            CaseListItemVO caseVo = Converter.convert(CaseListItemVO.class, temp);
+            if (temp != null) {
+                caseVo.setTaskId(caseTaken.getTaskId());
+                caseVo.setTaken(caseTaken.isTaken());
+                caseList.add(caseVo);
+            }
+        }
+        return caseList;
+    }
+
+    @Override
+    public long create(CaseCreateVO vo) throws Exception {
+        Application application = applicationService.getAppById(vo.getApplicationId());
+        if (application == null) throw new IllegalOperationException();
+        CaseFromKibug item = Converter.convert(CaseFromKibug.class, vo);
+        item.setCategory(application.getCategory());
+        caseDao.save(item);
+        AppPlatform platform = AppPlatform.fromShort(application.getPlatform());
+        apiService.addCase(moocKiBugSecret, item.getId()+"", platform.getPlatform(), item.getName(), UrlConstants.HOSTNAME +"#/case/" + item.getId(), item.getDescription(), 0, application.getUploadedCaseId());
+        return item.getId();
+    }
+
+    @Override
+    public void updateCase(Long caseId, CaseCreateVO dto) throws Exception {
+        CaseFromKibug item = caseDao.findOne(caseId);
+        if (item == null) throw new IllegalOperationException();
+        Converter.copy(item, dto);
+        caseDao.save(item);
+    }
+
+    @Override
+    public boolean takeCase(long workerId, long caseId, long taskId) throws Exception {
+        String result = apiService.takeTask(workerId, taskId, caseId+"", moocKiBugSecret);
+        return result.equals("")?false:true;
+    }
+
+    private Specification<CaseFromKibug> getWhereClause(Long appId) {
+        return new Specification<CaseFromKibug>() {
+            @Override
+            public Predicate toPredicate(Root<CaseFromKibug> a, CriteriaQuery<?> q, CriteriaBuilder cb) {
+                Predicate predicate = cb.conjunction();
+                if (appId!=null) {
+                    predicate.getExpressions().add(
+                            cb.equal(a.<Long>get("applicationId"), appId)
+                    );
+                }
+                return predicate;
+            }
+        };
+    }
+}

+ 67 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/MobileClientServiceImpl.java

@@ -0,0 +1,67 @@
+package cn.iselab.mooctest.site.service.fromKibug.impl;
+
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.dao.fromKibug.MobileClientDao;
+import cn.iselab.mooctest.site.models.fromKibug.MobileClient;
+import cn.iselab.mooctest.site.service.fromKibug.MobileClientService;
+import cn.iselab.mooctest.site.web.data.fromKibug.CreateMobileClientVO;
+import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
+import cn.iselab.mooctest.site.web.util.Converter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by NJUta on 2017/6/1.
+ */
+@Service
+public class MobileClientServiceImpl implements MobileClientService {
+    @Autowired
+    private MobileClientDao mobileClientDao;
+
+    @Override
+    public List<MobileClient> getLastestMobileClients(AppPlatform platform) throws Exception {
+        List<MobileClient> mobileClients = new ArrayList<>();
+        MobileClient temp;
+        if (platform != null) {
+            temp = getLastestMobileClient(platform);
+            if (temp != null) mobileClients.add(temp);
+        } else {
+            temp = getLastestMobileClient(AppPlatform.ANDROID);
+            if (temp != null) mobileClients.add(temp);
+            temp = getLastestMobileClient(AppPlatform.IOS);
+            if (temp != null) mobileClients.add(temp);
+        }
+        return mobileClients;
+    }
+
+    @Override
+    public int create(CreateMobileClientVO mobileClient) throws Exception {
+        List<MobileClient> lastestMobileList = getLastestMobileClients(mobileClient.getParsedPlatform());
+        MobileClient lastestMobile = null;
+        if (lastestMobileList != null && lastestMobileList.size() > 0) {
+            lastestMobile = lastestMobileList.get(0);
+        }
+        if (lastestMobile != null && mobileClient.getVersion() <= lastestMobile.getVersion()) {
+            throw new IllegalOperationException();
+        }
+        MobileClient client = Converter.convert(MobileClient.class, mobileClient);
+        client.setPlatform(mobileClient.getParsedPlatform().getPlatformId());
+        mobileClientDao.save(client);
+        return 0;
+    }
+
+    private MobileClient getLastestMobileClient(AppPlatform platform) throws Exception {
+        Pageable pageable=new PageRequest(0,1);
+        List<MobileClient> mobileClients = mobileClientDao.getLastestMobileClient(platform.getPlatformId(),pageable).getContent();
+        if (mobileClients.size() > 0) {
+            return mobileClients.get(0);
+        } else {
+            return null;
+        }
+    }
+}

+ 30 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/StatisServiceImpl.java

@@ -0,0 +1,30 @@
+package cn.iselab.mooctest.site.service.fromKibug.impl;
+
+import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
+import cn.iselab.mooctest.site.dao.fromKibug.AppStatisDao;
+import cn.iselab.mooctest.site.models.fromKibug.AppStatis;
+import cn.iselab.mooctest.site.service.fromKibug.StatisService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class StatisServiceImpl implements StatisService{
+    @Autowired
+    private AppStatisDao appStatisDao;
+
+    @Override
+    public AppStatis getAppStatis(long applicationId) throws Exception {
+        AppStatis appStatis = appStatisDao.findOne(applicationId);
+        if (appStatis == null) throw new IllegalOperationException();
+        return appStatis;
+    }
+
+    @Override
+    public void create(long applicationId) throws Exception {
+        AppStatis appStatis = new AppStatis();
+        appStatis.setDeviceModelStatis("{}");
+        appStatis.setDeviceOsStatis("{}");
+        appStatis.setId(applicationId);
+        appStatisDao.save(appStatis);
+    }
+}

+ 13 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GroupServiceImpl.java

@@ -188,4 +188,17 @@ public class GroupServiceImpl implements GroupService {
     public Group save(Group group) {
         return groupDao.save(group);
     }
+
+    @Override
+    public List<Long> getGroupIdsByTaskId(long taskId) {
+        List<Task2Group> task2Groups = task2GroupDao.findByTaskId(taskId);
+        List<Long> groupIds = new ArrayList<>();
+
+        for (Task2Group task2Group : task2Groups
+                ) {
+            groupIds.add(task2Group.getGroupId());
+        }
+
+        return groupIds;
+    }
 }

+ 5 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TaskController.java

@@ -86,6 +86,11 @@ public class TaskController extends BaseController {
         return taskLogic.getTaskDetailByAdmin(taskId);
     }
 
+    @RequestMapping(value = UrlConstants.API_WORKER + "task/{id:\\d+}", method = RequestMethod.GET)
+    public TaskVO getWorkerTaskDetail(HttpServletRequest request, @PathVariable("id") long taskId) {
+        long workerId = RequestUtils.getWorkerId(request);
+        return taskLogic.getTaskDetailByWorker(workerId, taskId);
+    }
 
     @RequestMapping(value = UrlConstants.API_MANAGER + "task/{id:\\d+}/assistantManager", method = RequestMethod.GET)
     public List<ManagerVO> getAssistantManagersByTaskId(@PathVariable("id") long id, HttpServletRequest request) {

+ 158 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/ApplicationController.java

@@ -0,0 +1,158 @@
+package cn.iselab.mooctest.site.web.ctrl.fromKibug;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.common.event.AppCreateEvent;
+import cn.iselab.mooctest.site.common.event.EventUtil;
+import cn.iselab.mooctest.site.common.web.ResponseMessage;
+import cn.iselab.mooctest.site.common.web.SuccessResult;
+import cn.iselab.mooctest.site.models.fromKibug.Application;
+import cn.iselab.mooctest.site.service.application.ApiService;
+import cn.iselab.mooctest.site.service.fromKibug.ApplicationService;
+import cn.iselab.mooctest.site.web.data.fromKibug.ApplicationVO;
+import cn.iselab.mooctest.site.web.data.fromKibug.AutoTestVO;
+import cn.iselab.mooctest.site.web.util.Converter;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by NJUta on 2017/5/27.
+ */
+@RestController
+public class ApplicationController {
+    @Autowired
+    private ApplicationService applicationService;
+    @Autowired
+    private ApiService apiService;
+    @Autowired
+    EventUtil eventUtil;
+    @Value("${mooc.kiBugSecret}")
+    private String moocKiBugSecret;
+    /**
+     * 按条件搜索
+     *
+     * @param managerId
+     * @param keyword
+     * @param platform
+     * @param status
+     * @param page
+     * @param count
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application", method = RequestMethod.GET)
+    public Map<String, Object> search(@RequestParam(name = "managerId", required = false) Long managerId,
+                                      @RequestParam(name = "keyword", required = false) String keyword,
+                                      @RequestParam(name = "platform", required = false) String platform,
+                                      @RequestParam(name = "status", required = false) Integer status,
+                                      @RequestParam(name = "page", defaultValue = "0") Integer page,
+                                      @RequestParam(name = "count", defaultValue = "10") Integer count) throws Exception {
+        AppPlatform appPlatform = AppPlatform.parse(platform);
+        List<Application> applications = applicationService.search(managerId, keyword, appPlatform, status, page, count);
+        SuccessResult successResult = new SuccessResult();
+        successResult.put(ResponseMessage.List_RESULT, Lists.transform(applications, item -> {
+            ApplicationVO vo = Converter.convert(ApplicationVO.class, item);
+            vo.setPlatform(AppPlatform.fromShort(item.getPlatform()).getPlatform());
+            return vo;
+        }));
+        return successResult;
+    }
+
+    /**
+     * 创建应用
+     *
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application", method = RequestMethod.POST)
+    public Map<String, Object> create(@RequestBody @NotNull ApplicationVO vo) throws Exception {
+        vo.validate();
+//        if (AuthUtil.isManager()) {
+//            dto.setManagerId(CurrentUser.get().getId());
+//        }
+        long id = applicationService.createApp(vo, 0);
+        apiService.verifyApp(vo.getUploadedCaseId(), UrlConstants.HOSTNAME + "#/app/" + id + "/info");
+
+        AppCreateEvent appCreateEvent = AppCreateEvent.create(id);
+        eventUtil.post(appCreateEvent);
+
+        SuccessResult successResult = new SuccessResult();
+        successResult.put(ResponseMessage.ID_RESULT, id);
+        return successResult;
+    }
+
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application/auto-test", method = RequestMethod.POST)
+    public Map<String, Object> createAutoTest(@RequestBody @NotNull AutoTestVO vo) throws Exception {
+        vo.validate();
+        long id = applicationService.createAutoTestApp(vo);
+        apiService.uploadApp(moocKiBugSecret,vo.getName(),UrlConstants.HOSTNAME + "#/app/" + id + "/info",false,vo.getManagerId());
+
+        AppCreateEvent appCreateEvent = AppCreateEvent.create(id);
+        eventUtil.post(appCreateEvent);
+
+        SuccessResult successResult = new SuccessResult();
+        successResult.put(ResponseMessage.ID_RESULT, id);
+        return successResult;
+    }
+
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application/{appId}", method = RequestMethod.GET)
+    public Map<String, Object> get(@PathVariable @NotNull Long appId) throws Exception {
+        SuccessResult successResult = new SuccessResult();
+        Application application = applicationService.getAppById(appId);
+        ApplicationVO vo = Converter.convert(ApplicationVO.class, application);
+        vo.setPlatform(AppPlatform.fromShort(application.getPlatform()).getPlatform());
+        successResult.put(ResponseMessage.ITEM_RESULT, vo);
+        return successResult;
+    }
+
+    /**
+     * 更新应用信息
+     *
+     * @param appId
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application/{appId}", method = RequestMethod.PUT)
+    public Map<String, Object> update(@PathVariable @NotNull Long appId,
+                                      @RequestBody @NotNull ApplicationVO vo) throws Exception {
+        vo.validate();
+        SuccessResult successResult = new SuccessResult();
+        applicationService.updateApp(appId, vo);
+        return successResult;
+    }
+
+    /**
+     * 请求立刻自动测试
+     *
+     * @param appId
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application/{appId}/auto/", method = RequestMethod.POST)
+    public Map<String, Object> testAuto(@PathVariable @NotNull Long appId) throws Exception {
+        applicationService.autoTestApp(appId);
+        return new SuccessResult();
+    }
+
+    /**
+     * 获取应用分类列表
+     *
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"application/categories", method = RequestMethod.GET)
+    public Map<String, Object> getCategory() throws Exception {
+        SuccessResult successResult = new SuccessResult();
+        List<String> categories = applicationService.getCategories();
+        successResult.put(ResponseMessage.List_RESULT, categories);
+        return successResult;
+    }
+}

+ 173 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/KibugCaseController.java

@@ -0,0 +1,173 @@
+package cn.iselab.mooctest.site.web.ctrl.fromKibug;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.common.enums.UserType;
+import cn.iselab.mooctest.site.common.web.ResponseMessage;
+import cn.iselab.mooctest.site.common.web.SuccessResult;
+import cn.iselab.mooctest.site.models.fromKibug.Application;
+import cn.iselab.mooctest.site.models.fromKibug.CaseFromKibug;
+import cn.iselab.mooctest.site.service.fromKibug.ApplicationService;
+import cn.iselab.mooctest.site.service.fromKibug.KibugCaseService;
+import cn.iselab.mooctest.site.web.data.fromKibug.*;
+import cn.iselab.mooctest.site.web.logic.ApiLogic;
+import cn.iselab.mooctest.site.web.util.Converter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by NJUta on 2017/5/31.
+ */
+@RestController
+public class KibugCaseController {
+    @Autowired
+    private ApplicationService applicationService;
+    @Autowired
+    private KibugCaseService caseService;
+    @Autowired
+    private ApiLogic apiLogic;
+
+    /**
+     * 搜索Case
+     *
+     * @param appId    由该app下划分的Case
+     * @param workerId 被该worker选中的Case
+     * @param platform 平台
+     * @param page     页码
+     * @param count    偏移量
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"case", method = RequestMethod.GET)
+    public Map<String, Object> search(@RequestParam(name = "appId", required = false) Long appId,
+                                      @RequestParam(name = "workerId", required = false) Long workerId,
+                                      @RequestParam(name = "platform", required = false) String platform,
+                                      @RequestParam(name = "page", defaultValue = "0", required = false) Integer page,
+                                      @RequestParam(name = "count", defaultValue = "10", required = false) Integer count) throws Exception {
+        //if (AuthUtil.isWorker()) workerId = CurrentUser.get().getId();
+        SuccessResult successResult = new SuccessResult();
+        List<CaseListItemVO> caseVoList;
+        AppPlatform appPlatform = platform == null ? null : AppPlatform.parse(platform);
+        if (workerId != null) {
+            caseVoList = caseService.getCaseByWorker(workerId, appPlatform, page, count);
+        } else {
+            caseVoList = new ArrayList<>();
+            List<CaseFromKibug> caseList = caseService.getCaseByApplication(appId, page, count);
+            for (CaseFromKibug item : caseList) {
+                caseVoList.add(Converter.convert(CaseListItemVO.class, item));
+            }
+        }
+        for (CaseListItemVO item : caseVoList) {
+            try {
+                Application application = applicationService.getAppById(item.getApplicationId());
+                item.setIconLocation(application.getIconLocation());
+                item.setPlatform(AppPlatform.fromShort(application.getPlatform()).getPlatform());
+            } catch (Exception e) {
+                continue;
+            }
+        }
+        successResult.put(ResponseMessage.List_RESULT, caseVoList);
+        return successResult;
+    }
+    /**
+     * 创建Case
+     *
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"case", method = RequestMethod.POST)
+    public Map<String, Object> create(@RequestBody @NotNull CaseCreateVO vo) throws Exception {
+        vo.validate();
+        SuccessResult successResult = new SuccessResult();
+        long caseId = caseService.create(vo);
+        successResult.put(ResponseMessage.ID_RESULT, caseId);
+        return successResult;
+    }
+
+    /**
+     * 查询Case
+     *
+     * @param caseId
+     * @return
+     * @throws Exception
+     */
+/*    @RequestMapping(value= UrlConstants.API_KIBUG+"case/{caseId}", method = RequestMethod.GET)
+    public Map<String, Object> get(HttpServletRequest request, @PathVariable @NotNull Long caseId,
+                                   @RequestParam(name = "taskId", required = false) Long taskId,
+                                   @RequestParam(name = "needReport", required = false, defaultValue = "false") Boolean needReport) throws Exception {
+        SuccessResult successResult = new SuccessResult();
+        CaseFromKibug caseItem;
+        UserVO user = apiLogic.checkIdentityRfct(request);
+        if (user.getIdentity()== UserType.WORKER) {
+            caseItem = caseService.getCaseById(taskId, caseId, user.getId());
+        } else {
+            caseItem = caseService.getCaseById(caseId);
+        }
+        Application application = applicationService.getAppById(caseItem.getApplicationId());
+        KibugCaseVO vo = new KibugCaseVO();
+        Converter.copy(vo, application);
+        Converter.copy(vo, caseItem);
+        vo.setPlatform(AppPlatform.fromShort(application.getPlatform()).getPlatform());
+        vo.setTaskId(taskId);
+        if (taskId != null && user.getIdentity()==UserType.MANAGER) {
+            //todo 验证身份是否是taskOwner,等慕测接口写好
+//            Task task = taskService.getTaskInfo();
+            vo.setEditRule(true);
+            ScoreRule scoreRule = caseService.getScoreRule(taskId, caseId);
+            vo.setScriptPercentage(scoreRule.getScript());
+            vo.setManualPercentage(scoreRule.getManual());
+        }
+        if (user.getIdentity()== UserType.WORKER && needReport && taskId != null) {
+            Long reportId = reportService.getFirstReportId(taskId, caseId, CurrentUser.get().getId());
+            if (reportId == null) {
+                vo.setReportId(null);
+            } else {
+                vo.setReportId(ReportIndex.encrypt(ReportIndex.getDefaultIndex(reportId)));
+            }
+        }
+        successResult.put(ResponseMessage.ITEM_RESULT, vo);
+        return successResult;
+    }*/
+
+    /**
+     * 更新Case
+     *
+     * @param caseId
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"case/{caseId}", method = RequestMethod.PUT)
+    public Map<String, Object> update(@PathVariable @NotNull Long caseId,
+                                      @RequestBody @NotNull CaseCreateVO vo) throws Exception {
+        vo.validate();
+        SuccessResult successResult = new SuccessResult();
+        caseService.updateCase(caseId, vo);
+        return successResult;
+    }
+
+    /**
+     * 参加case
+     *
+     * @param caseId
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"case/{caseId}/take", method = RequestMethod.POST)
+    public Map<String, Object> takeCase(@PathVariable @NotNull Long caseId,
+                                        @RequestBody @NotNull TakeCaseVO vo) throws Exception {
+        SuccessResult successResult = new SuccessResult();
+        boolean result = caseService.takeCase(vo.getWorkerId(), caseId, vo.getTaskId());
+        successResult.put(ResponseMessage.ITEM_RESULT, result);
+        return successResult;
+    }
+
+}

+ 46 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/KibugTaskController.java

@@ -0,0 +1,46 @@
+package cn.iselab.mooctest.site.web.ctrl.fromKibug;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.web.ResponseMessage;
+import cn.iselab.mooctest.site.common.web.SuccessResult;
+import cn.iselab.mooctest.site.models.fromKibug.TaskFromKibug;
+import cn.iselab.mooctest.site.util.http.RequestUtils;
+import cn.iselab.mooctest.site.web.util.TimeUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by NJUta on 2017/6/1.
+ */
+@RestController
+public class KibugTaskController {
+
+    /**
+     * worker获取自己的task列表
+     *
+     * @return
+     */
+    /*@RequestMapping(value= UrlConstants.API_KIBUG+"task", method = RequestMethod.GET)
+    public Map<String, Object> search(HttpServletRequest request, @RequestParam(name = "groupId", required = false) Long groupId) throws Exception {
+        List<TaskFromKibug> taskList = taskService.getTaskByWorker(RequestUtils.getWorkerId(request), groupId);
+        List<TaskFromKibug> returnList = new ArrayList<>();
+        long currentTime = System.currentTimeMillis();
+        for (TaskFromKibug task : taskList) {
+            if (TimeUtils.parseTimeStr(task.getBeginTime()) < currentTime) {
+                returnList.add(task);
+            }
+        }
+        SuccessResult result = new SuccessResult();
+
+        result.put(ResponseMessage.List_RESULT, returnList);
+
+        return result;
+    }*/
+}

+ 66 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/MobileClientController.java

@@ -0,0 +1,66 @@
+package cn.iselab.mooctest.site.web.ctrl.fromKibug;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import cn.iselab.mooctest.site.common.web.ResponseMessage;
+import cn.iselab.mooctest.site.common.web.SuccessResult;
+import cn.iselab.mooctest.site.models.fromKibug.MobileClient;
+import cn.iselab.mooctest.site.service.fromKibug.MobileClientService;
+import cn.iselab.mooctest.site.web.data.fromKibug.CreateMobileClientVO;
+import cn.iselab.mooctest.site.web.data.fromKibug.MobileClientVO;
+import cn.iselab.mooctest.site.web.util.Converter;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+public class MobileClientController {
+
+    @Autowired
+    private MobileClientService mobileClientService;
+    /**
+     * 获取最新客户端链接
+     *
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"client", method = RequestMethod.GET)
+    @ResponseBody
+    public Map<String, Object> get(@RequestParam(name = "platform", required = false) String platform) throws Exception {
+        AppPlatform appPlatform = null;
+        if (platform != null)
+            appPlatform = AppPlatform.parse(platform);
+        List<MobileClient> mobileClients = mobileClientService.getLastestMobileClients(appPlatform);
+        List<MobileClientVO> mobileClientVoList = Lists.transform(mobileClients, item -> {
+            MobileClientVO clientVo = Converter.convert(MobileClientVO.class, item);
+            clientVo.setPlatform(AppPlatform.fromShort(item.getPlatform()).getPlatform());
+            return clientVo;
+        });
+        SuccessResult successResult = new SuccessResult();
+        if (platform != null) {
+            successResult.put(ResponseMessage.ITEM_RESULT, mobileClientVoList.size() > 0 ? mobileClientVoList.get(0) : null);
+        } else {
+            successResult.put(ResponseMessage.List_RESULT, mobileClientVoList);
+        }
+        return successResult;
+    }
+
+    /**
+     * 创建最新客户端连接
+     *
+     * @param vo
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"client", method = RequestMethod.POST)
+    public Map<String, Object> create(@RequestBody @NotNull CreateMobileClientVO vo) throws Exception {
+        vo.validate();
+        SuccessResult successResult = new SuccessResult();
+        int id = mobileClientService.create(vo);
+        successResult.put(ResponseMessage.ID_RESULT, id);
+        return successResult;
+    }
+}

+ 41 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/StatisController.java

@@ -0,0 +1,41 @@
+package cn.iselab.mooctest.site.web.ctrl.fromKibug;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.web.ResponseMessage;
+import cn.iselab.mooctest.site.common.web.SuccessResult;
+import cn.iselab.mooctest.site.models.fromKibug.AppStatis;
+import cn.iselab.mooctest.site.service.fromKibug.StatisService;
+import cn.iselab.mooctest.site.web.data.fromKibug.AppStatisVO;
+import cn.iselab.mooctest.site.web.util.Converter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+public class StatisController {
+
+    @Autowired
+    StatisService statisService;
+
+    /**
+     * 获取应用的统计信息
+     *
+     * @param appId
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value= UrlConstants.API_KIBUG+"statis/app/{appId}", method = RequestMethod.GET)
+    public Map<String, Object> app(@PathVariable Long appId) throws Exception {
+        SuccessResult successResult = new SuccessResult();
+        AppStatis appStatis = statisService.getAppStatis(appId);
+        AppStatisVO vo = Converter.convert(AppStatisVO.class, appStatis);
+//        vo.setReportCount(statisService.getAppReports(appId));
+//        vo.setWorkerCount(statisService.getAppWorkers(appId));
+        successResult.put(ResponseMessage.ITEM_RESULT, vo);
+        return successResult;
+    }
+}

+ 9 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/TaskVO.java

@@ -23,8 +23,17 @@ public class TaskVO extends BaseVO {
     private List<CaseBlockVO> caseBlocks;
     private Integer workerCount;
     private List<ManagerVO> assistantManagers;
+    private List<String> groupNames;
     private Integer status;
 
+    public List<String> getGroupNames() {
+        return groupNames;
+    }
+
+    public void setGroupNames(List<String> groupNames) {
+        this.groupNames = groupNames;
+    }
+
     public Long getId() {
         return id;
     }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/AppStatisVO.java

@@ -0,0 +1,11 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+@Data
+public class AppStatisVO {
+    private long id;
+    private String deviceModelStatis;
+    private String deviceOsStatis;
+    private int reportCount;
+    private int workerCount;
+}

+ 34 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/ApplicationVO.java

@@ -0,0 +1,34 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+
+@Data
+public class ApplicationVO extends ValidateVO {
+    private long id;
+    private long managerId;
+    private long uploadedCaseId;
+    private String name;
+    private String platform;
+    private String category;
+    private int appSize;
+    private String iconLocation;
+    private String appLocation;
+    private String requireLocation;
+    private String launchData;
+    private long createTimeMillis;
+    private long endTimeMillis;
+    private short testType;
+    private short status;
+    private String extra;
+    private int fromCloud;
+
+    @Override
+    public void validate() throws IllegalArgumentException {
+        notNull("managerId", managerId);
+        notNull("uploadedCaseId", uploadedCaseId);
+        notEmpty("name", name);
+        notEmpty("platform", platform);
+        notEmpty("category", category);
+    }
+}
+

+ 19 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/AutoTestVO.java

@@ -0,0 +1,19 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+
+@Data
+public class AutoTestVO extends ValidateVO {
+    private Long managerId;
+    private String name;
+    private String iconLocation;
+    private String appLocation;
+
+    @Override
+    public void validate() throws IllegalArgumentException {
+        notEmpty("name", name);
+        notNull("managerId", managerId);
+        notEmpty("iconLocation", appLocation);
+        notEmpty("appLocation", appLocation);
+    }
+}

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/CaseCreateVO.java

@@ -0,0 +1,22 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class CaseCreateVO  extends ValidateVO {
+
+    private Long applicationId;
+    private String name;
+    private String scriptTemplateUrl;
+    private String scriptTemplateName;
+    private String description;
+
+    @Override
+    public void validate() throws IllegalArgumentException {
+        notNull("applicationId", applicationId);
+        inLength("name", name, 2, 100);
+        inLength("description", description, 1, 1000);
+    }
+}

+ 21 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/CaseListItemVO.java

@@ -0,0 +1,21 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CaseListItemVO {
+    private long id;
+    private long applicationId;
+    private String name;
+    private String description;
+    private String platform;
+    private String category;
+    private String scriptTemplateUrl;
+    private String scriptTemplateName;
+    private String iconLocation;
+
+    private Long taskId;
+    private Boolean taken;
+}

+ 31 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/CreateMobileClientVO.java

@@ -0,0 +1,31 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import cn.iselab.mooctest.site.common.enums.AppPlatform;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * Created by NJUta on 2017/6/1.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class CreateMobileClientVO extends ValidateVO {
+    private String platform;
+    private String url;
+    private AppPlatform parsedPlatform;
+    private Float version;
+    private String description;
+
+    public AppPlatform getParsedPlatform() {
+        return parsedPlatform == null ? AppPlatform.parse(platform) : parsedPlatform;
+    }
+
+    @Override
+    public void validate() throws IllegalArgumentException {
+        notNull("platform", platform);
+        parsedPlatform = AppPlatform.parse(platform);
+        notNull("category", url);
+        notNull("version", version);
+        inLength("description", description, 0, 125);
+    }
+}

+ 34 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/KibugCaseVO.java

@@ -0,0 +1,34 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+
+@Data
+public class KibugCaseVO {
+    private long id;
+    private long applicationId;
+    private String name;
+    private String scriptTemplateUrl;
+    private String scriptTemplateName;
+    private String description;
+
+    private long managerId;
+    private String platform;
+    private String category;
+    private int appSize;
+    private String iconLocation;
+    private String appLocation;
+    private String requireLocation;
+    private String launchData;
+    private String extra;
+
+    private Long taskId;
+    private Boolean taken;
+
+    //是否有权限修改评分
+    private boolean editRule = false;
+    //占分比例
+    private int manualPercentage;
+    private int scriptPercentage;
+
+    private String reportId;
+}

+ 15 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/MobileClientVO.java

@@ -0,0 +1,15 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+
+/**
+ * Created by jessiechen on 2016/10/22.
+ */
+@Data
+public class MobileClientVO {
+    private int id;
+    private String platform;
+    private String url;
+    private float version;
+    private String description;
+}

+ 15 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/TakeCaseVO.java

@@ -0,0 +1,15 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import lombok.Data;
+
+@Data
+public class TakeCaseVO extends ValidateVO{
+    private Long taskId;
+    private Long workerId;
+
+    @Override
+    public void validate() throws IllegalArgumentException {
+        notNull("taskId", taskId);
+        notNull("workerId", workerId);
+    }
+}

+ 14 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/UserVO.java

@@ -0,0 +1,14 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+import cn.iselab.mooctest.site.common.enums.UserType;
+import lombok.Data;
+
+/**
+ * Created by NJUta on 2017/6/2.
+ */
+@Data
+public class UserVO {
+    private long id;
+    private UserType identity;
+    private String name;
+}

+ 45 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromKibug/ValidateVO.java

@@ -0,0 +1,45 @@
+package cn.iselab.mooctest.site.web.data.fromKibug;
+
+public abstract class ValidateVO {
+
+    protected static void inRange(String property, Integer value, int lbound, int ubound) throws IllegalArgumentException {
+        notNull(property, value);
+        if (value < lbound || value > ubound) {
+            String errorMsg = String.format("%s must be in range [%d, %d]", property, lbound, ubound);
+            throw new IllegalArgumentException(errorMsg);
+        }
+    }
+
+    protected static void inLength(String property, String value, int lbound, int ubound) throws IllegalArgumentException {
+        notNull(property, value);
+        int length = value.length();
+        if (length < lbound || length > ubound) {
+            String errorMsg = String.format("%s must be in length of [%d, %d]", property, lbound, ubound);
+            throw new IllegalArgumentException(errorMsg);
+        }
+    }
+
+    protected static void notEmpty(String property, String value) throws IllegalArgumentException {
+        if (value == null || value.trim().isEmpty()) {
+            String errorMsg = String.format("%s must not be empty", property);
+            throw new IllegalArgumentException(errorMsg);
+        }
+    }
+
+    protected static void notNull(String property, Object value) throws IllegalArgumentException {
+        String errorMsg = String.format("%s must not be null", property);
+        if (value == null)
+            throw new IllegalArgumentException(errorMsg);
+    }
+
+    protected static boolean notAllNull(Object... objects) {
+        for (Object object : objects) {
+            if (object != null)
+                return true;
+        }
+        return false;
+    }
+
+    public abstract void validate() throws IllegalArgumentException;
+
+}

+ 16 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/IllegalOperationException.java

@@ -0,0 +1,16 @@
+package cn.iselab.mooctest.site.web.exception;
+
+
+import cn.iselab.mooctest.site.common.web.StatusCode;
+
+public class IllegalOperationException extends ServerException {
+
+    public IllegalOperationException() {
+        super(StatusCode.ILLEGAL_OPERATION, "ILLEGAL_OPERATION");
+    }
+
+    public IllegalOperationException(String message) {
+        super(StatusCode.ILLEGAL_OPERATION, message);
+    }
+
+}

+ 34 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/ServerException.java

@@ -0,0 +1,34 @@
+package cn.iselab.mooctest.site.web.exception;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: qgan(qgan@v5.cn)
+ * Date: 14-3-11
+ * Time: 下午7:13
+ * To change this template use File | Settings | File Templates.
+ */
+public class ServerException extends RuntimeException {
+    private int errorCode;
+    private String error;
+
+    public ServerException(int errorCode, String error) {
+        this.error = error;
+        this.errorCode = errorCode;
+    }
+
+    public int getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(int errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/TaskLogic.java

@@ -40,4 +40,6 @@ public interface TaskLogic {
     ManagerVO editAssistantManager(long managerId, long id, ManagerVO assisManagerVO);
 
     List<GradeVO> getGrades(long taskId);
+
+    TaskVO getTaskDetailByWorker(long workerId, long taskId);
 }

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ManagerLogicImpl.java

@@ -80,6 +80,7 @@ public class ManagerLogicImpl implements ManagerLogic {
         if (manager == null) {
             return null;
         }
+
         manager.setStatus(managerVO.getStatus());
         manager.setGroupSize(managerVO.getGroupSize());
         manager.setGroupNum(managerVO.getGroupNum());

+ 26 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TaskLogicImpl.java

@@ -606,4 +606,30 @@ public class TaskLogicImpl extends BaseLogic implements TaskLogic {
     private DevCase getCase(long caseId) {
         return taskService.getCase(caseId);
     }
+
+    public TaskVO getTaskDetailByWorker(long workerId, long taskId) {
+        Task task = taskService.getTask(taskId);
+
+        if (task == null) {
+            throw new HttpNotFoundException("task not exits");
+        }
+        if (assignedTaskService.getAssignedTask(taskId, workerId) == null) {
+            throw new HttpForbiddenException("worker not task the task");
+        }
+
+        TaskVO taskVO = taskVOWrapper.wrap(task);
+        Manager manager = managerService.getManagerById(task.getManagerId());
+        taskVO.setManagerName(manager.getName());
+        List<Long> groupIds = groupService.getGroupIdsByTaskId(taskId);
+
+        List<String> groupNames = new ArrayList<>();
+
+        for (Long groupId : groupIds) {
+            if (groupService.getWorkersByGroupId(groupId).contains(workerService.getWorkerById(workerId))) {
+                groupNames.add(groupService.getGroup(groupId).getName());
+            }
+        }
+        taskVO.setGroupNames(groupNames);
+        return taskVO;
+    }
 }

+ 81 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/util/Converter.java

@@ -0,0 +1,81 @@
+package cn.iselab.mooctest.site.web.util;
+
+import com.google.common.collect.Maps;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.cglib.beans.BeanCopier;
+
+import java.util.Map;
+
+public class Converter {
+
+    private static Map<CopierIdentity, BeanCopier> copierCache = Maps.newConcurrentMap();
+    private static PrimitiveConverter primitiveConverter = new PrimitiveConverter();
+
+    public static <T> T copy(T target, Object source) {
+        BeanCopier copier = getCopier(source.getClass(), target.getClass());
+        copier.copy(source, target, primitiveConverter);
+        return target;
+    }
+
+    public static <T> T convert(Class<T> targetClass, Object source) {
+        try {
+            T target = targetClass.newInstance();
+            BeanCopier copier = getCopier(source.getClass(), targetClass);
+            copier.copy(source, target, primitiveConverter);
+            return target;
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static BeanCopier getCopier(Class<?> source, Class<?> target) {
+        CopierIdentity identity = new CopierIdentity(source, target);
+        BeanCopier copier;
+        if (copierCache.containsKey(identity)) {
+            copier = copierCache.get(identity);
+        } else {
+            copier = BeanCopier.create(source, target, true);
+            copierCache.putIfAbsent(identity, copier);
+        }
+        return copier;
+    }
+
+    public static class PrimitiveConverter implements org.springframework.cglib.core.Converter {
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object convert(Object value, Class target, Object context) {
+            if (value == null) return null;
+            if (target.equals(String.class)
+                    && !String.class.isAssignableFrom(value.getClass()))
+                return value.toString();
+            if (Number.class.isAssignableFrom(value.getClass())) {
+                Number num = (Number) value;
+                if (target.equals(int.class) || target.equals(Integer.class))
+                    return num.intValue();
+                else if (target.equals(long.class) || target.equals(Long.class))
+                    return num.longValue();
+                else if (target.equals(short.class) || target.equals(Short.class))
+                    return num.shortValue();
+                else if (target.equals(float.class) || target.equals(Float.class))
+                    return num.floatValue();
+                else if (target.equals(double.class) || target.equals(Double.class))
+                    return num.doubleValue();
+                else if (target.equals(byte.class) || target.equals(Byte.class))
+                    return num.byteValue();
+            } else if (target.isAssignableFrom(value.getClass()))
+                return value;
+            return null;
+        }
+    }
+
+    @AllArgsConstructor
+    @Data
+    @EqualsAndHashCode
+    private static class CopierIdentity {
+        private Class<?> source;
+        private Class<?> target;
+    }
+
+}

+ 32 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/util/TimeUtils.java

@@ -0,0 +1,32 @@
+package cn.iselab.mooctest.site.web.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * Created by jessiechen on 2016/12/9.
+ */
+public class TimeUtils {
+
+    private static Logger logger = LoggerFactory.getLogger(TimeUtils.class);
+
+    public static long parseTimeStr(String timeStr) throws ParseException {
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.s");
+        formatter.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+        Date time = formatter.parse(timeStr);
+        return time.getTime();
+    }
+
+    public static void main(String args[]) {
+        try {
+            System.out.println(TimeUtils.parseTimeStr("2016-12-03 14:00:00.0"));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 3 - 0
mooctest-site-server/src/main/resources/application.properties

@@ -0,0 +1,3 @@
+mooc.webUrl=http://www.mooctest.net
+mooc.kiBugSecret=kibug.mooctest.net
+mooc.kiJamSecret=kijam.mooctest.net

+ 1 - 1
mooctest-site-server/src/main/resources/application.yaml

@@ -76,7 +76,7 @@ spring:
     profiles: pre 
     datasource:
         url: jdbc:mysql://localhost:3306/mooctest_main?useUnicode=yes&characterEncoding=UTF-8
-        username: root
+        username: mooctest
         password: secr3t!
 
 server:

+ 52 - 0
mooctest-site-server/src/test/java/cn/iselab/mooctest/site/service/fromKibug/impl/ApplicationServiceImplTest.java

@@ -0,0 +1,52 @@
+package cn.iselab.mooctest.site.service.fromKibug.impl;
+
+import cn.iselab.mooctest.site.Application;
+import cn.iselab.mooctest.site.dao.fromKibug.ApplicationDao;
+import org.hibernate.validator.constraints.Mod10Check;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.when;
+
+/**
+ * Created by NJUta on 2017/6/2.
+ */
+
+@RunWith(MockitoJUnitRunner.class)
+@WebAppConfiguration
+@SpringApplicationConfiguration(classes = Application.class)
+public class ApplicationServiceImplTest {
+    @InjectMocks()
+    private ApplicationServiceImpl applicationService = new ApplicationServiceImpl();
+
+    @Mock
+    private ApplicationDao applicationDao;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+    @Test
+    public void test_getAppById() throws Exception {
+        cn.iselab.mooctest.site.models.fromKibug.Application except = new cn.iselab.mooctest.site.models.fromKibug.Application();
+        except.setId(888);
+        when(applicationDao.findOne(0L)).thenReturn(except);
+        applicationService.getAppById(0L);
+        Assert.assertEquals(except.getId(), 888);
+    }
+
+}