梅杰 пре 8 година
родитељ
комит
6fce6ee50d
100 измењених фајлова са 1767 додато и 252 уклоњено
  1. 19 1
      mooctest-site-server/pom.xml
  2. 18 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/Application.java
  3. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/AliyunOSSConstants.java
  4. 2 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/AnswerWayConstants.java
  5. 13 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/BugStatusConstants.java
  6. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/OwningPartyConstants.java
  7. 12 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/PathConstants.java
  8. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/TargetTypeConstants.java
  9. 25 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/PublicityCaseEvent.java
  10. 26 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/PublicityTargetEvent.java
  11. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/StatisEventsListener.java
  12. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ApplicationStartup.java
  13. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ClientFeatureConfiguration.java
  14. 25 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java
  15. 19 8
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/realm/ShiroRealm.java
  16. 19 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/AssignedTask2UserInfoDao.java
  17. 2 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/AssignedTaskDao.java
  18. 2 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/CaseDao.java
  19. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Comment2CaseDao.java
  20. 18 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Comment2TargetDao.java
  21. 14 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/CommentDao.java
  22. 15 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ContestMentorAssignedTaskDao.java
  23. 11 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ContestMentorDao.java
  24. 14 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ContestMentorExamDao.java
  25. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Exam2CaseDao.java
  26. 0 17
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ExamGroupUserDao.java
  27. 4 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GroupDao.java
  28. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/PaperDao.java
  29. 18 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ParticipantExamDao.java
  30. 15 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/UserOperationDao.java
  31. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/instancePermission/TaskPermissionDao.java
  32. 48 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/shiro/MySessionDao.java
  33. 104 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/AssignedTask2UserInfo.java
  34. 57 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Comment.java
  35. 59 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Comment2Case.java
  36. 58 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Comment2Target.java
  37. 57 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ContestMentorExam.java
  38. 4 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/DevTarget.java
  39. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Paper.java
  40. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ParticipantExam.java
  41. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User.java
  42. 27 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/UserOperation.java
  43. 4 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/WebTarget.java
  44. 11 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/Oauth2/impl/ExamServiceImpl2.java
  45. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/ServerRunner.java
  46. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceImpl.java
  47. 45 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceMockImpl.java
  48. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/SourceServiceImpl.java
  49. 33 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/SourceServiceMockImpl.java
  50. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/kibug/impl/KibugServiceImpl.java
  51. 30 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/kibug/impl/KibugServiceMockImpl.java
  52. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/AssignedTask2UserInfoService.java
  53. 7 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/AssignedTaskService.java
  54. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CaseService.java
  55. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CommentService.java
  56. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/ContestMentorService.java
  57. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/DetailStatisticsService.java
  58. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/EmailService.java
  59. 11 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/ExamService.java
  60. 15 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/RecordService.java
  61. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TargetService.java
  62. 0 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/Task2AssistantManagerService.java
  63. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/WechatService.java
  64. 41 6
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/impl/WechatServiceImpl.java
  65. 0 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/common/impl/MongoAPIServiceImpl.java
  66. 2 40
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromDev/impl/PluginServiceImpl.java
  67. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/ReportService.java
  68. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/ReportServiceImpl.java
  69. 45 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/AssignedTask2UserInfoServiceImpl.java
  70. 14 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/AssignedTaskServiceImpl.java
  71. 24 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaseServiceImpl.java
  72. 67 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CommentServiceImpl.java
  73. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/ContestMentorServiceImpl.java
  74. 19 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/DetailStatisticsServiceImpl.java
  75. 28 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/EmailServiceImpl.java
  76. 41 19
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/ExamServiceImpl.java
  77. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GroupServiceImpl.java
  78. 0 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/MenuServiceImpl.java
  79. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/PaperServiceImpl.java
  80. 90 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/RecordServiceImpl.java
  81. 13 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TargetServiceImpl.java
  82. 0 49
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/Task2AssistantManagerServiceImpl.java
  83. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/instancePermission/AppPermissionService.java
  84. 20 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/instancePermission/impl/AppPermissionServiceImpl.java
  85. 5 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/data/JSONUtil.java
  86. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/http/RequestUtils.java
  87. 24 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CaseController.java
  88. 76 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CommentController.java
  89. 4 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ContestController.java
  90. 41 19
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ExamController.java
  91. 26 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/OSSController.java
  92. 22 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PaperController.java
  93. 15 6
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TargetController.java
  94. 41 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TestController.java
  95. 57 24
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/UserController.java
  96. 8 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/WechatController.java
  97. 0 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/AnalysisController.java
  98. 6 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/PluginController.java
  99. 1 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/BugController.java
  100. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/ReportController.java

+ 19 - 1
mooctest-site-server/pom.xml

@@ -19,7 +19,7 @@
             <groupId>cn.iselab.mooctest</groupId>
 
             <artifactId>dev-dubbo-api</artifactId>
-            <version>1.7</version>
+            <version>1.8</version>
 
         </dependency>
         <dependency>
@@ -178,6 +178,24 @@
         </dependency>
         <!-- MS framework dependencies end -->
 
+        <!--EasyExcel dependencies-->
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-base</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-web</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-annotation</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <!--EasyExcel END-->
+
         <!-- SMS dependency -->
         <dependency>
             <groupId>cn.iselab</groupId>

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

@@ -46,12 +46,16 @@ import org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration;
 import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
 import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration;
 import org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration;
+import org.springframework.boot.context.embedded.MultipartConfigFactory;
 import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
+import javax.servlet.MultipartConfigElement;
+
 /**
  * @author liuzicong
  */
@@ -112,4 +116,18 @@ public class Application {
         application.addListeners(new ApplicationStartup());
         application.run(args);
     }
+
+    /**
+     * 文件上传配置
+     * @return
+     */
+    @Bean
+    public MultipartConfigElement multipartConfigElement() {
+        MultipartConfigFactory factory = new MultipartConfigFactory();
+        //单个文件最大
+        factory.setMaxFileSize("100MB"); //KB,MB
+        /// 设置总上传数据总大小
+        factory.setMaxRequestSize("500MB");
+        return factory.createMultipartConfig();
+    }
 }

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/AliyunOSSConstants.java

@@ -11,4 +11,6 @@ public class AliyunOSSConstants {
     public static final String PATH_TARGET = "target/";
 
     public static final String CERTIFICATE = "certificate/";
+
+    public static final String HEADIMAGE = "headImage/";
 }

+ 2 - 7
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/AnswerWayConstants.java

@@ -23,11 +23,6 @@ public class AnswerWayConstants {
     public static final long REPORT = 5;
     public static final long EMBEDDED = 6;
     public static final long JMETER = 7;
-
-//    public static final long PYTHON_SUBSITE_ID = 4;   -》 -2
-//    public static final int KIKBUG_SUBSITE_ID = 6;
-//    public static final long KIVUL_SUBSITE_ID = 7;     -》 -1
-//    public static final long DEV_SUBSITE_ID = 10;
-//    public static final int KIJAM_SUBSITE_ID = 12;
-//    public static final long DEVELOP_SUBSITE_ID = 13;
+    public static final long ZHICEYUN = 8;
+    public static final long KIVUL = 9;
 }

+ 13 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/BugStatusConstants.java

@@ -0,0 +1,13 @@
+package cn.iselab.mooctest.site.common.constant;
+
+/**
+ * @Author ROKG
+ * @Description
+ * @Date: Created in 下午10:59 2017/12/3
+ * @Modified By:
+ */
+public class BugStatusConstants {
+
+    public static short BUG_NOT_DELETE=0;
+    public static short BUG_DELETE=1;
+}

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/OwningPartyConstants.java

@@ -15,5 +15,9 @@ public class OwningPartyConstants {
 
     public final static Integer KAIYUN=4;
 
+    public final static Integer KIVUL=7;
+
+    public final static Integer ZHICEYUN=6;
+
     public final static String THIRDEMAIL="anheng@mooctest.net";
 }

+ 12 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/constant/PathConstants.java

@@ -0,0 +1,12 @@
+package cn.iselab.mooctest.site.common.constant;
+
+import org.apache.commons.io.FileUtils;
+
+/**
+ * Created by ROGK on 2017/10/14.
+ */
+public class PathConstants {
+    public static String HOME= FileUtils.getUserDirectoryPath();
+
+    public static String SCRIPTS=HOME+ "/scripts";
+}

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

@@ -7,4 +7,5 @@ public class TargetTypeConstants {
     public static final int KIBUG = 6;
     public static final int WEB = 8;
     public static final int DEV = 10;
+    public static final int PC = 11;
 }

+ 25 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/PublicityCaseEvent.java

@@ -0,0 +1,25 @@
+package cn.iselab.mooctest.site.common.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * Created by major on 2017/10/25.
+ */
+
+@Getter
+@Builder
+@AllArgsConstructor
+public class PublicityCaseEvent implements Event {
+    Long caseId;
+
+    public static PublicityCaseEvent create(Long caseId){
+        return new PublicityCaseEvent(caseId);
+    }
+
+    @Override
+    public String getDescription() {
+        return String.format("publicity case, id: %s", caseId);
+    }
+}

+ 26 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/event/PublicityTargetEvent.java

@@ -0,0 +1,26 @@
+package cn.iselab.mooctest.site.common.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+
+/**
+ * Created by HenryLee on 2017/10/17.
+ */
+
+@Getter
+@Builder
+@AllArgsConstructor
+public class PublicityTargetEvent implements Event{
+
+    Long targetId;
+
+    public static PublicityTargetEvent create(Long targetId){
+        return new PublicityTargetEvent(targetId);
+    }
+
+    @Override
+    public String getDescription() {
+        return String.format("publicity target, id: %s", targetId);
+    }
+}

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

@@ -1,7 +1,9 @@
 package cn.iselab.mooctest.site.common.event;
 
 import cn.iselab.mooctest.site.service.ContestMentorService;
+import cn.iselab.mooctest.site.service.TargetService;
 import cn.iselab.mooctest.site.service.fromKibug.StatisService;
+import cn.iselab.mooctest.site.web.logic.CaseLogic;
 import com.google.common.eventbus.Subscribe;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +21,12 @@ public class StatisEventsListener implements InitializingBean {
     @Autowired
     private ContestMentorService instructorService;
 
+    @Autowired
+    private TargetService targetService;
+
+    @Autowired
+    private CaseLogic caseLogic;
+
     @Override
     public void afterPropertiesSet() throws Exception {
         eventUtil.register(this);
@@ -40,4 +48,13 @@ public class StatisEventsListener implements InitializingBean {
         instructorService.updateContestMentorPermisson(event.getExamId(),event.getStudentId(), event.getTeacherEmails());
     }
 
+    @Subscribe
+    public void publicityTarget(PublicityTargetEvent publicityTargetEvent) throws Exception {
+        targetService.publicityTarget(publicityTargetEvent.getTargetId());
+    }
+
+    @Subscribe
+    public void publicityCase(PublicityCaseEvent publicityCaseEvent) throws Exception {
+        caseLogic.publicityCase(publicityCaseEvent.getCaseId());
+    }
 }

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ApplicationStartup.java

@@ -14,7 +14,7 @@ public class ApplicationStartup implements ApplicationListener<ContextRefreshedE
         System.out.println("-----------------------------------------------------------------------------------------");
         System.out.println("listener");
         ExamController examController = event.getApplicationContext().getBean(ExamController.class);
-        examController.updateStatusForAllTask();
+   //     examController.updateStatusForAllTask();
         examController.startInitExamSchedulerMap();
         System.out.println("exam scheduler map initialized");
         System.out.println("-----------------------------------------------------------------------------------------");

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ClientFeatureConfiguration.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.configure;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by tangshanshan on 2017/11/17.
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix="featureSwitch.client")
+public class ClientFeatureConfiguration {
+    private String sms;
+    private String email;
+    private String oss;
+}

+ 25 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java

@@ -2,12 +2,15 @@ package cn.iselab.mooctest.site.configure;
 
 import cn.iselab.mooctest.site.configure.realm.MyAuthorizationFilter;
 import cn.iselab.mooctest.site.configure.realm.ShiroRealm;
+import cn.iselab.mooctest.site.dao.shiro.MySessionDao;
 import org.apache.shiro.cache.ehcache.EhCacheManager;
 import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
 import org.apache.shiro.spring.LifecycleBeanPostProcessor;
 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
 import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
@@ -63,6 +66,7 @@ public class ShiroConfiguration {
         DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
         securityManager.setRealm(shiroRealm);
         securityManager.setCacheManager(ehCacheManager());
+        //securityManager.setSessionManager(defaultWebSessionManager());
         return securityManager;
     }
 
@@ -83,6 +87,7 @@ public class ShiroConfiguration {
 
         filterChainDefinitionManager.put("/api/test/login", "anon");
         filterChainDefinitionManager.put("/api/test/register", "anon");
+        filterChainDefinitionManager.put("/api/featureSwitch", "anon");
         filterChainDefinitionManager.put("/api/common/**", "anon");
         filterChainDefinitionManager.put("/api/mobileLogin", "anon");
 
@@ -125,6 +130,26 @@ public class ShiroConfiguration {
         return aASA;
     }
 
+    @Bean(name = "sessionDao")
+    public MySessionDao sessionDao(){
+        MySessionDao sessionDao = new MySessionDao();
+        sessionDao.setSessionIdGenerator(new JavaUuidSessionIdGenerator());
+//        sessionDao.setSessionIdGenerator(JavaUuidSessionIdGenerator);
+        return sessionDao;
+    }
+
+    @Bean(name = "sessionManager")
+    public DefaultWebSessionManager defaultWebSessionManager(){
+        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
+        sessionManager.setCacheManager(ehCacheManager());
+        sessionManager.setGlobalSessionTimeout(1800000);//超时时间
+        sessionManager.setSessionValidationSchedulerEnabled(true);//定时清除无效的session
+        sessionManager.setSessionValidationInterval(1800000);//半个小时清理一次失效的session
+        sessionManager.setDeleteInvalidSessions(true);//删除无效的session
+        sessionManager.setSessionDAO(sessionDao());
+        return sessionManager;
+    }
+
 }
 
 

+ 19 - 8
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/realm/ShiroRealm.java

@@ -100,25 +100,25 @@ public class ShiroRealm extends AuthorizingRealm {
         DefaultUsernamepasswordToken upToken = (DefaultUsernamepasswordToken) token;
         String username = upToken.getUsername();
         String loginType = upToken.getLoginType();
-        if(loginType.equals("mobile")){
-            if (userService.findByMobile(username) == null){
+        if (loginType.equals("mobile")) {
+            if (userService.findByMobile(username) == null) {
                 throw new AccountException("user not exist");
             }
             User user = userService.findByMobile(username);
-            if (!mobileVerificationService.validateMobileVerification(username,new String(upToken.getPassword()))){
+            if (!mobileVerificationService.validateMobileVerification(username, new String(upToken.getPassword()))) {
                 throw new IncorrectCredentialsException("wrong verification");
             }
             return new SimpleAuthenticationInfo(username, upToken.getPassword(), getName());
-        }else if(loginType.equals("email&mobile")){
+        } else if (loginType.equals("email&mobile")) {
             User user = userService.findByUsername(username);
             // Null username is invalid
             if (user == null) {
                 throw new AccountException("user not exist.");
             }
-            if (username.isEmpty()){
+            if (username.isEmpty()) {
                 throw new AccountException("empty username");
             }
-            if (userService.findByUsername(username) == null){
+            if (userService.findByUsername(username) == null) {
                 throw new AccountException("user not exist");
             }
             user = userService.findByUsername(username);
@@ -126,7 +126,7 @@ public class ShiroRealm extends AuthorizingRealm {
                 throw new IncorrectCredentialsException("wrong password");
             }
             return new SimpleAuthenticationInfo(username, user.getPassword(), getName());
-        }else{
+        } else {
             return null;
         }
     }
@@ -162,9 +162,12 @@ public class ShiroRealm extends AuthorizingRealm {
     }
 
     private Boolean checkTaskPermission(TaskPermission taskPermission) {
-
         List<TaskPermission> taskPermissions = taskPermissionService.getByUserIdAndInstanceId(taskPermission.getUserId(),
                 taskPermission.getInstanceId());
+        if (taskPermissions.stream().anyMatch(tp -> tp.getUserId().equals(0) &&
+                (tp.getOperation().equals("*") || tp.getOperation().equals(taskPermission.getOperation())))) {
+            return true;
+        }
         return taskPermissions.stream().anyMatch(tp -> tp.implies(taskPermission));
     }
 
@@ -177,12 +180,20 @@ public class ShiroRealm extends AuthorizingRealm {
     private Boolean checkCasePermission(CasePermission casePermission) {
         List<CasePermission> casePermissions = casePermissionService.getByUserIdAndInstanceId(casePermission.getUserId(),
                 casePermission.getInstanceId());
+        if (casePermissions.stream().anyMatch(cp -> cp.getUserId().equals(0) &&
+                (cp.getOperation().equals("*") || cp.getOperation().equals(casePermission.getOperation())))) {
+            return true;
+        }
         return casePermissions.stream().anyMatch(cp -> cp.implies(casePermission));
     }
 
     private Boolean checkGroupPermission(GroupPermission groupPermission) {
         List<GroupPermission> groupPermissions = groupPermissionService.getByUserIdAndInstanceId(groupPermission.getUserId(),
                 groupPermission.getInstanceId());
+        if (groupPermissions.stream().anyMatch(gp -> gp.getUserId().equals(0) &&
+                (gp.getOperation().equals("*") || gp.getOperation().equals(gp.getOperation())))) {
+            return true;
+        }
         return groupPermissions.stream().anyMatch(gp -> gp.implies(groupPermission));
     }
 

+ 19 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/AssignedTask2UserInfoDao.java

@@ -0,0 +1,19 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.AssignedTask2UserInfo;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-10-25.
+ */
+@Transactional
+public interface AssignedTask2UserInfoDao extends CrudRepository<AssignedTask2UserInfo, Long> {
+
+    List<AssignedTask2UserInfo> findByTaskId(Long taskId);
+
+    AssignedTask2UserInfo findByTaskIdAndId(Long taskId, Long participantId);
+}

+ 2 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/AssignedTaskDao.java

@@ -26,7 +26,8 @@ public interface AssignedTaskDao extends PagingAndSortingRepository<AssignedTask
     @Query("SELECT a FROM AssignedTask a WHERE a.taskId = :taskId AND a.workerId = :workerId")
     AssignedTask findByTaskIdAndWorkerIdIgnoringDeletion(@Param("taskId") long taskId, @Param("workerId") long workerId);
 
-    Page<AssignedTask> findByTaskId(Long examId, Pageable pageable);
+    @Query("SELECT a FROM AssignedTask a, User u WHERE a.taskId = :taskId AND a.participantId = u.id and u.name like concat('%',:keyword,'%') ")
+    Page<AssignedTask> findByTaskId(@Param("taskId")Long examId, @Param("keyword")String keyword, Pageable pageable);
 
     List<AssignedTask> findByParticipantId(long participantId);
 

+ 2 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/CaseDao.java

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.site.dao;
 
 import cn.iselab.mooctest.site.models.Case;
+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;
@@ -12,7 +13,7 @@ import java.util.List;
  * Created by sean on 16/12/24.
  */
 @Transactional
-public interface CaseDao extends PagingAndSortingRepository<Case, Long> {
+public interface CaseDao extends PagingAndSortingRepository<Case, Long>,JpaSpecificationExecutor<Case> {
 
     @Query("SELECT c FROM Case c WHERE c.subjectId = :subjectId AND c.deleted = 0")
     Iterable<Case> findBySubjectId(long subjectId);

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Comment2CaseDao.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.Comment2Case;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-10-11.
+ */
+@Transactional
+public interface Comment2CaseDao extends CrudRepository<Comment2Case, Long> {
+
+    List<Comment2Case> findByCaseId(Long caseId);
+}

+ 18 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Comment2TargetDao.java

@@ -0,0 +1,18 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.Comment2Target;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-10-11.
+ */
+@Transactional
+public interface Comment2TargetDao extends CrudRepository<Comment2Target, Long> {
+
+    List<Comment2Target> findByTargetId(Long targetId);
+
+}

+ 14 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/CommentDao.java

@@ -0,0 +1,14 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.Comment;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * @author sean
+ * @date 2017-10-12.
+ */
+@Transactional
+public interface CommentDao extends CrudRepository<Comment, Long> {
+}

+ 15 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ContestMentorAssignedTaskDao.java

@@ -2,15 +2,28 @@ package cn.iselab.mooctest.site.dao;
 
 import cn.iselab.mooctest.site.models.AssignedTask;
 import cn.iselab.mooctest.site.models.ContestMentorAssignedTask;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
 import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
 
 /**
  * Created by shanshan on 2017/9/14.
  */
-public interface ContestMentorAssignedTaskDao  extends PagingAndSortingRepository<ContestMentorAssignedTask, Long>,JpaSpecificationExecutor<ContestMentorAssignedTask> {
+public interface ContestMentorAssignedTaskDao extends PagingAndSortingRepository<ContestMentorAssignedTask, Long>,JpaSpecificationExecutor<ContestMentorAssignedTask>,CrudRepository<ContestMentorAssignedTask, Long> {
+
+    @Query("SELECT a FROM ContestMentorAssignedTask a,User u " +
+            "WHERE a.taskId = :taskId " +
+            "AND a.mentorId=:mentorId and a.participantId = u.id " +
+            "and u.name like concat('%',:keyword,'%') ")
+    Page<ContestMentorAssignedTask> findByTaskIdAndMentorId(@Param("taskId")Long examId, @Param("keyword")String keyword, @Param("mentorId")Long userId, Pageable pageable);
 
-    Page<ContestMentorAssignedTask> findByTaskIdAndMentorId(Long examId, Long userId, Pageable pageable);
+    @Query("select a from ContestMentorAssignedTask a where a.taskId=:taskId and a.mentorId=:mentorId")
+    List<ContestMentorAssignedTask> findByTaskIdAndMentorId(@Param("taskId")Long taskId, @Param("mentorId") Long mentorId);
 }

+ 11 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ContestMentorDao.java

@@ -15,7 +15,7 @@ import java.util.List;
  * Created by shanshan on 2017/8/1.
  */
 @Transactional
-public interface ContestMentorDao  extends CrudRepository<ContestMentor, Long> {
+public interface ContestMentorDao extends CrudRepository<ContestMentor, Long> {
     List<ContestMentor> findByExamIdAndParticipantIdAndRole(Long examId, Long userId, Byte role);
 
     @Query("SELECT u FROM User u,ContestMentor cm " +
@@ -25,4 +25,14 @@ public interface ContestMentorDao  extends CrudRepository<ContestMentor, Long> {
 
     @Query("SELECT count(u.id) from User u, ContestMentor cm where u.id=:userId and u.email=cm.teacherEmail and cm.role=0")
     Long countByTeacherId(@Param("userId") Long userId);
+
+    @Query("SELECT DISTINCT cm.examId from ContestMentor cm where cm.teacherEmail=:teacherEmail")
+    List<Long> findByMentor(@Param("teacherEmail") String teacherEmail);
+
+    List<ContestMentor> findByExamIdAndTeacherName(Long examId, Long teacherName);
+
+    @Query("SELECT cm FROM ContestMentor cm WHERE cm.examId = :examId " +
+            "AND cm.teacherEmail = :email " +
+            "AND cm.role = 0")
+    List<ContestMentor> findByExamIdAndTeacherEmail(@Param("examId") Long examId, @Param("email") String email);
 }

+ 14 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ContestMentorExamDao.java

@@ -0,0 +1,14 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.ContestMentorExam;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * Created by tangshanshan on 2017/12/4.
+ */
+@Transactional
+public interface ContestMentorExamDao extends PagingAndSortingRepository<ContestMentorExam, Long>,JpaSpecificationExecutor<ContestMentorExam> {
+}

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

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.site.dao;
 
 import cn.iselab.mooctest.site.models.Exam2Case;
+import cn.iselab.mooctest.site.models.Exam2Paper;
 import org.springframework.data.repository.CrudRepository;
 
 

+ 0 - 17
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ExamGroupUserDao.java

@@ -1,17 +0,0 @@
-package cn.iselab.mooctest.site.dao;
-
-import cn.iselab.mooctest.site.models.ExamGroupUser;
-import cn.iselab.mooctest.site.models.Task;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.repository.PagingAndSortingRepository;
-
-import java.util.List;
-
-/**
- * Created by shanshan on 2017/7/25.
- */
-public interface ExamGroupUserDao extends PagingAndSortingRepository<ExamGroupUser, Long>,JpaSpecificationExecutor<ExamGroupUser> {
-    ExamGroupUser findByIdAndParticipantId(Long examId, Long participantId);
-
-    List<ExamGroupUser> findByParticipantId(Long participantId);
-}

+ 4 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GroupDao.java

@@ -130,7 +130,10 @@ public interface GroupDao extends PagingAndSortingRepository<Group, Long> {
             " SELECT g2w.participantId " +
             " FROM Group2Worker g2w " +
             " WHERE g2w.groupId=:groupId)" +
-            " AND (u.name LIKE concat('%',:keyword,'%') or u.email LIKE concat('%',:keyword,'%') or u.mobile LIKE concat('%',:keyword,'%'))")
+            " AND (u.name LIKE concat('%',:keyword,'%') " +
+            "or u.email LIKE concat('%',:keyword,'%') " +
+            "or u.mobile LIKE concat('%',:keyword,'%') " +
+            "or u.school LIKE concat('%',:keyword,'%'))")
     Page<User> findByIdAndKeyWord(@Param("groupId")long groupId, @Param("keyword") String keyword, Pageable pageable);
 }
 

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/PaperDao.java

@@ -20,6 +20,9 @@ public interface PaperDao extends PagingAndSortingRepository<Paper, Long>, JpaSp
 
     Paper findById(long paperId);
 
+    @Query("select p from Paper p,Task2Case t2c where t2c.caseId=:caseId and t2c.taskId=p.id")
+    Page<Paper> findByCaseId(@Param("caseId") Long caseId,Pageable pageable);
+
 //    @Query("select p from Paper p where p.ownerId=:ownerId")
 //    Page<Paper> findByOwnerId(@Param("ownerId")long ownerId, String keyword, Pageable pageable);
 

+ 18 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ParticipantExamDao.java

@@ -0,0 +1,18 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.ParticipantExam;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * Created by shanshan on 2017/7/25.
+ */
+@Transactional
+public interface ParticipantExamDao extends PagingAndSortingRepository<ParticipantExam, Long>,JpaSpecificationExecutor<ParticipantExam> {
+    ParticipantExam findByIdAndParticipantId(Long examId, Long participantId);
+
+    List<ParticipantExam> findByParticipantId(Long participantId);
+}

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

@@ -0,0 +1,15 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.UserOperation;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * Created by HenryLee on 2017/10/18.
+ */
+@Transactional
+public interface UserOperationDao extends PagingAndSortingRepository<UserOperation, Long>, JpaSpecificationExecutor<UserOperation> {
+
+}

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/instancePermission/TaskPermissionDao.java

@@ -24,4 +24,7 @@ public interface TaskPermissionDao extends CrudRepository<TaskPermission, Long>
     List<TaskPermission> findByUserIdAndOperationAndInstanceIdIn(Long userId, String operation, List<Long> contestIds);
 
     List<TaskPermission> findByUserIdAndOperationAndInstanceId(Long userId, String operation, Long examId);
+
+    @Query("SELECT count(distinct tp.userId) FROM TaskPermission tp WHERE tp.instanceId = :instanceId and tp.operation=:operation")
+    Integer countByHasPermission(@Param("instanceId")Long instanceId, @Param("operation")String operation);
 }

+ 48 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/shiro/MySessionDao.java

@@ -0,0 +1,48 @@
+package cn.iselab.mooctest.site.dao.shiro;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.UnknownSessionException;
+import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
+import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author sean
+ * @date 2017-10-31.
+ */
+public class MySessionDao extends EnterpriseCacheSessionDAO{
+
+    private Map<Serializable, Session> map = new HashMap<>();
+
+    @Override
+    protected Serializable doCreate(Session session) {
+        Serializable sessionId = new JavaUuidSessionIdGenerator().generateId(session);
+        assignSessionId(session, sessionId);
+        map.put(sessionId,session);
+        return sessionId;
+    }
+
+    @Override
+    protected Session doReadSession(Serializable sessionId) {
+        return map.get(sessionId);
+    }
+
+    @Override
+    public void update(Session session) throws UnknownSessionException {
+        map.put(session.getId(), session);
+    }
+
+    @Override
+    public void delete(Session session) {
+        map.remove(session.getId());
+    }
+
+    @Override
+    public Collection<Session> getActiveSessions() {
+        return map.values();
+    }
+}

+ 104 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/AssignedTask2UserInfo.java

@@ -0,0 +1,104 @@
+package cn.iselab.mooctest.site.models;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.io.Serializable;
+
+/**
+ * @author sean
+ * @date 2017-10-22.
+ */
+@Entity
+@Table(name = "assigned_task_user_info")
+@ExcelTarget("assigned_task_user_info")
+public class AssignedTask2UserInfo implements Serializable {
+
+    //实际为participantId
+    @Id
+    @Column(name = "id")
+    private Long id;
+
+    @Column(name = "task_id")
+    private Long taskId;
+
+    @Column(name = "name")
+    @Excel(name = "姓名", orderNum = "1", mergeVertical = true, isImportField = "name")
+    private String name;
+
+    @Column(name = "score")
+    @Excel(name = "成绩", orderNum = "2", mergeVertical = true, isImportField = "score")
+    private Double score;
+
+    @Column(name = "school")
+    @Excel(name = "学校", orderNum = "3", mergeVertical = true, isImportField = "school")
+    private String school;
+
+    @Column(name = "email")
+    @Excel(name = "邮箱", orderNum = "4", mergeVertical = true, isImportField = "email")
+    private String email;
+
+    @Column(name = "mobile")
+    @Excel(name = "手机", orderNum = "5", mergeVertical = true, isImportField = "mobile")
+    private String mobile;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(Long taskId) {
+        this.taskId = taskId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public String getSchool() {
+        return school;
+    }
+
+    public void setSchool(String school) {
+        this.school = school;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+}

+ 57 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Comment.java

@@ -0,0 +1,57 @@
+package cn.iselab.mooctest.site.models;
+
+import javax.persistence.*;
+
+/**
+ * @author sean
+ * @date 2017-10-12.
+ */
+@Entity
+@Table(name = "comment")
+public class Comment {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name = "comment")
+    private String comment;
+
+    @Column(name = "difficulty")
+    private Integer difficulty;
+
+    @Column(name = "user_id")
+    private Long userId;
+
+    public Integer getDifficulty() {
+        return difficulty;
+    }
+
+    public void setDifficulty(Integer difficulty) {
+        this.difficulty = difficulty;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+}

+ 59 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Comment2Case.java

@@ -0,0 +1,59 @@
+package cn.iselab.mooctest.site.models;
+
+import javax.persistence.*;
+import java.sql.Timestamp;
+
+/**
+ * @author sean
+ * @date 2017-10-11.
+ */
+@Entity
+@Table(name = "comment_2_case")
+public class Comment2Case {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name = "case_id")
+    private Long caseId;
+
+    @Column(name = "comment_id")
+    private Long commentId;
+
+    @Column(name = "create_time")
+    private Timestamp createTime = new Timestamp(System.currentTimeMillis());
+
+    public Timestamp getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Timestamp createTime) {
+        this.createTime = createTime;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getCaseId() {
+        return caseId;
+    }
+
+    public void setCaseId(Long caseId) {
+        this.caseId = caseId;
+    }
+
+    public Long getCommentId() {
+        return commentId;
+    }
+
+    public void setCommentId(Long commentId) {
+        this.commentId = commentId;
+    }
+}
+

+ 58 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Comment2Target.java

@@ -0,0 +1,58 @@
+package cn.iselab.mooctest.site.models;
+
+import javax.persistence.*;
+import java.sql.Timestamp;
+
+/**
+ * @author sean
+ * @date 2017-10-11.
+ */
+@Entity
+@Table(name = "comment_2_target")
+public class Comment2Target {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name = "target_id")
+    private Long targetId;
+
+    @Column(name = "comment_id")
+    private Long commentId;
+
+    @Column(name = "create_time")
+    private Timestamp createTime = new Timestamp(System.currentTimeMillis());
+
+    public Timestamp getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Timestamp createTime) {
+        this.createTime = createTime;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getTargetId() {
+        return targetId;
+    }
+
+    public void setTargetId(Long targetId) {
+        this.targetId = targetId;
+    }
+
+    public Long getCommentId() {
+        return commentId;
+    }
+
+    public void setCommentId(Long commentId) {
+        this.commentId = commentId;
+    }
+}

+ 57 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ContestMentorExam.java

@@ -0,0 +1,57 @@
+package cn.iselab.mooctest.site.models;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.sql.Timestamp;
+
+/**
+ * Created by tangshanshan on 2017/12/3.
+ */
+@Entity
+@Data
+@Table(name = "exam_contest_mentor")
+public class ContestMentorExam {
+    @Id
+    private Long id;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "begin_time")
+    private Timestamp beginTime;
+
+    @Column(name = "end_time")
+    private Timestamp endTime;
+
+    @Column(name = "duration")
+    private Integer duration;
+
+    @Column(name = "manager_id")
+    private Long managerId;
+
+    @Column(name = "information")
+    private String information;
+
+    @Column(name = "subsite_id")
+    private Long subsiteId;
+
+    @Column(name = "owner_id")
+    private Long ownerId;
+
+    @Column(name = "type")
+    private Byte type;// exam: 0, exercise: 1, activity: 2
+
+    @Column(name = "status")
+    private Integer status;
+
+    @Column(name = "is_third_party")
+    private Integer owningParty ;
+
+    @Column(name = "contest_mentor_id")
+    private Long ContestMentorId;
+}
+

+ 4 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/DevTarget.java

@@ -13,10 +13,10 @@ public class DevTarget {
     private long id;
 
     @Column(name = "upload_case_id")
-    private long uploadedCaseId;
+    private Long uploadedCaseId;
 
     @Column(name = "end_time_millis")
-    private long endTimeMillis;
+    private Long endTimeMillis;
 
     public long getId() {
         return id;
@@ -26,7 +26,7 @@ public class DevTarget {
         this.id = id;
     }
 
-    public long getUploadedCaseId() {
+    public Long getUploadedCaseId() {
         return uploadedCaseId;
     }
 
@@ -34,7 +34,7 @@ public class DevTarget {
         this.uploadedCaseId = uploadedCaseId;
     }
 
-    public long getEndTimeMillis() {
+    public Long getEndTimeMillis() {
         return endTimeMillis;
     }
 

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Paper.java

@@ -33,4 +33,7 @@ public class Paper {
 
     @Column(name = "update_time", columnDefinition = "TIMESTAMP default CURRENT_TIMESTAMP")
     private Timestamp updateTime;
+
+    @Column(name = "is_public")
+    private Boolean isPublic;
 }

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ExamGroupUser.java → mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ParticipantExam.java

@@ -14,7 +14,7 @@ import java.sql.Timestamp;
 @Entity
 @Data
 @Table(name = "exam_group_user")
-public class ExamGroupUser{
+public class ParticipantExam {
     @Id
     private Long id;
 

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User.java

@@ -35,6 +35,9 @@ public class User {
     @Column(name = "create_time")
     private Timestamp createTime;
 
+    @Column( name = "photo_url")
+    private String photoUrl;
+
     public String getName() {
         return name;
     }
@@ -90,4 +93,12 @@ public class User {
     public String getSchool() {
         return this.school;
     }
+
+    public String getPhotoUrl() {
+        return photoUrl;
+    }
+
+    public void setPhotoUrl(String photoUrl) {
+        this.photoUrl = photoUrl;
+    }
 }

+ 27 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/UserOperation.java

@@ -0,0 +1,27 @@
+package cn.iselab.mooctest.site.models;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * Created by HenryLee on 2017/10/18.
+ */
+@Data
+@Entity
+@Table(name = "user_operation")
+public class UserOperation {
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name  = "ip")
+    private String ip;
+
+    @Column(name  = "user_id")
+    private Long userId;
+
+    @Column(name = "operation")
+    private String operation;
+
+}

+ 4 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/WebTarget.java

@@ -14,10 +14,10 @@ public class WebTarget {
     private long id;
 
     @Column(name = "super_id")
-    private long superId;
+    private Long superId;
 
     @Column(name = "end_time_millis")
-    private long endTimeMillis;
+    private Long endTimeMillis;
 
     public long getId() {
         return id;
@@ -27,7 +27,7 @@ public class WebTarget {
         this.id = id;
     }
 
-    public long getSuperId() {
+    public Long getSuperId() {
         return superId;
     }
 
@@ -35,7 +35,7 @@ public class WebTarget {
         this.superId = superId;
     }
 
-    public long getEndTimeMillis() {
+    public Long getEndTimeMillis() {
         return endTimeMillis;
     }
 

+ 11 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/Oauth2/impl/ExamServiceImpl2.java

@@ -13,6 +13,7 @@ import cn.iselab.mooctest.site.service.AssignedTaskService;
 import cn.iselab.mooctest.site.service.ExamStatusService;
 import cn.iselab.mooctest.site.service.PaperService;
 import cn.iselab.mooctest.site.service.TaskService;
+import cn.iselab.mooctest.site.service.instancePermission.PaperPermissionService;
 import cn.iselab.mooctest.site.web.data.fromDev.PluginResultVO;
 import cn.iselab.mooctest.site.web.data.fromKibug.ReportScriptResultVO;
 import cn.iselab.mooctest.site.web.data.fromKibug.ReportVO;
@@ -64,6 +65,8 @@ public class ExamServiceImpl2 implements ExamService {
     private UserDao userDao;
     @Autowired
     private OSSLogic ossLogic;
+    @Autowired
+    private PaperPermissionService paperPermissionService;
 
     @Override
     public TaskVO getCaseList(Long userId, Long taskId, Long subsiteId) throws Exception {
@@ -130,7 +133,12 @@ public class ExamServiceImpl2 implements ExamService {
         for(ScoreDetails scoreDetails: taskResultDTO.getScoreDetails()) {
             OpenId2UserId openId2UserId = openId2UserIdDao.findByOpenId(scoreDetails.getOpen_id());
             participantId = openId2UserId.getUserId();
-            task = examService.getExamByIdAndParticipantIdIfPermited(taskId, openId2UserId.getUserId());
+            try {
+                task = examService.getExamByIdAndParticipantIdIfPermited(taskId, openId2UserId.getUserId());
+            } catch (UnauthorizedException exception) {
+
+                continue;
+            }
             this.saveAssignedTask(participantId, scoreDetails, task, caseNameMap);
         }
         if(task != null && needCreatePaper) {
@@ -189,6 +197,8 @@ public class ExamServiceImpl2 implements ExamService {
             paper.setOwnerId(-1L);
         }
         paper = paperService.createOrUpdate(paper);
+        paperPermissionService.publishPaper(paper.getId());
+
         for(Long id: caseNameMap.keySet()) {
             Task2Case task2Case = new Task2Case();
             task2Case.setTaskId(paper.getId());

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/ServerRunner.java

@@ -7,12 +7,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.stereotype.Component;
 
 /**
  * @author liuzicong
  */
 @Component
+@ConditionalOnExpression("${featureSwitch.server.rpcServerRunner}==true")
 public class ServerRunner implements CommandLineRunner {
 
     private final Logger LOG = LoggerFactory.getLogger(getClass());

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceImpl.java

@@ -6,6 +6,7 @@ import cn.iselab.mooctest.site.rpc.dev.api.ApbcService;
 import cn.iselab.mooctest.site.rpc.dev.api.MutationService;
 import cn.iselab.mooctest.site.rpc.dev.data.*;
 import com.alibaba.dubbo.config.annotation.Reference;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
@@ -14,6 +15,7 @@ import java.util.List;
  * Created by cxworks on 17-6-22.
  */
 @Component
+@ConditionalOnExpression("${featureSwitch.server.rpcDevService}==true")
 public class DevServiceImpl implements DevService {
     @Reference(version = "1.0.0")
     AnalyzeService analyzeService;

+ 45 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/DevServiceMockImpl.java

@@ -0,0 +1,45 @@
+package cn.iselab.mooctest.site.rpc.dev.impl;
+
+import cn.iselab.mooctest.site.rpc.dev.DevService;
+import cn.iselab.mooctest.site.rpc.dev.data.*;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * Created by tangshanshan on 2017/11/16.
+ */
+@Component
+@ConditionalOnExpression("${featureSwitch.server.rpcDevService}==false")
+public class DevServiceMockImpl implements DevService {
+    @Override
+    public ApbcDTO apbcAnalyze(String examID, String workerID, String caseName, long startTime, long endTime, WeightDTO weightDTO) {
+        return null;
+    }
+
+    @Override
+    public boolean apbcAllAnalyze(long examID, long caseID, List<Long> workerID, long startTime, long endTime) {
+        return false;
+    }
+
+    @Override
+    public MutationDTO mutationAnalyze(String url, List<String> mutators) {
+        return null;
+    }
+
+    @Override
+    public boolean mutationAllAnalyze(long examID, long caseID, List<Long> workerID, long endTime) {
+        return false;
+    }
+
+    @Override
+    public CoverageDTO coverageAnalyze(String examID, String workerID, String caseName) {
+        return null;
+    }
+
+    @Override
+    public List<CoverageInfoDTO> getCoverageInfo(String examName) {
+        return null;
+    }
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/SourceServiceImpl.java

@@ -3,12 +3,14 @@ package cn.iselab.mooctest.site.rpc.dev.impl;
 import cn.iselab.mooctest.site.rpc.dev.SourceService;
 import cn.iselab.mooctest.site.rpc.dev.data.MutatorsDTO;
 import com.alibaba.dubbo.config.annotation.Reference;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.stereotype.Component;
 
 /**
  * Created by ROGK on 2017/7/3.
  */
 @Component
+@ConditionalOnExpression("${featureSwitch.server.rpcSourceService}==true")
 public class SourceServiceImpl implements SourceService{
 
     @Reference(version = "1.0.0")

+ 33 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/dev/impl/SourceServiceMockImpl.java

@@ -0,0 +1,33 @@
+package cn.iselab.mooctest.site.rpc.dev.impl;
+
+import cn.iselab.mooctest.site.rpc.dev.SourceService;
+import cn.iselab.mooctest.site.rpc.dev.data.MutatorsDTO;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by tangshanshan on 2017/11/16.
+ */
+@Component
+@ConditionalOnExpression("${featureSwitch.server.rpcSourceService}==false")
+public class SourceServiceMockImpl  implements SourceService {
+    @Override
+    public void deleteMutation(long taskId, long caseId) {
+
+    }
+
+    @Override
+    public void initMutators(long taskId, long caseId) {
+
+    }
+
+    @Override
+    public MutatorsDTO getMutators(long taskId, long caseId) {
+        return null;
+    }
+
+    @Override
+    public void setMutators(MutatorsDTO mutators) {
+
+    }
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/kibug/impl/KibugServiceImpl.java

@@ -4,6 +4,7 @@ import cn.iselab.mooctest.rpc.kibug.api.AutoTestService;
 import cn.iselab.mooctest.rpc.kibug.data.AutoTestResultDTO;
 import cn.iselab.mooctest.site.rpc.kibug.KibugService;
 import com.alibaba.dubbo.config.annotation.Reference;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
@@ -12,6 +13,7 @@ import java.util.List;
  * Created by cxworks on 17-6-22.
  */
 @Component
+@ConditionalOnExpression("${featureSwitch.server.rpcKibugService}==true")
 public class KibugServiceImpl implements KibugService {
 
     @Reference(version = "1.0.0")

+ 30 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/rpc/kibug/impl/KibugServiceMockImpl.java

@@ -0,0 +1,30 @@
+package cn.iselab.mooctest.site.rpc.kibug.impl;
+
+import cn.iselab.mooctest.rpc.kibug.data.AutoTestResultDTO;
+import cn.iselab.mooctest.site.rpc.kibug.KibugService;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * Created by tangshanshan on 2017/11/16.
+ */
+@Component
+@ConditionalOnExpression("${featureSwitch.server.rpcKibugService}==false")
+public class KibugServiceMockImpl implements KibugService {
+    @Override
+    public Long createAutoTest(Long managerId, String name, String iconLocation, String appLocation) {
+        return null;
+    }
+
+    @Override
+    public List<AutoTestResultDTO> getApplicationAutoResult(Long id) {
+        return null;
+    }
+
+    @Override
+    public AutoTestResultDTO getRecentAutoTestResult(Long id) {
+        return null;
+    }
+}

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/AssignedTask2UserInfoService.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.service;
+
+import cn.iselab.mooctest.site.models.AssignedTask2UserInfo;
+import cn.iselab.mooctest.site.models.User;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-10-26.
+ */
+public interface AssignedTask2UserInfoService {
+
+    List<AssignedTask2UserInfo> getAssignedTaskUserInfoByExamId(Long examId) throws Exception;
+
+    List<AssignedTask2UserInfo> getAssignedTaskUserInfoOfExamIdByContestMentor(Long examId, User user);
+}

+ 7 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/AssignedTaskService.java

@@ -2,6 +2,7 @@ package cn.iselab.mooctest.site.service;
 
 import cn.iselab.mooctest.site.data.AssignedCase;
 import cn.iselab.mooctest.site.models.AssignedTask;
+import cn.iselab.mooctest.site.models.ContestMentorAssignedTask;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
@@ -32,13 +33,17 @@ public interface AssignedTaskService {
 
     AssignedTask getAssignedTask(long taskId, long participantId);
 
-    Page<AssignedTask> getAssignedTaskPage(Long examId, Pageable pageable);
+    Page<AssignedTask> getAssignedTaskPage(Long examId,String keyword, Pageable pageable);
 
-    Page<AssignedTask> getContestMentorAssignedTaskPage(Long examId, Pageable pageable);
+    Page<AssignedTask> getContestMentorAssignedTaskPage(Long examId,String keyword, Pageable pageable);
 
     List<Double> getScoreList(Long examId);
 
     Boolean isSubmitted(Long examId, Long participantId, Long caseId, String subsiteCaseId);
 
     List<AssignedTask> getSubmittedRecordsByExamId(Long examId);
+
+    List<AssignedTask> getAssignedTasksByParticipantId(long participantId);
+
+    List<ContestMentorAssignedTask> getConestAssignedTasks(Long examId, Long mentorId);
 }

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

@@ -51,4 +51,6 @@ public interface CaseService {
     CaseExtends save(CaseExtends caseExtends);
 
     List<Long> getCasesByTaskId(Long taskId);
+
+    Page<Case> getCasesByTargetId(long targetId, String keyword, Pageable pageable);
 }

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CommentService.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.service;
+
+import cn.iselab.mooctest.site.models.Comment;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-10-12.
+ */
+public interface CommentService {
+
+    Comment commentOnCase(Comment comment, Long caseId);
+
+    Comment commentOnTarget(Comment comment, Long targetId);
+
+    List<Comment> getCommentsByCaseId(Long caseId);
+
+    List<Comment> getCommentsByTargetId(Long targetId);
+}

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/ContestMentorService.java

@@ -1,5 +1,7 @@
 package cn.iselab.mooctest.site.service;
 
+import cn.iselab.mooctest.site.models.ContestMentor;
+
 import java.util.List;
 
 /**
@@ -10,4 +12,6 @@ public interface ContestMentorService {
 
     void checkAndAddContestMentorPermission(List<Long> userIds);
 
+    List<Long> getExamIdByTeacherName(String teacherName);
+
 }

+ 6 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/DetailStatisticsService.java

@@ -3,6 +3,8 @@ package cn.iselab.mooctest.site.service;
 import cn.iselab.mooctest.site.models.CaseExtends;
 import cn.iselab.mooctest.site.models.Paper;
 import cn.iselab.mooctest.site.models.Task;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 
 import java.util.List;
 
@@ -16,4 +18,8 @@ public interface DetailStatisticsService {
     List<Paper> findPaperByCaseId(long caseId);
 
     List<Task> findTaskByCaseId(long caseId);
+
+    Page<Paper> findPaperByCaseId(long caseId, Pageable pageable);
+
+    List<Task> findTaskByPaperId(long paperId);
 }

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

@@ -16,6 +16,8 @@ public interface EmailService {
 
     boolean sendForgetPasswordEmail(User user);
 
+    boolean sendVerifyEmail(User user,String email);
+
     boolean sendManagerRegisterEmail(Manager manager);
 
     boolean sendManagerApplicationEmail(User user);

+ 11 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/ExamService.java

@@ -1,10 +1,12 @@
 package cn.iselab.mooctest.site.service;
 
-import cn.iselab.mooctest.site.data.CaseBlock;
-import cn.iselab.mooctest.site.models.ExamGroupUser;
+import cn.iselab.mooctest.site.models.AssistManagerExam;
+import cn.iselab.mooctest.site.models.ContestMentorExam;
+import cn.iselab.mooctest.site.models.ParticipantExam;
 import cn.iselab.mooctest.site.models.Task;
 import org.springframework.data.domain.Page;
 
+import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 
 import java.util.List;
@@ -16,7 +18,11 @@ public interface ExamService {
 
     Page<Task> getExams(Long organizerId, Byte type, Integer status, String keyword, Pageable pageable);
 
-    Page<ExamGroupUser> getExamsByParticipantId(Long participantId, Byte type, Integer status, String keyword, Pageable pageable);
+    Page<ParticipantExam> getExamsByParticipantId(Long participantId, Byte type, Integer status, String keyword, Pageable pageable);
+
+    Page<AssistManagerExam> getExamsByAssistManagerId(Long assistManagerId, Byte type, Integer status, String keyword, PageRequest pageable);
+
+    Page<ContestMentorExam> getExamsByContestMentorId(Long contestMentorId, Byte type, Integer status, String keyword, PageRequest pageable);
 
     Task getExamByIdAndParticipantIdIfPermited(Long examId, Long participantId);
 
@@ -33,4 +39,6 @@ public interface ExamService {
     List<Task> getAllTask();
 
     Task getExamByName(String name);
+
+    void deleteExam2Paper(Long examId, Long paperId);
 }

+ 15 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/RecordService.java

@@ -0,0 +1,15 @@
+package cn.iselab.mooctest.site.service;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Created by HenryLee on 2017/10/18.
+ */
+public interface RecordService {
+
+    void recordLoginAction(HttpServletRequest request,Long userId);
+
+    void recordLogoutAction(HttpServletRequest request,Long userId);
+
+    String getLoginIP(HttpServletRequest request);
+}

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TargetService.java

@@ -26,6 +26,8 @@ public interface TargetService {
 
     void updateTarget(App app);
 
+    void publicityTarget(Long targetId);
+
     App findById(long id);
 
     void verifyApp(App app);
@@ -33,4 +35,5 @@ public interface TargetService {
     void createTargetWeb(WebTarget webTarget);
 
     Page<App> getAllTargets(Pageable pageable);
+
 }

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

@@ -24,6 +24,4 @@ public interface Task2AssistantManagerService {
     List<Task2AssistantManager> getTask2AssistantManagerByManagerId(long managerId);
 
     void deleteAssistManager(List<Task2AssistantManager> deleteAssistantManagers);
-
-    Page<AssistManagerExam> getExamsByAssistManagerId(Long assistManagerId, Byte type, Integer status, String keyword, PageRequest pageable);
 }

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/WechatService.java

@@ -31,4 +31,8 @@ public interface WechatService {
     String getWorkersPassword(long taskId);
 
     String getWorkersGrade(long taskId);
+
+    String getContests(long userId);
+
+    int getContestParticipant(String taskName);
 }

+ 41 - 6
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/impl/WechatServiceImpl.java

@@ -1,13 +1,11 @@
 package cn.iselab.mooctest.site.service.application.impl;
 
-import cn.iselab.mooctest.site.common.constant.MailConstants;
 import cn.iselab.mooctest.site.dao.*;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.service.ExamService;
 import cn.iselab.mooctest.site.service.User2RoleService;
 import cn.iselab.mooctest.site.service.application.WechatService;
 import cn.iselab.mooctest.site.util.data.EncryptionUtil;
-import net.sf.json.JSON;
 import org.json.JSONArray;
 import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,7 +51,7 @@ public class WechatServiceImpl implements WechatService {
     private Task2GroupDao task2GroupDao;
 
     @Autowired
-    private ExamGroupUserDao examGroupUserDao;
+    private ParticipantExamDao participantExamDao;
 
     @Autowired
     private ExamService examService;
@@ -80,9 +78,9 @@ public class WechatServiceImpl implements WechatService {
         if (user == null){
             return null;
         }
-        List<ExamGroupUser> examGroupUsers=examGroupUserDao.findByParticipantId(user.getId());
-        for(ExamGroupUser examGroupUser:examGroupUsers){
-            Task task = examService.getExamByName(examGroupUser.getName());
+        List<ParticipantExam> participantExams = participantExamDao.findByParticipantId(user.getId());
+        for(ParticipantExam participantExam : participantExams){
+            Task task = examService.getExamByName(participantExam.getName());
             Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis());
             if (task.getEndTime().after(currentTimestamp)){
                 JSONObject taskObj = new JSONObject();
@@ -413,6 +411,43 @@ public class WechatServiceImpl implements WechatService {
         return resultObj.toString();
     }
 
+    public String getContests(long userId){
+        JSONObject resultObj=new JSONObject();
+        List<AssignedTask> tasks=assignedTaskDao.findByParticipantId(userId);
+        if (tasks == null || tasks.isEmpty()){
+            resultObj.put("message", "task not found");
+            return resultObj.toString();
+        }else {
+            JSONArray jsonArray=new JSONArray();
+            tasks.forEach(task-> {
+                JSONObject object=new JSONObject();
+                object.put("id",task.getTaskId());
+                object.put("name",task.getName());
+                jsonArray.put(object);
+            });
+            return jsonArray.toString();
+        }
+    }
+
+    public int getContestParticipant(String taskName){
+        if(taskName.indexOf("开发者")!=-1) {
+            return 4897;
+        }else if(taskName.indexOf("移动应用")!=-1){
+            if(taskName.indexOf("个人")!=-1)
+                return 2925;
+            else
+                return 1269;
+        }else if(taskName.indexOf("Web")!=-1){
+            if(taskName.indexOf("应用")!=-1)
+                return 1653;
+            else
+                return 3148;
+        }else if(taskName.indexOf("嵌入式")!=-1){
+            return 1838;
+        }else
+            return 0;
+    }
+
     private User checkUser(String account){
         User user=userDao.findByEmail(account);
         if(user==null){

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

@@ -87,7 +87,6 @@ public class MongoAPIServiceImpl implements MongoAPIService {
             mutationForMongoDTO.setId(id);
             mutationForMongoDTO.setEtag(etag);
             mutationDTOS.add(mutationForMongoDTO);
-            mutationForMongoDTO.getMutationDTO().setTotal(33);
         }
         return mutationDTOS;
     }

+ 2 - 40
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromDev/impl/PluginServiceImpl.java

@@ -92,18 +92,6 @@ public class PluginServiceImpl extends BaseService implements PluginService{
                                 weight.getApfd() * grade.getApfd()) / 100
                 );
 
-//                //向主站发送成绩
-//                RecordScoreVO sendScore = new RecordScoreVO();
-//                sendScore.setScore(
-//                        (coverageScore +
-//                                weight.getMutation() * grade.getMutation() +
-//                                weight.getApfd() * grade.getApfd()) / 100
-//                );
-//                sendScore.setCaseId(caseID + "");
-//                sendScore.setTaskId(taskID);
-//                sendScore.setWorkerId(workerID);
-//                sendScore.setResultUrl("grade.html#/case/" + taskID + "/" + workerID + "/" + caseID);
-//                String picked = apiService.checkCaseAssignment(workerID, Long.toString(caseID), taskID, "dev.mooctest.net");
                 try {
                     assignedTaskService.recordScore(taskID,caseID,workerID,grade.getScore());
                 }catch (Exception e){
@@ -166,15 +154,6 @@ public class PluginServiceImpl extends BaseService implements PluginService{
             grade.setMutation(0);
             gradeDao.save(grade);
 
-//            //向主站发送成绩
-//            RecordScoreVO sendScore = new RecordScoreVO();
-//            sendScore.setScore(savingScore);
-//            sendScore.setCaseId(caseID + "");
-//            sendScore.setTaskId(taskID);
-//            sendScore.setWorkerId(workerID);
-//            sendScore.setResultUrl("grade.html#/case/" + taskID + "/" + workerID + "/" + caseID);
-//            String picked = apiService.checkCaseAssignment(workerID, Long.toString(caseID), taskID, "dev.mooctest.net");
-//            return apiService.addScore(sendScore.getWorkerId(),new Long(sendScore.getCaseId()),sendScore.getScore(),sendScore.getResultUrl(),picked,"dev.mooctest.net");
             try {
                 assignedTaskService.recordScore(taskID,caseID,workerID,savingScore);
             }catch (Exception e){
@@ -196,16 +175,7 @@ public class PluginServiceImpl extends BaseService implements PluginService{
         if (gradeList != null && gradeList.size() != 0) {
             Grade grade = gradeList.get(0);
             grade.setScore(score);
-//            RecordScoreVO sendScore = new RecordScoreVO();
-//            sendScore.setScore(score);
-//            sendScore.setCaseId(caseId + "");
-//            sendScore.setTaskId(taskId);
-//            sendScore.setWorkerId(workerId);
-//            sendScore.setResultUrl("grade.html#/debug/" + taskId + "/" + workerId + "/" + caseId);
-//
-//            String picked = apiService.checkCaseAssignment(workerId, Long.toString(caseId), taskId, "dev.mooctest.net");
-//
-//            apiService.addScore(sendScore.getWorkerId(),new Long(sendScore.getCaseId()),sendScore.getScore(),sendScore.getResultUrl(),picked,"dev.mooctest.net");
+
             try {
                 assignedTaskService.recordScore(taskId,caseId,workerId,score);
             }catch (Exception e){
@@ -219,15 +189,7 @@ public class PluginServiceImpl extends BaseService implements PluginService{
             grade.setWorkerId(workerId);
             grade.setCaseId(caseId);
             grade.setScore(score);
-//            //向主站发送成绩
-//            RecordScoreVO sendScore = new RecordScoreVO();
-//            sendScore.setScore(score);
-//            sendScore.setCaseId(caseId + "");
-//            sendScore.setTaskId(taskId);
-//            sendScore.setWorkerId(workerId);
-//            sendScore.setResultUrl("grade.html#/debug/" + taskId + "/" + workerId + "/" + caseId);
-//            String picked = apiService.checkCaseAssignment(workerId, Long.toString(caseId), taskId, "dev.mooctest.net");
-//            apiService.addScore(sendScore.getWorkerId(),new Long(sendScore.getCaseId()),sendScore.getScore(),sendScore.getResultUrl(),picked,"dev.mooctest.net");
+
             try {
                 assignedTaskService.recordScore(taskId,caseId,workerId,score);
             }catch (Exception e){

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/ReportService.java

@@ -49,5 +49,5 @@ public interface ReportService {
 
     List<Report> getReportsByUserId(Long userId) throws Exception;
 
-    Report getReportByCaseTakeId(long caseTakeId) throws Exception;
+    Report getReportByCaseTakeId(long caseTakeId);
 }

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/fromKibug/impl/ReportServiceImpl.java

@@ -172,7 +172,7 @@ public class ReportServiceImpl extends BaseService implements ReportService {
     }
 
     @Override
-    public Report getReportByCaseTakeId(long caseTakeId) throws Exception{
+    public Report getReportByCaseTakeId(long caseTakeId){
         return reportDao.findByCaseTakeId(caseTakeId);
     }
 

+ 45 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/AssignedTask2UserInfoServiceImpl.java

@@ -0,0 +1,45 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.dao.AssignedTask2UserInfoDao;
+import cn.iselab.mooctest.site.dao.ContestMentorDao;
+import cn.iselab.mooctest.site.models.AssignedTask2UserInfo;
+import cn.iselab.mooctest.site.models.ContestMentor;
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.service.AssignedTask2UserInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author sean
+ * @date 2017-10-26.
+ */
+@Service
+public class AssignedTask2UserInfoServiceImpl implements AssignedTask2UserInfoService {
+
+    @Autowired
+    private AssignedTask2UserInfoDao assignedTask2UserInfoDao;
+
+    @Autowired
+    private ContestMentorDao contestMentorDao;
+
+    @Override
+    public List<AssignedTask2UserInfo> getAssignedTaskUserInfoByExamId(Long examId) throws Exception {
+        return new ArrayList<>(assignedTask2UserInfoDao.findByTaskId(examId));
+    }
+
+    @Override
+    public List<AssignedTask2UserInfo> getAssignedTaskUserInfoOfExamIdByContestMentor(Long examId, User user) {
+        List<ContestMentor> contestMentors = contestMentorDao.findByExamIdAndTeacherEmail(examId, user.getEmail());
+        List<Long> participantIds = contestMentors.stream().map(contestMentor -> contestMentor.getParticipantId()).collect(Collectors.toList());
+        List<AssignedTask2UserInfo> assignedTask2UserInfos = new ArrayList<>();
+        for (Long participantId : participantIds) {
+            AssignedTask2UserInfo assignedTask2UserInfo = assignedTask2UserInfoDao.findByTaskIdAndId(examId, participantId);
+            assignedTask2UserInfos.add(assignedTask2UserInfo);
+        }
+        return assignedTask2UserInfos;
+    }
+}

+ 14 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/AssignedTaskServiceImpl.java

@@ -232,14 +232,14 @@ public class AssignedTaskServiceImpl extends BaseService implements AssignedTask
     }
 
     @Override
-    public Page<AssignedTask> getAssignedTaskPage(Long examId, Pageable pageable) {
-        return assignedTaskDao.findByTaskId(examId, pageable);
+    public Page<AssignedTask> getAssignedTaskPage(Long examId, String keyword, Pageable pageable) {
+        return assignedTaskDao.findByTaskId(examId,keyword, pageable);
     }
 
     @Override
-    public Page<AssignedTask> getContestMentorAssignedTaskPage(Long examId, Pageable pageable) {
+    public Page<AssignedTask> getContestMentorAssignedTaskPage(Long examId, String keyword, Pageable pageable) {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
-        Page<ContestMentorAssignedTask> assignedTaskPage = contestMentorAssignedTaskDao.findByTaskIdAndMentorId(examId,user.getId(), pageable);
+        Page<ContestMentorAssignedTask> assignedTaskPage = contestMentorAssignedTaskDao.findByTaskIdAndMentorId(examId, keyword, user.getId(), pageable);
 
         return assignedTaskPage.map(new Converter<ContestMentorAssignedTask, AssignedTask>() {
             @Override
@@ -278,4 +278,14 @@ public class AssignedTaskServiceImpl extends BaseService implements AssignedTask
         }
         return submittedAssignedTask;
     }
+
+    @Override
+    public List<AssignedTask> getAssignedTasksByParticipantId(long participantId) {
+        return assignedTaskDao.findByParticipantId(participantId);
+    }
+
+    @Override
+    public List<ContestMentorAssignedTask> getConestAssignedTasks(Long examId, Long mentorId){
+        return contestMentorAssignedTaskDao.findByTaskIdAndMentorId(examId,mentorId);
+    }
 }

+ 24 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaseServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iselab.mooctest.site.service.impl;
 import cn.iselab.mooctest.site.dao.*;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.service.CaseService;
+import cn.iselab.mooctest.site.util.data.StringUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
@@ -173,8 +174,10 @@ public class CaseServiceImpl implements CaseService {
     public CaseExtends save(CaseExtends caseExtends) {
         caseExtends.setCaseId("-1");
         caseExtends.setDomain(0);
-        caseExtends.setDifficulty(1);
         caseExtends.setDeleted(false);
+        if(caseExtends.getDifficulty() == null) {
+            caseExtends.setDifficulty(1);
+        }
         return caseExtendsDao.save(caseExtends);
     }
 
@@ -216,4 +219,24 @@ public class CaseServiceImpl implements CaseService {
         List<Task2Case> task2Cases = task2CaseDao.findByTaskId(taskId);
         return task2Cases.stream().map(task2Case -> task2Case.getCaseId()).collect(Collectors.toList());
     }
+
+    @Override
+    public Page<Case> getCasesByTargetId(long targetId, String keyword, Pageable pageable){
+        Specification<Case> where=Specifications.where(getWhereTarget(targetId,keyword));
+        return caseDao.findAll(where,pageable);
+    }
+
+    private Specification<Case> getWhereTarget(long targetId, String keyword){
+        return new Specification<Case>() {
+            @Override
+            public Predicate toPredicate(Root<Case> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
+                Predicate predicate=criteriaBuilder.conjunction();
+                predicate.getExpressions().add(criteriaBuilder.equal(root.get("appId"), targetId));
+                predicate.getExpressions().add(criteriaBuilder.equal(root.get("visible"), true));
+                if(keyword!=null)
+                    predicate.getExpressions().add(criteriaBuilder.like(root.get("name"), "%"+ StringUtils.trim(keyword)+"%"));
+                return predicate;
+            }
+        };
+    }
 }

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

@@ -0,0 +1,67 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.dao.Comment2CaseDao;
+import cn.iselab.mooctest.site.dao.Comment2TargetDao;
+import cn.iselab.mooctest.site.dao.CommentDao;
+import cn.iselab.mooctest.site.models.Comment;
+import cn.iselab.mooctest.site.models.Comment2Case;
+import cn.iselab.mooctest.site.models.Comment2Target;
+import cn.iselab.mooctest.site.service.CommentService;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author sean
+ * @date 2017-10-12.
+ */
+@Service
+public class CommentServiceImpl implements CommentService {
+
+    @Autowired
+    private Comment2CaseDao comment2CaseDao;
+
+    @Autowired
+    private Comment2TargetDao comment2TargetDao;
+
+    @Autowired
+    private CommentDao commentDao;
+
+    @Override
+    public Comment commentOnCase(Comment comment, Long caseId) {
+        comment = commentDao.save(comment);
+
+        Comment2Case comment2Case = new Comment2Case();
+        comment2Case.setCaseId(caseId);
+        comment2Case.setCommentId(comment.getId());
+        comment2CaseDao.save(comment2Case);
+        return comment;
+    }
+
+    @Override
+    public Comment commentOnTarget(Comment comment, Long targetId) {
+        comment = commentDao.save(comment);
+        Comment2Target comment2Target = new Comment2Target();
+        comment2Target.setTargetId(targetId);
+        comment2Target.setCommentId(comment.getId());
+        comment2TargetDao.save(comment2Target);
+        return comment;
+    }
+
+    @Override
+    public List<Comment> getCommentsByCaseId(Long caseId) {
+        List<Comment2Case> comment2Cases = comment2CaseDao.findByCaseId(caseId);
+        List<Long> commentIds = comment2Cases.stream().map(Comment2Case::getCommentId).collect(Collectors.toList());
+        return Lists.newArrayList(commentDao.findAll());
+    }
+
+    @Override
+    public List<Comment> getCommentsByTargetId(Long targetId) {
+        List<Comment2Target> comment2Targets = comment2TargetDao.findByTargetId(targetId);
+        List<Long> commentIds = comment2Targets.stream().map(Comment2Target::getCommentId).collect(Collectors.toList());
+        return Lists.newArrayList(commentDao.findAll());
+    }
+}

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/ContestMentorServiceImpl.java

@@ -68,4 +68,8 @@ public class ContestMentorServiceImpl implements ContestMentorService {
         checkAndAddContestMentorPermission(teacherIds);
     }
 
+    @Override
+    public List<Long> getExamIdByTeacherName(String teacherName){
+        return contestMentorDao.findByMentor(teacherName);
+    }
 }

+ 19 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/DetailStatisticsServiceImpl.java

@@ -6,10 +6,12 @@ import cn.iselab.mooctest.site.service.PaperService;
 import cn.iselab.mooctest.site.service.DetailStatisticsService;
 import cn.iselab.mooctest.site.service.TaskService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
-
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Created by HenryLee on 2017/9/29.
@@ -20,6 +22,8 @@ public class DetailStatisticsServiceImpl implements DetailStatisticsService {
     @Autowired
     CaseExtendsDao caseExtendsDao;
     @Autowired
+    Exam2PaperDao exam2PaperDao;
+    @Autowired
     Exam2CaseDao exam2CaseDao;
     @Autowired
     Task2CaseDao task2CaseDao;
@@ -27,6 +31,8 @@ public class DetailStatisticsServiceImpl implements DetailStatisticsService {
     PaperService paperService;
     @Autowired
     TaskService taskService;
+    @Autowired
+    PaperDao paperDao;
 
     @Override
     public List<CaseExtends> findCaseByTargetId(long targetId) {
@@ -55,4 +61,16 @@ public class DetailStatisticsServiceImpl implements DetailStatisticsService {
         });
         return exams;
     }
+
+    @Override
+    public Page<Paper> findPaperByCaseId(long caseId, Pageable pageable) {
+        return paperDao.findByCaseId(caseId,pageable);
+    }
+
+    @Override
+    public List<Task> findTaskByPaperId(long paperId) {
+        List<Exam2Paper> exam2Papers = exam2PaperDao.findByPaperId(paperId);
+        List<Long> examIds = exam2Papers.stream().map(Exam2Paper::getExamId).collect(Collectors.toList());
+        return taskService.getTasks(examIds);
+    }
 }

+ 28 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/EmailServiceImpl.java

@@ -51,6 +51,7 @@ public class EmailServiceImpl extends BaseService implements EmailService {
     private static Template forgetPasswordTpl = ve.getTemplate("tpl/mail/forget_password.vm", "UTF-8");
     private static Template managerRegisterTpl = ve.getTemplate("tpl/mail/manager_register.vm", "UTF-8");
     private static Template arrearsTpl = ve.getTemplate("tpl/mail/arrear.vm","UTF-8");
+    private static Template verifyEmailTpl = ve.getTemplate("tpl/mail/verify_email.vm","UTF-8");
 
     @Override
     public boolean sendForgetPasswordEmail(Worker worker) {
@@ -133,6 +134,33 @@ public class EmailServiceImpl extends BaseService implements EmailService {
     }
 
     @Override
+    public boolean sendVerifyEmail(User user,String email) {
+        try {
+            String subject = "[Mooctest]验证邮箱";
+            String passStr = "user_" + user.getId() + "_" + email + "_" +
+                    String.valueOf(System.currentTimeMillis() +
+                            Constants.FORGET_PASSWORD_LINK_TIMEOUT_EMAIL);
+            String encryptStr = EncryptionUtil.encryptDES(passStr);
+            String base64Encrypt = new String(Base64.encodeBase64(encryptStr.getBytes("UTF-8")));
+            String url = host + "/verifyEmail/" + base64Encrypt;
+            MailSender sms = MailSenderFactory.getSystemSender(MailSenderType.SERVICE);
+
+            VelocityContext context = new VelocityContext();
+            context.put("resetUrl", url);
+            context.put("name", user.getName());
+
+            StringWriter stringWriter = new StringWriter();
+            verifyEmailTpl.merge(context, stringWriter);
+
+            sms.send(email, subject, stringWriter.toString());
+            return true;
+        } catch (Exception e) {
+            LOG.error("", e);
+            return false;
+        }
+    }
+
+    @Override
     public boolean sendManagerRegisterEmail(Manager manager) {
         try {
             String subject = "[Mooctest]身份审核通知";

+ 41 - 19
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/ExamServiceImpl.java

@@ -1,7 +1,6 @@
 package cn.iselab.mooctest.site.service.impl;
 
 import cn.iselab.mooctest.site.dao.*;
-import cn.iselab.mooctest.site.data.CaseBlock;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.service.BaseService;
 import cn.iselab.mooctest.site.service.ExamService;
@@ -10,7 +9,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.shiro.authz.UnauthorizedException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
-
+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;
@@ -33,13 +32,15 @@ public class ExamServiceImpl extends BaseService implements ExamService {
     @Autowired
     GroupDao groupDao;
     @Autowired
-    ExamGroupUserDao examGroupUserDao;
+    ParticipantExamDao participantExamDao;
     @Autowired
     Task2GroupDao task2GroupDao;
     @Autowired
     Exam2PaperDao exam2PaperDao;
     @Autowired
-    Exam2CaseDao exam2CaseDao;
+    AssistManagerExamDao assistManagerExamDao;
+    @Autowired
+    ContestMentorExamDao contestMentorExamDao;
 
     @Override
     public Page<Task> getExams(Long organizerId, Byte type, Integer status, String keyword, Pageable pageable) {
@@ -49,18 +50,33 @@ public class ExamServiceImpl extends BaseService implements ExamService {
     }
 
     @Override
-    public Page<ExamGroupUser> getExamsByParticipantId(Long participantId, Byte type, Integer status, String keyword, Pageable pageable) {
-        Specifications<ExamGroupUser> where =  Specifications.where(getExamUserWhereClause(participantId,status, type, keyword));
-        return examGroupUserDao.findAll(where, pageable);
+    public Page<ParticipantExam> getExamsByParticipantId(Long participantId, Byte type, Integer status, String keyword, Pageable pageable) {
+        Specifications<ParticipantExam> where =  Specifications.where(
+                getExamListQuery(ParticipantExam.class,"participantId",participantId,status, type, keyword));
+        return participantExamDao.findAll(where, pageable);
+    }
+
+    @Override
+    public Page<AssistManagerExam> getExamsByAssistManagerId(Long assistManagerId, Byte type, Integer status, String keyword, PageRequest pageable) {
+        Specifications<AssistManagerExam> where =  Specifications.where(
+                getExamListQuery(AssistManagerExam.class,"assistManagerId",assistManagerId,status, type, keyword));
+        return assistManagerExamDao.findAll(where, pageable);
+    }
+
+    @Override
+    public Page<ContestMentorExam> getExamsByContestMentorId(Long contestMentorId, Byte type, Integer status, String keyword, PageRequest pageable) {
+        Specifications<ContestMentorExam> where =  Specifications.where(
+                getExamListQuery(ContestMentorExam.class,"ContestMentorId",contestMentorId,status, type, keyword));
+        return contestMentorExamDao.findAll(where, pageable);
     }
 
     @Override
     public Task getExamByIdAndParticipantIdIfPermited(Long examId, Long participantId) {
-        ExamGroupUser examGroupUser = examGroupUserDao.findByIdAndParticipantId(examId, participantId);
-        if(examGroupUser == null){
+        ParticipantExam participantExam = participantExamDao.findByIdAndParticipantId(examId, participantId);
+        if(participantExam == null){
             throw new UnauthorizedException("unauthorized");
         }
-        return Converter.convert(Task.class, examGroupUser);
+        return Converter.convert(Task.class, participantExam);
     }
 
     @Override
@@ -96,16 +112,21 @@ public class ExamServiceImpl extends BaseService implements ExamService {
 
     @Override
     public void saveExam2Paper(Long examId, Long paperId) {
-        List<Exam2Paper> exam2Papers = exam2PaperDao.findByExamId(examId);
-        if(exam2Papers.size()>0){
-            exam2PaperDao.delete(exam2Papers);
-        }
+        deleteExam2Paper(examId, paperId);
         Exam2Paper exam2Paper = new Exam2Paper();
         exam2Paper.setPaperId(paperId);
         exam2Paper.setExamId(examId);
         exam2PaperDao.save(exam2Paper);
     }
 
+    @Override
+    public void deleteExam2Paper(Long examId, Long paperId) {
+        List<Exam2Paper> exam2Papers = exam2PaperDao.findByExamId(examId);
+        if(exam2Papers.size()>0){
+            exam2PaperDao.delete(exam2Papers);
+        }
+    }
+
     private Specification<Task> getTaskWhereClause(Long ownerId, Integer status, Byte type, String keyword) {
         return new Specification<Task>() {
             @Override
@@ -136,14 +157,15 @@ public class ExamServiceImpl extends BaseService implements ExamService {
             }
         };
     }
-    private Specification<ExamGroupUser> getExamUserWhereClause(Long participantId, Integer status, Byte type, String keyword) {
-        return new Specification<ExamGroupUser>() {
+    private <T> Specification<T> getExamListQuery(Class<T> model,String JoinedUserColumn,Long userId, Integer status, Byte type, String keyword) {
+        return new Specification<T>(){
+
             @Override
-            public Predicate toPredicate(Root<ExamGroupUser> a, CriteriaQuery<?> q, CriteriaBuilder cb) {
+            public Predicate toPredicate(Root a, CriteriaQuery q, CriteriaBuilder cb) {
                 Predicate predicate = cb.conjunction();
-                if(participantId!=null) {
+                if(userId!=null) {
                     predicate.getExpressions().add(
-                            cb.equal(a.<Long>get("participantId"), participantId)
+                            cb.equal(a.<Long>get(JoinedUserColumn), userId)
                     );
                 }
                 if(status!=null) {

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

@@ -267,6 +267,7 @@ public class GroupServiceImpl implements GroupService {
         //add Group2Worker
         Group2Worker group2Worker = new Group2Worker();
         group2Worker.setGroupId(group.getId());
+        group2Worker.setParticipantId(id);
         group2Worker.setWorkerId(id);
         group2Worker.setRecordCreateTime(new Timestamp(System.currentTimeMillis()));
         group2WorkerDao.save(group2Worker);

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

@@ -23,7 +23,6 @@ public class MenuServiceImpl implements MenuService {
     private RoleDao roleDao;
 
     @Override
-
     public List<Menu> getMenuListByRoleId(Long roleId) {
         return menuDao.findByRoleId(roleId);
     }

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

@@ -185,6 +185,8 @@ public class PaperServiceImpl extends BaseService implements PaperService {
                                 cb.notEqual(a.get("ownerId"), thirdUser.getId())
                         );
                     }
+                    Predicate predicate1 = cb.equal(a.<Long>get("isPublic"),1);
+                    predicate.getExpressions().add(cb.and(predicate1));
                 }
                 if(keyword!=null) {
                     predicate.getExpressions().add(

+ 90 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/RecordServiceImpl.java

@@ -0,0 +1,90 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.dao.UserOperationDao;
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.models.UserOperation;
+import cn.iselab.mooctest.site.service.RecordService;
+import org.apache.shiro.SecurityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.sql.Timestamp;
+
+/**
+ * Created by HenryLee on 2017/10/18.
+ */
+@Service
+public class RecordServiceImpl implements RecordService{
+
+    private static final Logger log = LoggerFactory.getLogger(Process.class.getName());
+
+    @Autowired
+    UserOperationDao userOperationDao;
+
+    @Override
+    public void recordLoginAction(HttpServletRequest request, Long userId) {
+        UserOperation userOperation = this.buildUserOperation(request,userId);
+        if(userOperation==null)
+            return;
+        userOperation.setOperation("Login");
+        userOperationDao.save(userOperation);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] Login at [%s]",userId,current.toString()));
+    }
+
+    @Override
+    public void recordLogoutAction(HttpServletRequest request, Long userId) {
+        UserOperation userOperation = this.buildUserOperation(request,userId);
+        if(userOperation==null)
+            return;
+        userOperation.setOperation("Logout");
+        userOperationDao.save(userOperation);
+        Timestamp current = new Timestamp(System.currentTimeMillis());
+        log.info(String.format("User[%d] Logout at [%s]",userId,current.toString()));
+    }
+
+    private UserOperation buildUserOperation(HttpServletRequest request, Long userId) {
+        String ip = this.getLoginIP(request);
+        if("101.37.78.167".equals(ip)) {
+            return null;
+        }
+        UserOperation userOperation = new UserOperation();
+        userOperation.setIp(ip);
+        userOperation.setUserId(userId);
+        return userOperation;
+    }
+
+    @Override
+    public String getLoginIP(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("http_client_ip");
+        }
+        if (isNotValidIP(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip.equals("0:0:0:0:0:0:0:1")) {
+            ip = "127.0.0.1";
+        }
+        if (ip.split(",").length > 1) {
+            ip = ip.split(",")[0];
+        }
+        return ip;
+    }
+
+    private boolean isNotValidIP(String ip) {
+        return ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip);
+    }
+}

+ 13 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TargetServiceImpl.java

@@ -1,9 +1,6 @@
 package cn.iselab.mooctest.site.service.impl;
 
-import cn.iselab.mooctest.site.dao.AppDao;
-import cn.iselab.mooctest.site.dao.TargetDao;
-import cn.iselab.mooctest.site.dao.TargetDevDao;
-import cn.iselab.mooctest.site.dao.TargetWebDao;
+import cn.iselab.mooctest.site.dao.*;
 import cn.iselab.mooctest.site.dao.fromKibug.ApplicationDao;
 import cn.iselab.mooctest.site.dao.fromKibug.IncrementIdDao;
 import cn.iselab.mooctest.site.models.App;
@@ -25,6 +22,7 @@ import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import java.util.List;
 
 /**
  * Created by ROGK on 2017/6/26.
@@ -52,7 +50,7 @@ public class TargetServiceImpl extends BaseService implements TargetService {
 
     @Override
     public Page<App> getTargets(long ownerId, String keyword, Pageable pageable) {
-        Specifications<App> where = Specifications.where(getWhereClause(ownerId, keyword)).or(getPublic(keyword));
+        Specifications<App> where = Specifications.where(getPublic(keyword));
         return targetDao.findAll(where, pageable);
     }
 
@@ -93,6 +91,13 @@ public class TargetServiceImpl extends BaseService implements TargetService {
         targetDao.save(app);
     }
 
+    @Override
+    public void publicityTarget(Long targetId) {
+        App app = this.findById(targetId);
+        app.setVisible(true);
+        targetDao.save(app);
+    }
+
     private Specification<App> getWhereClause(Long ownerId, String keyword) {
         return new Specification<App>() {
             @Override
@@ -108,6 +113,9 @@ public class TargetServiceImpl extends BaseService implements TargetService {
                             cb.like(a.<String>get("name"), "%" + StringUtils.trim(keyword) + "%")
                     );
                 }
+                predicate.getExpressions().add(
+                        cb.equal(a.get("visible"), false)
+                );
                 return predicate;
             }
         };

+ 0 - 49
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/Task2AssistantManagerServiceImpl.java

@@ -1,24 +1,12 @@
 package cn.iselab.mooctest.site.service.impl;
 
-import cn.iselab.mooctest.site.dao.AssistManagerExamDao;
 import cn.iselab.mooctest.site.dao.Task2AssistantManagerDao;
-import cn.iselab.mooctest.site.models.AssistManagerExam;
-import cn.iselab.mooctest.site.models.ExamGroupUser;
 import cn.iselab.mooctest.site.models.Task2AssistantManager;
 import cn.iselab.mooctest.site.service.BaseService;
 import cn.iselab.mooctest.site.service.Task2AssistantManagerService;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-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.List;
 
 /**
@@ -30,8 +18,6 @@ public class Task2AssistantManagerServiceImpl extends BaseService implements Tas
 
     @Autowired
     private Task2AssistantManagerDao task2AssistantManagerDao;
-    @Autowired
-    AssistManagerExamDao assistManagerExamDao;
 
     @Override
     public List<Task2AssistantManager> getTask2AssistantManagerByTaskId(long taskId) {
@@ -63,39 +49,4 @@ public class Task2AssistantManagerServiceImpl extends BaseService implements Tas
         task2AssistantManagerDao.delete(deleteAssistantManagers);
     }
 
-    @Override
-    public Page<AssistManagerExam> getExamsByAssistManagerId(Long assistManagerId, Byte type, Integer status, String keyword, PageRequest pageable) {
-        Specifications<AssistManagerExam> where =  Specifications.where(getAssistManagerClause(assistManagerId,status, type, keyword));
-        return assistManagerExamDao.findAll(where, pageable);
-    }
-
-    private Specification<AssistManagerExam> getAssistManagerClause(Long assistManagerId, Integer status, Byte type, String keyword) {
-        return new Specification<AssistManagerExam>() {
-            @Override
-            public Predicate toPredicate(Root<AssistManagerExam> a, CriteriaQuery<?> q, CriteriaBuilder cb) {
-                Predicate predicate = cb.conjunction();
-                if(assistManagerId!=null) {
-                    predicate.getExpressions().add(
-                            cb.equal(a.<Long>get("assistManagerId"), assistManagerId)
-                    );
-                }
-                if(status!=null) {
-                    predicate.getExpressions().add(
-                            cb.equal(a.<Integer>get("status"), status)
-                    );
-                }
-                if(type!=null) {
-                    predicate.getExpressions().add(
-                            cb.equal(a.<Byte>get("type"), type)
-                    );
-                }
-                if(keyword!=null) {
-                    predicate.getExpressions().add(
-                            cb.like(a.<String>get("name"), "%" + StringUtils.trim(keyword) + "%")
-                    );
-                }
-                return predicate;
-            }
-        };
-    }
 }

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/instancePermission/AppPermissionService.java

@@ -13,6 +13,10 @@ public interface AppPermissionService {
     //for manager
     AppPermission uploadApp(Long userId, Long appId);
 
+    AppPermission uploadPublicApp(Long appId);
+
+    void setApp(Long appId);
+
     List<AppPermission> getAppPermissionsByUserId(Long userId);
     
     List<AppPermission> getByUserIdAndInstanceId(Long id, Long instanceId);

+ 20 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/instancePermission/impl/AppPermissionServiceImpl.java

@@ -27,12 +27,31 @@ public class AppPermissionServiceImpl implements AppPermissionService {
         appPermission.setUserId(userId);
         appPermission.setInstanceId(appId);
         appPermission.setCreateTime(new Timestamp(System.currentTimeMillis()));
-        appPermission.setOperation("add,view");
+        appPermission.setOperation("*");
         ShiroAuthorizationHelper shiroAuthorizationHelper = new ShiroAuthorizationHelper();
+        appPermissionDao.save(appPermission);
         return appPermission;
     }
 
     @Override
+    public AppPermission uploadPublicApp(Long appId) {
+        AppPermission appPermission = new AppPermission();
+        appPermission.setUserId(0L);
+        appPermission.setInstanceId(appId);
+        appPermission.setCreateTime(new Timestamp(System.currentTimeMillis()));
+        appPermission.setOperation("view");
+        appPermissionDao.save(appPermission);
+        return appPermission;
+    }
+
+    @Override
+    public void setApp(Long appId){
+        AppPermission appPermission=appPermissionDao.findOne(appId);
+        appPermission.setOperation("view");
+        appPermission.setUserId(0L);
+        appPermissionDao.save(appPermission);
+    }
+    @Override
     public List<AppPermission> getAppPermissionsByUserId(Long userId) {
         return appPermissionDao.findByUserId(userId);
     }

+ 5 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/data/JSONUtil.java

@@ -1,7 +1,9 @@
 package cn.iselab.mooctest.site.util.data;
 
 import com.google.gson.JsonParser;
+import net.sf.json.JSON;
 import org.json.JSONArray;
+import org.json.JSONObject;
 import org.json.JSONTokener;
 
 /**
@@ -10,8 +12,10 @@ import org.json.JSONTokener;
 public class JSONUtil {
 
     public static boolean isJson(String json){
+        if(json==null || json=="")
+            return false;
         try{
-            new JsonParser().parse(json);
+            new JSONObject(json);
             return true;
         }catch (Exception e){
             return false;

+ 6 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/http/RequestUtils.java

@@ -4,6 +4,12 @@ import cn.iselab.mooctest.site.web.constants.AttrConsts;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 

+ 24 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CaseController.java

@@ -108,6 +108,20 @@ public class CaseController extends BaseController {
         caseLogic.update(caseExtendsVO,caseId);
     }
 
+    @RequiresPermissions("case:update")
+    @RequestMapping(value = UrlConstants.API + "case/publicity/{caseId}", method = RequestMethod.PUT)
+    public void publicityCase(@PathVariable("caseId") Long caseId){
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String permissionStr = user.getId().toString() + ":case:update:" + caseId.toString();
+        if (!SecurityUtils.getSubject().isPermitted(new CasePermission(permissionStr))) {
+            throw new UnauthorizedException("unauthorized");
+        }
+//        if(caseId!=caseExtendsVO.getId()){
+//            throw new IllegalArgumentException("Id are not same");
+//        }
+        caseLogic.publicityCase(caseId);
+    }
+
     @RequestMapping(value = UrlConstants.API + "case/{caseId}", method = RequestMethod.DELETE)
     public CaseExtendsVO deleteCase(@PathVariable("caseId") long caseId){
         return caseLogic.delete(caseId);
@@ -163,4 +177,14 @@ public class CaseController extends BaseController {
         return caseLogic.getCaseDownloadSignature(examId, userId, caseName);
     }
 
+    @RequiresRoles(value = "manager")
+    @RequestMapping(value = UrlConstants.API+"cases/{targetId}",method = RequestMethod.POST)
+    public Page<CaseVO> getCasesForTarget(@PathVariable @NotNull long targetId,
+                                          @RequestParam(value = "keyword",required = false)String keyword,HttpServletRequest request) throws Exception{
+        Integer activePage = Integer.parseInt(request.getHeader("activePage"));
+        Integer rowsOnPage = Integer.parseInt(request.getHeader("rowsOnPage"));
+        Pageable pageable=new PageRequest(activePage-1,rowsOnPage);
+        return caseLogic.getCasesForTarget(targetId,keyword,pageable);
+    }
+
 }

+ 76 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CommentController.java

@@ -0,0 +1,76 @@
+package cn.iselab.mooctest.site.web.ctrl;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.models.instancePermission.CasePermission;
+import cn.iselab.mooctest.site.web.data.CommentVO;
+import cn.iselab.mooctest.site.web.data.TargetVO;
+import cn.iselab.mooctest.site.web.logic.CommentLogic;
+import cn.iselab.mooctest.site.web.logic.TargetLogic;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-10-11.
+ */
+@RestController
+public class CommentController {
+
+    @Autowired
+    private CommentLogic commentLogic;
+
+    @Autowired
+    private TargetLogic targetLogic;
+
+    @RequiresRoles("manager")
+    @RequestMapping(value = UrlConstants.API + "case/comment/{caseId}", method = RequestMethod.PUT)
+    public CommentVO commentOnCase(@PathVariable("caseId") Long caseId, @RequestBody CommentVO commentVO) {
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String casePermissionStr = user.getId() + ":case:view:" + caseId.toString();
+        if (!SecurityUtils.getSubject().isPermitted(new CasePermission(casePermissionStr))) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        commentVO.setUserId(user.getId());
+        commentVO.setCaseId(caseId);
+        return commentLogic.commentOnCaseOrTarget(commentVO);
+    }
+
+    @RequiresRoles("manager")
+    @RequestMapping(value = UrlConstants.API + "target/comment/{targetId}", method = RequestMethod.PUT)
+    public CommentVO commentOnTarget(@PathVariable("targetId") Long targetId, @RequestBody CommentVO commentVO) {
+        TargetVO targetVO = targetLogic.getTargetById(targetId);
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        if (targetVO.isVisible().equals(Boolean.FALSE) && targetVO.getOwnerId() != user.getId()) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        commentVO.setTargetId(targetId);
+        commentVO.setUserId(user.getId());
+        return commentLogic.commentOnCaseOrTarget(commentVO);
+    }
+
+    @RequestMapping(value = UrlConstants.API + "case/comment/{caseId}", method = RequestMethod.GET)
+    public List<CommentVO> commentListOnCases(@PathVariable("caseId") Long caseId) {
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String casePermissionStr = user.getId() + ":case:view:" + caseId.toString();
+        if (!SecurityUtils.getSubject().isPermitted(new CasePermission(casePermissionStr))) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        return commentLogic.getCommentsByCaseId(caseId);
+    }
+
+    @RequestMapping(value = UrlConstants.API + "target/comment/{targetId}", method = RequestMethod.GET)
+    public List<CommentVO> commentListOnTargets(@PathVariable("targetId") Long targetId) {
+        TargetVO targetVO = targetLogic.getTargetById(targetId);
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        if (targetVO.isVisible().equals(Boolean.FALSE) && targetVO.getOwnerId() != user.getId()) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        return commentLogic.getCommentsByTargetId(targetId);
+    }
+}

+ 4 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ContestController.java

@@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
@@ -66,7 +67,9 @@ public class ContestController {
         Integer activePage = Integer.parseInt(activePageStr);
         Integer rowsOnPage = Integer.parseInt(rowsOnPageStr);
 
-        Pageable pageable = new PageRequest(activePage - 1, rowsOnPage);
+        String sortBy = "beginTime";
+        Sort sortByBeginTime = new Sort(Sort.Direction.ASC,sortBy);
+        Pageable pageable = new PageRequest(activePage - 1, rowsOnPage,sortByBeginTime);
         return contestLogic.getContestList(user.getId(), pageable);
     }
 

+ 41 - 19
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ExamController.java

@@ -19,6 +19,7 @@ import org.springframework.data.domain.Sort;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -52,32 +53,24 @@ public class ExamController extends BaseController {
         Sort sortByStatus = new Sort(Sort.Direction.ASC, "status");
         Sort sortById = new Sort(Sort.Direction.DESC, "id");
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+
         if (queryBy.equals("organizer")) {
             return examLogic.getExamList(user.getId(), type, status, keyword, new PageRequest(activePage - 1, rowsOnPage, sortById));
-        } else if(queryBy.equals("participant")) {
+        } else if (queryBy.equals("participant")) {
             return examLogic.getParticipantExamList(user.getId(), type, status, keyword, new PageRequest(activePage - 1, rowsOnPage, sortByStatus));
-        } else{
+        } else if(queryBy.equals("assistManager")){
             return examLogic.getAssistManagerExamList(user.getId(), type, status, keyword, new PageRequest(activePage - 1, rowsOnPage, sortByStatus));
+        } else{
+            return examLogic.getContestMentorExamList(user.getId(), type, status, keyword, new PageRequest(activePage - 1, rowsOnPage, sortByStatus));
         }
     }
 
-    @RequiresPermissions("tasks:view")
-    @RequestMapping(value = "/api/test/exams", method = RequestMethod.GET)
-    public List<ExamVO> getExams() {
-        if (!SecurityUtils.getSubject().isPermitted("tasks:view")) {
-            throw new UnauthorizedException("unauthorized");
-        }
-        String username = (String) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
-        return examLogic.getExamList(username);
-    }
-
     @RequiresPermissions("task:view")
     @RequestMapping(value = "api/exam/{examId}", method = RequestMethod.GET)
     public ExamVO getExamById(@PathVariable Long examId) {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
         String permissionStr = user.getId().toString() + ":task:view:" + examId.toString();
         boolean isOwner = SecurityUtils.getSubject().isPermitted(new TaskPermission(permissionStr));
-
         if (isOwner) {
             return examLogic.getExamById(examId);
         } else {
@@ -105,6 +98,17 @@ public class ExamController extends BaseController {
     }
 
     @RequiresPermissions("task:update")
+    @RequestMapping(value = "api/exam2paper/{examId}/{paperId}", method = RequestMethod.DELETE)
+    public Boolean deleteExam2Paper(@PathVariable Long examId, @PathVariable Long paperId) {
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String examPermissionStr = user.getId().toString() + ":task:update:" + examId.toString();
+        if (!SecurityUtils.getSubject().isPermitted(new TaskPermission(examPermissionStr))) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        return examLogic.deleteExam2Paper(examId, paperId);
+    }
+
+    @RequiresPermissions("task:update")
     @RequestMapping(value = "api/exam/{examId}", method = RequestMethod.PUT)
     public ExamVO update(@PathVariable Long examId, @RequestBody ExamVO examVO) {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
@@ -123,6 +127,7 @@ public class ExamController extends BaseController {
     public Page<AssignedTaskVO> getAssignedTaskByExamId(@RequestParam(name = "examId", required = false) Long examId,
                                                         @RequestParam(name = "sortOrder", required = false, defaultValue = "desc") String sortOrder,
                                                         @RequestParam(name = "sortBy", required = false, defaultValue = "score") String sortBy,
+                                                        @RequestParam(name = "keyword", required = false, defaultValue = "") String keyword,
                                                         HttpServletRequest request) throws Exception {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
         String examPermissionStr = user.getId().toString() + ":task:view:" + examId.toString();
@@ -134,7 +139,7 @@ public class ExamController extends BaseController {
 
         boolean hasScorePermission = SecurityUtils.getSubject().isPermitted(new TaskPermission(user.getId().toString() + ":task:score:" + examId.toString()));
         boolean needFilter = !hasScorePermission;
-        return examLogic.getAssignedTasks(examId, needFilter, pageable);
+        return examLogic.getAssignedTasks(examId,keyword, needFilter, pageable);
     }
 
     @RequestMapping(value = UrlConstants.API + "exam/user", method = RequestMethod.GET)
@@ -157,25 +162,26 @@ public class ExamController extends BaseController {
         return examLogic.getUsers(examId,needFilter,email,keyword,pageable);
     }
 
-    private Pageable getPageInfo(String sortOrder, String sortBy,HttpServletRequest request){
+    private Pageable getPageInfo(String sortOrder, String sortBy,HttpServletRequest request) {
         String activePage = request.getHeader("activePage");
         String rowsOnPage = request.getHeader("rowsOnPage");
         if (activePage == null || rowsOnPage == null) {
             throw new IllegalArgumentException("缺少分页信息");
         }
         Sort sort;
-        if(sortOrder.equals("desc"))
-            sort = new Sort(Sort.Direction.DESC,sortBy);
+        if (sortOrder.equals("desc"))
+            sort = new Sort(Sort.Direction.DESC, sortBy);
         else
-            sort = new Sort(Sort.Direction.ASC,sortBy);
+            sort = new Sort(Sort.Direction.ASC, sortBy);
 
         return new PageRequest(Integer.parseInt(activePage) - 1, Integer.parseInt(rowsOnPage), sort);
     }
 
+
     @RequestMapping(value = UrlConstants.API + "score", method = RequestMethod.GET)
     public ScoreVO getScoreByExamIdAndWorkerId(@RequestParam(name = "examId") Long examId) throws Exception {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
-        examLogic.getExamByIdAndParticipantIdIfPermited(examId,user.getId());
+        examLogic.getExamByIdAndParticipantIdIfPermited(examId, user.getId());
         return examLogic.getScoreBy(examId, user.getId());
     }
 
@@ -208,4 +214,20 @@ public class ExamController extends BaseController {
         return examLogic.updateStatutsForAllTask();
     }
 
+    @RequestMapping(value = UrlConstants.API + "scoreExcel/{examId}", method = RequestMethod.GET)
+    public void getExamScoresOfExcel(@PathVariable("examId") Long examId,
+                                     HttpServletResponse response) throws Exception {
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+
+        String permissionStrForOwner = user.getId().toString() + ":task:*:" + examId.toString();
+        String permissionStrForContestMentor = user.getId().toString() + ":task:view:" + examId.toString();
+
+        if (SecurityUtils.getSubject().isPermitted(new TaskPermission(permissionStrForOwner))) {
+            examLogic.exportExcelByOwner(response, examId);
+        } else if (SecurityUtils.getSubject().isPermitted(new TaskPermission(permissionStrForContestMentor))) {
+            examLogic.exportExcelByContestMentor(response, examId, user);
+        } else {
+            throw new UnauthorizedException("unthorized");
+        }
+    }
 }

+ 26 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/OSSController.java

@@ -1,17 +1,29 @@
 package cn.iselab.mooctest.site.web.ctrl;
 
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.web.SuccessResult;
 import cn.iselab.mooctest.site.rpc.oauth2.constant.OSSPath;
+import cn.iselab.mooctest.site.util.http.RequestUtils;
+import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import cn.iselab.mooctest.site.web.logic.OSSLogic;
 import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
+import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.omg.CORBA.PUBLIC_MEMBER;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
 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 org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
 import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Map;
 
 /**
  * @author sean
@@ -56,4 +68,18 @@ public class OSSController extends BaseController {
 
     @RequestMapping(value = UrlConstants.API_COMMON + "oss/certificate", method = RequestMethod.GET)
     public boolean verificationCertificate(@RequestParam(name="userId") String userId) {return ossLogic.verificationCertificate(userId);}
+
+    @RequestMapping(value = UrlConstants.API_COMMON + "oss/key/headimage", method = RequestMethod.GET)
+    public String getHeadImageKey(@RequestParam(name = "userId") String userId) {return ossLogic.getHeadImageKey(userId);}
+
+    @RequestMapping(value = UrlConstants.API_COMMON + "oss/verification/headimage", method = RequestMethod.GET)
+    public String verificationHeadImage(@RequestParam(name = "userId") String userId) {return ossLogic.verificationHeadImageKey(userId);}
+
+    @RequestMapping(value = UrlConstants.API_COMMON + "upload/file",consumes = MediaType.MULTIPART_FORM_DATA_VALUE, method = RequestMethod.POST)
+    public Map<String,Object> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("path") String path, HttpServletRequest request) throws IOException{
+        String result=ossLogic.saveFile(file,path);
+        SuccessResult successResult = new SuccessResult();
+        successResult.put("path", request.getHeader("Font-Address")+result);
+        return successResult;
+    }
 }

+ 22 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PaperController.java

@@ -5,10 +5,12 @@ import cn.iselab.mooctest.site.common.web.ErrorResult;
 import cn.iselab.mooctest.site.common.web.StatusCode;
 import cn.iselab.mooctest.site.common.web.SuccessResult;
 import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.models.instancePermission.CasePermission;
 import cn.iselab.mooctest.site.models.instancePermission.PaperPermission;
 import cn.iselab.mooctest.site.models.instancePermission.TaskPermission;
 import cn.iselab.mooctest.site.web.data.PaperVO;
 import cn.iselab.mooctest.site.web.data.TargetKibugVO;
+import cn.iselab.mooctest.site.web.logic.DetailStatisticsLogic;
 import cn.iselab.mooctest.site.web.logic.PaperLogic;
 import org.apache.log4j.spi.ErrorCode;
 import org.apache.shiro.SecurityUtils;
@@ -36,6 +38,8 @@ import java.util.Map;
 public class PaperController {
     @Autowired
     PaperLogic paperLogic;
+    @Autowired
+    DetailStatisticsLogic detailStatisticsLogic;
 
     @RequiresPermissions("paper:view")
     @RequestMapping(value= "api/paper/{paperId}", method = RequestMethod.GET)
@@ -88,6 +92,7 @@ public class PaperController {
                                       @RequestParam(name = "isPublic", required = false) boolean isPublic,
                                       @RequestParam(name = "sortOrder", required = false) String sortOrder,
                                       @RequestParam(name = "sortBy", required = false) String sortBy,
+                                      @RequestParam(name = "caseId", required = false) Long caseId,
                                       HttpServletRequest request) {
         Sort sort;
         if(sortOrder.equals("desc"))
@@ -100,7 +105,12 @@ public class PaperController {
             throw new IllegalArgumentException("缺少分页信息");
         }
         Pageable pageable = new PageRequest(Integer.parseInt(activePage) - 1, Integer.parseInt(rowsOnPage),sort);
-        return paperLogic.getPaperList(isPublic, keyword, pageable);
+        if(caseId == null) {
+            return paperLogic.getPaperList(isPublic, keyword, pageable);
+        }else {
+            return detailStatisticsLogic.findPapersByCaseId(caseId,pageable);
+        }
+
     }
 
     @RequiresPermissions("paper:update")
@@ -118,4 +128,15 @@ public class PaperController {
         }
     }
 
+    @RequiresPermissions("paper:update")
+    @RequestMapping(value = UrlConstants.API + "paper/publicity/{paperId}", method = RequestMethod.PUT)
+    public PaperVO publicityPaper(@PathVariable("paperId") Long paperId) throws Exception {
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String permissionStr = user.getId().toString() + ":paper:update:" + paperId.toString();
+        if (!SecurityUtils.getSubject().isPermitted(new PaperPermission(permissionStr))) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        return paperLogic.publicityPaper(paperId);
+    }
+
 }

+ 15 - 6
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TargetController.java

@@ -3,10 +3,7 @@ package cn.iselab.mooctest.site.web.ctrl;
 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.web.data.TargetDevVO;
-import cn.iselab.mooctest.site.web.data.TargetKibugVO;
-import cn.iselab.mooctest.site.web.data.TargetVO;
-import cn.iselab.mooctest.site.web.data.TargetWebVO;
+import cn.iselab.mooctest.site.web.data.*;
 import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
 import cn.iselab.mooctest.site.web.logic.TargetLogic;
 import org.apache.shiro.authz.annotation.RequiresRoles;
@@ -35,10 +32,11 @@ public class TargetController extends BaseController {
     public Page<TargetVO> getTargets(@PathVariable @NotNull long ownerId, @RequestParam(name = "keyword", required = false) String keyword, HttpServletRequest request) {
         Integer activePage = Integer.parseInt(request.getHeader("activePage"));
         Integer rowsOnPage = Integer.parseInt(request.getHeader("rowsOnPage"));
+        Sort sortByCreate=new Sort(Sort.Direction.DESC,"createTime");
         if (activePage == null || rowsOnPage == null) {
             return null;
         }
-        Pageable pageable = new PageRequest(activePage - 1, rowsOnPage);
+        Pageable pageable = new PageRequest(activePage - 1, rowsOnPage, sortByCreate);
         return targetLogic.getTargets(ownerId, keyword, pageable);
     }
 
@@ -47,10 +45,11 @@ public class TargetController extends BaseController {
     public Page<TargetVO> getMyTargets(HttpServletRequest request, @RequestParam(name = "ownerId") long ownerId, @RequestParam(name = "keyword", required = false) String keyword) throws Exception {
         Integer activePage = Integer.parseInt(request.getHeader("activePage"));
         Integer rowsOnPage = Integer.parseInt(request.getHeader("rowsOnPage"));
+        Sort sortByCreate=new Sort(Sort.Direction.DESC,"createTime");
         if (activePage == null || rowsOnPage == null) {
             return null;
         }
-        Pageable pageable = new PageRequest(activePage - 1, rowsOnPage);
+        Pageable pageable = new PageRequest(activePage - 1, rowsOnPage, sortByCreate);
         return targetLogic.getMyTargets(ownerId, keyword, pageable);
     }
 
@@ -87,6 +86,16 @@ public class TargetController extends BaseController {
         return successResult;
     }
 
+    @RequiresRoles(value = "manager")
+    @RequestMapping(value = "api/target", method = RequestMethod.PUT)
+    public Map<String,Object> updateTarget(@RequestParam(value = "targetId")Long targetId,
+                                           @RequestParam(value = "name",required = false)String name,
+                                           @RequestParam(value = "visible",required = false)Boolean visible,
+                                           @RequestBody TargetVO vo) throws Exception{
+        targetLogic.updateTarget(targetId,name,visible);
+        return SuccessResult.ok(ResponseMessage.Error_Code,200);
+    }
+
     @RequiresRoles("admin")
     @RequestMapping(value = UrlConstants.API + "app/{id}", method = RequestMethod.PUT)
     public void verifyApp(@PathVariable("id") long id, @RequestBody TargetVO targetVO) {

+ 41 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TestController.java

@@ -1,11 +1,15 @@
 package cn.iselab.mooctest.site.web.ctrl;
 
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
 import cn.iselab.mooctest.site.common.enums.SessionKey;
+import cn.iselab.mooctest.site.configure.ClientFeatureConfiguration;
 import cn.iselab.mooctest.site.configure.realm.DefaultUsernamepasswordToken;
+import cn.iselab.mooctest.site.dao.shiro.MySessionDao;
 import cn.iselab.mooctest.site.models.ManagerProperty;
 import cn.iselab.mooctest.site.models.User;
 import cn.iselab.mooctest.site.service.ManagerPropertyService;
 import cn.iselab.mooctest.site.service.OpenId2UserIdService;
+import cn.iselab.mooctest.site.service.RecordService;
 import cn.iselab.mooctest.site.util.data.EncryptionUtil;
 import cn.iselab.mooctest.site.web.data.UserVO;
 import cn.iselab.mooctest.site.web.data.wrapper.UserVOWrapper;
@@ -14,9 +18,11 @@ import cn.iselab.mooctest.site.web.exception.HttpUnauthorizedException;
 import cn.iselab.mooctest.site.web.logic.MenuLogic;
 import cn.iselab.mooctest.site.web.logic.PermissionLogic;
 import cn.iselab.mooctest.site.web.logic.UserLogic;
+import com.alibaba.dubbo.common.json.JSON;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.RequiresUser;
 import org.apache.shiro.subject.Subject;
+import org.json.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,7 +33,16 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.URL;
 
 /**
  * Created by Liu on 2017/6/5.
@@ -36,6 +51,9 @@ import javax.servlet.http.HttpSession;
 public class TestController {
 
     @Autowired
+    private MySessionDao mySessionDao;
+
+    @Autowired
     private UserLogic userLogic;
 
     @Autowired
@@ -53,6 +71,12 @@ public class TestController {
     @Autowired
     private ManagerPropertyService managerPropertyService;
 
+    @Autowired
+    ClientFeatureConfiguration clientFeatures;
+
+    @Autowired
+    private RecordService recordService;
+
     private Logger LOG = LoggerFactory.getLogger(getClass());
 
     @RequestMapping(value = "/api/test/getSession", method = RequestMethod.GET)
@@ -62,7 +86,7 @@ public class TestController {
     }
 
     @RequestMapping(value = "/api/test/login", method = RequestMethod.POST)
-    public UserVO login(@RequestBody UserVO userVO, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
+    public UserVO login(@RequestBody UserVO userVO, BindingResult bindingResult, RedirectAttributes redirectAttributes,HttpServletRequest request) {
         if (bindingResult.hasErrors()) {
             throw new HttpUnauthorizedException("unauthorized");
 
@@ -110,12 +134,13 @@ public class TestController {
             } else if (userVO.getMobile() != null) {
                 userVO = userLogic.findUserByMobile(userVO.getMobile());
             }
+            recordService.recordLoginAction(request,userVO.getId());
             User user = userVOWrapper.unwrap(userVO);
             userVO.setMenuVOs(menuLogic.getMenuListByUserId(user.getId()));
             currentUser.getSession().setAttribute("User", user);
             userVO.setOpenId(openId2UserIdService.findOpenIdByUserId(userVO.getId()));
 
-            if (managerPropertyService.getManagerPropertyByUserId(user.getId()) != null){
+            if (managerPropertyService.getManagerPropertyByUserId(user.getId()) != null) {
                 ManagerProperty managerProperty = managerPropertyService.getManagerPropertyByUserId(user.getId());
                 userVO.setExpireTime(Long.valueOf(managerProperty.getExpireTime().getTime()));
             }
@@ -127,7 +152,9 @@ public class TestController {
     }
 
     @RequestMapping(value = "/api/test/logout", method = RequestMethod.GET)
-    public void logout(RedirectAttributes redirectAttributes) {
+    public void logout(RedirectAttributes redirectAttributes,HttpServletRequest request) {
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        recordService.recordLogoutAction(request,user.getId());
         //使用权限管理工具进行用户的退出,跳出登录,给出提示信息
         SecurityUtils.getSubject().logout();
         redirectAttributes.addFlashAttribute("message", "您已安全退出");
@@ -164,4 +191,15 @@ public class TestController {
         return true;
     }
 
+
+    @RequestMapping(value = "/api/featureSwitch", method = RequestMethod.GET)
+    public ClientFeatureConfiguration getClientFeatures() {
+        return clientFeatures;
+    }
+
+
+    @RequestMapping(value = UrlConstants.API_COMMON + "onlineMembers", method = RequestMethod.GET)
+    public Integer getNumbersOfOnlineUsers() {
+        return mySessionDao.getActiveSessions().size();
+    }
 }

+ 57 - 24
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/UserController.java

@@ -3,9 +3,12 @@ package cn.iselab.mooctest.site.web.ctrl;
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
 import cn.iselab.mooctest.site.configure.realm.DefaultUsernamepasswordToken;
 import cn.iselab.mooctest.site.dao.MobileVerificationDao;
+import cn.iselab.mooctest.site.models.ManagerProperty;
 import cn.iselab.mooctest.site.models.MobileVerification;
 import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.service.ManagerPropertyService;
 import cn.iselab.mooctest.site.service.OpenId2UserIdService;
+import cn.iselab.mooctest.site.service.RecordService;
 import cn.iselab.mooctest.site.service.UserService;
 import cn.iselab.mooctest.site.web.data.ManagerPropertyVO;
 import cn.iselab.mooctest.site.web.data.UserVO;
@@ -56,6 +59,12 @@ public class UserController {
     @Autowired
     private OpenId2UserIdService openId2UserIdService;
 
+    @Autowired
+    private ManagerPropertyService managerPropertyService;
+
+    @Autowired
+    private RecordService recordService;
+
     private Logger LOG = LoggerFactory.getLogger(getClass());
 
     @RequiresPermissions("personInfo:update")
@@ -82,6 +91,23 @@ public class UserController {
         return userLogic.updateMobile(userVO);
     }
 
+    @RequiresPermissions("personInfo:update")
+    @RequestMapping(value = UrlConstants.API + "user/email", method = RequestMethod.PUT)
+    public UserVO verifyEmail(@RequestBody UserVO userVO, HttpServletRequest request) {
+        return userLogic.sendVerifyEmail(userVO,request);
+    }
+
+    @RequestMapping(value = UrlConstants.API_COMMON + "user/email/{code}", method = RequestMethod.POST)
+    public UserVO updateEmail(@PathVariable("code")String code) {
+        return userLogic.verifyEmail(code);
+    }
+
+    @RequiresPermissions("personInfo:update")
+    @RequestMapping(value = UrlConstants.API + "user/appendfile", method = RequestMethod.PUT)
+    public UserVO updateAppendFile(@RequestBody UserVO userVO) {
+        return userLogic.updateAppendFile(userVO);
+    }
+
 
     @RequiresPermissions("password:update")
     @RequestMapping(value = UrlConstants.API + "user/password", method = RequestMethod.PUT)
@@ -90,7 +116,7 @@ public class UserController {
     }
 
     @RequestMapping(value = "/api/mobileLogin", method = RequestMethod.POST)
-    public UserVO loginByMobile(@RequestBody UserVO userVO, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
+    public UserVO loginByMobile(@RequestBody UserVO userVO, BindingResult bindingResult, RedirectAttributes redirectAttributes,HttpServletRequest request) {
         if (bindingResult.hasErrors()) {
             throw new HttpUnauthorizedException("unauthorized");
 
@@ -105,38 +131,45 @@ public class UserController {
         //获取当前的Subject
         Subject currentUser = SecurityUtils.getSubject();
         LOG.info("session过期时间 +" + SecurityUtils.getSubject().getSession().getTimeout());
-        try {
-            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
-            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
-            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
-            currentUser.login(token);
-        } catch (UnknownAccountException uae) {
-            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
-            redirectAttributes.addFlashAttribute("message", "未知账户");
-        } catch (IncorrectCredentialsException ice) {
-            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
-            redirectAttributes.addFlashAttribute("message", "密码不正确");
-        } catch (LockedAccountException lae) {
-            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
-            redirectAttributes.addFlashAttribute("message", "账户已锁定");
-        } catch (ExcessiveAttemptsException eae) {
-            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
-            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");
-        } catch (AuthenticationException ae) {
-            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
-            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
-            ae.printStackTrace();
-            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
-        }
+        currentUser.login(token);
+//        try {
+//            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
+//            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应
+//            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
+//            currentUser.login(token);
+//        } catch (UnknownAccountException uae) {
+//            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
+//            redirectAttributes.addFlashAttribute("message", "未知账户");
+//        } catch (IncorrectCredentialsException ice) {
+//            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
+//            redirectAttributes.addFlashAttribute("message", "密码不正确");
+//        } catch (LockedAccountException lae) {
+//            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
+//            redirectAttributes.addFlashAttribute("message", "账户已锁定");
+//        } catch (ExcessiveAttemptsException eae) {
+//            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
+//            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");
+//        } catch (AuthenticationException ae) {
+//            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
+//            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
+//            ae.printStackTrace();
+//            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
+//        }
         //验证是否登录成功
         if (currentUser.isAuthenticated()) {
             System.out.println("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
+            recordService.recordLoginAction(request,userVO.getId());
             User user = userService.findByMobile(userVO.getMobile());
             userVO = userVOWrapper.wrap(user);
             userVO.setPassword("");
             userVO.setMenuVOs(menuLogic.getMenuListByUserId(user.getId()));
             userVO.setOpenId(openId2UserIdService.findOpenIdByUserId(userVO.getId()));
             currentUser.getSession().setAttribute("User", user);
+
+            if (managerPropertyService.getManagerPropertyByUserId(user.getId()) != null){
+                ManagerProperty managerProperty = managerPropertyService.getManagerPropertyByUserId(user.getId());
+                userVO.setExpireTime(Long.valueOf(managerProperty.getExpireTime().getTime()));
+            }
             return userVO;
         } else {
             token.clear();

+ 8 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/WechatController.java

@@ -94,6 +94,14 @@ public class WechatController extends BaseController {
     public String getContestResult(HttpServletRequest request) {
         return wechatLogic.getContest(request);
     }
+
+    @RequestMapping(value = UrlConstants.API_WECHAT + "contests",method = RequestMethod.GET)
+    public String getContestList(HttpServletRequest request) { return wechatLogic.getContests(request); }
+
+    @RequestMapping(value = UrlConstants.API_WECHAT + "contests/worker",method = RequestMethod.GET)
+    public String getWorkersContest(HttpServletRequest request) {
+        return wechatLogic.getWorkerContests(request);
+    }
     /**
      *
      * POST methods
@@ -103,5 +111,4 @@ public class WechatController extends BaseController {
     public String joinGroup(HttpServletRequest request, @RequestBody JoinGroupWechatVO body) {
         return wechatLogic.joinGroup(request, body);
     }
-
 }

+ 0 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/AnalysisController.java

@@ -156,7 +156,6 @@ public class AnalysisController extends BaseController {
                                                     @RequestParam(name = "stuId", required = false) Long stuId,
                                                     @RequestParam(name = "caseId") long caseId) throws IOException {
 
-
         List<MutationForMongoDTO> mutationForMongoDTOS = mongoAPIService.getMutationFromMongo(stuId, examId, caseId);
 
         return mutationForMongoDTOS;

+ 6 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/PluginController.java

@@ -15,6 +15,7 @@ import cn.iselab.mooctest.site.web.data.fromKibug.ReportVO;
 import cn.iselab.mooctest.site.web.logic.ExamLogic;
 import cn.iselab.mooctest.site.web.logic.ReportLogic;
 import cn.iselab.mooctest.site.web.logic.fromDev.PluginLogic;
+import cn.iselab.mooctest.site.web.logic.fromDev.UpDownloadLogic;
 import org.apache.shiro.authz.UnauthorizedException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -35,13 +36,15 @@ public class PluginController extends BaseController{
     ReportLogic reportLogic;
     @Autowired
     private ExamLogic examLogic;
+    @Autowired
+    UpDownloadLogic upDownloadLogic;
 
     @RequestMapping(value = UrlConstants.API_DEV + "plugin/downloadSig", method = RequestMethod.GET)
     public String getDownloadSignature(HttpServletRequest request) {
         String taskID = request.getParameter("taskID"),
                 workerID = request.getParameter("workerID"),
                 caseID = request.getParameter("caseID");
-        String signature = pluginLogic.getDownloadSignature(taskID, workerID, Long.parseLong(caseID));
+        String signature = upDownloadLogic.getDownloadSignature(taskID, workerID, Long.parseLong(caseID));
         if (signature == null) {
             return StResponse.failure("签名未能生成");
         } else {
@@ -54,7 +57,7 @@ public class PluginController extends BaseController{
         String taskID = request.getParameter("taskID"),
                 workerID = request.getParameter("workerID"),
                 caseName = request.getParameter("caseName");
-        String signature = pluginLogic.getSubmitSignature(taskID, workerID, caseName);
+        String signature = upDownloadLogic.getSubmitSignature(taskID, workerID, caseName);
         if (signature == null) {
             return StResponse.failure("签名未能生成");
         } else {
@@ -67,7 +70,7 @@ public class PluginController extends BaseController{
         String taskID = request.getParameter("taskID"),
                 workerID = request.getParameter("workerID"),
                 caseName = request.getParameter("caseName");
-        String signature = pluginLogic.getSubmitAnswersSignature(taskID, workerID, caseName);
+        String signature = upDownloadLogic.getSubmitAnswersSignature(taskID, workerID, caseName);
         if (signature == null) {
             return StResponse.failure("签名未能生成");
         } else {

+ 1 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromKibug/BugController.java

@@ -18,6 +18,7 @@ import cn.iselab.mooctest.site.web.ctrl.BaseController;
 import cn.iselab.mooctest.site.web.data.fromKibug.BugVO;
 import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
 import cn.iselab.mooctest.site.web.logic.BugLogic;
+import cn.iselab.mooctest.site.web.logic.ReportLogic;
 import cn.iselab.mooctest.site.web.util.Converter;
 import net.sf.ehcache.transaction.xa.EhcacheXAException;
 import org.apache.shiro.SecurityUtils;
@@ -42,11 +43,6 @@ public class BugController extends BaseController{
 
     @RequestMapping(value= UrlConstants.API_KIBUG+"bug", method = RequestMethod.GET)
     public Map<String, Object> search(@RequestParam(name = "reportId", required = true) Long reportId) throws Exception {
-        User user=(User) SecurityUtils.getSubject().getSession().getAttribute("User");
-        String permissionStr=user.getId().toString()+ ":report:view:" +reportId.toString();
-        if(!SecurityUtils.getSubject().isPermitted(new ReportPermission(permissionStr))){
-            throw new UnauthorizedException("unauthorized");
-        }
 
         List<BugVO> bugVoList = bugLogic.getBugListByReportId(reportId);
 

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

@@ -201,4 +201,14 @@ public class ReportController extends BaseController{
         successResult.put(ResponseMessage.List_RESULT, voList);
         return successResult;
     }
+
+    /**
+     * 批量下载报告里的脚本
+     */
+    @RequiresRoles("admin")
+    @RequestMapping(value = UrlConstants.API_KIBUG+"script",method = RequestMethod.GET)
+    public Map<String, Object> downloadScripts(@RequestParam(value = "examId")long examId,
+                                               @RequestParam(value = "caseId")long caseId) throws Exception{
+        return reportLogic.downloadScripts(examId,caseId);
+    }
 }

Неке датотеке нису приказане због велике количине промена