wucl 2 년 전
커밋
0186585f32
81개의 변경된 파일3882개의 추가작업 그리고 0개의 파일을 삭제
  1. 38 0
      .gitignore
  2. 0 0
      .idea/.gitignore
  3. 7 0
      .idea/encodings.xml
  4. 14 0
      .idea/misc.xml
  5. 124 0
      .idea/uiDesigner.xml
  6. 6 0
      .idea/vcs.xml
  7. 208 0
      .idea/workspace.xml
  8. 304 0
      pom.xml
  9. 54 0
      src/main/java/com/dayou/BaseApplication.java
  10. 41 0
      src/main/java/com/dayou/configuration/BaseEntity.java
  11. 38 0
      src/main/java/com/dayou/configuration/BusinessException.java
  12. 29 0
      src/main/java/com/dayou/configuration/CacheConfig.java
  13. 113 0
      src/main/java/com/dayou/configuration/DefaultPageIntecptor.java
  14. 100 0
      src/main/java/com/dayou/configuration/ErrorCode.java
  15. 103 0
      src/main/java/com/dayou/configuration/GlobalExceptionHandler.java
  16. 31 0
      src/main/java/com/dayou/configuration/JwtConstants.java
  17. 27 0
      src/main/java/com/dayou/configuration/MybatisPlusConfig.java
  18. 88 0
      src/main/java/com/dayou/configuration/RestResponse.java
  19. 102 0
      src/main/java/com/dayou/configuration/SpringContextHolder.java
  20. 47 0
      src/main/java/com/dayou/configuration/WebConfig.java
  21. 16 0
      src/main/java/com/dayou/configuration/annotation/IgnoreAuth.java
  22. 41 0
      src/main/java/com/dayou/controller/CycleController.java
  23. 82 0
      src/main/java/com/dayou/controller/DocumentController.java
  24. 48 0
      src/main/java/com/dayou/controller/ProfessorResultController.java
  25. 43 0
      src/main/java/com/dayou/controller/QuestionAnalysisController.java
  26. 58 0
      src/main/java/com/dayou/controller/QuestionController.java
  27. 40 0
      src/main/java/com/dayou/controller/UserController.java
  28. 19 0
      src/main/java/com/dayou/dao/CycleMapper.java
  29. 22 0
      src/main/java/com/dayou/dao/DocumentMapper.java
  30. 14 0
      src/main/java/com/dayou/dao/DocumentQuestionMapper.java
  31. 27 0
      src/main/java/com/dayou/dao/ProfessorResultMapper.java
  32. 21 0
      src/main/java/com/dayou/dao/QuestionAnalysisMapper.java
  33. 14 0
      src/main/java/com/dayou/dao/QuestionMapper.java
  34. 14 0
      src/main/java/com/dayou/dao/UserMapper.java
  35. 25 0
      src/main/java/com/dayou/dto/CommitDTO.java
  36. 25 0
      src/main/java/com/dayou/dto/DocumentDTO.java
  37. 18 0
      src/main/java/com/dayou/dto/LoginDTO.java
  38. 22 0
      src/main/java/com/dayou/dto/UserDTO.java
  39. 23 0
      src/main/java/com/dayou/entity/Cycle.java
  40. 23 0
      src/main/java/com/dayou/entity/Document.java
  41. 21 0
      src/main/java/com/dayou/entity/DocumentQuestion.java
  42. 23 0
      src/main/java/com/dayou/entity/ProfessorResult.java
  43. 22 0
      src/main/java/com/dayou/entity/Question.java
  44. 23 0
      src/main/java/com/dayou/entity/QuestionAnalysis.java
  45. 22 0
      src/main/java/com/dayou/entity/User.java
  46. 112 0
      src/main/java/com/dayou/interceptor/LoginInterceptor.java
  47. 20 0
      src/main/java/com/dayou/service/ICycleService.java
  48. 14 0
      src/main/java/com/dayou/service/IDocumentQuestionService.java
  49. 24 0
      src/main/java/com/dayou/service/IDocumentService.java
  50. 28 0
      src/main/java/com/dayou/service/IProfessorResultService.java
  51. 20 0
      src/main/java/com/dayou/service/IQuestionAnalysisService.java
  52. 14 0
      src/main/java/com/dayou/service/IQuestionService.java
  53. 18 0
      src/main/java/com/dayou/service/IUserService.java
  54. 49 0
      src/main/java/com/dayou/service/impl/CycleServiceImpl.java
  55. 18 0
      src/main/java/com/dayou/service/impl/DocumentQuestionServiceImpl.java
  56. 64 0
      src/main/java/com/dayou/service/impl/DocumentServiceImpl.java
  57. 108 0
      src/main/java/com/dayou/service/impl/ProfessorResultServiceImpl.java
  58. 35 0
      src/main/java/com/dayou/service/impl/QuestionAnalysisServiceImpl.java
  59. 18 0
      src/main/java/com/dayou/service/impl/QuestionServiceImpl.java
  60. 67 0
      src/main/java/com/dayou/service/impl/UserServiceImpl.java
  61. 29 0
      src/main/java/com/dayou/service/websocket/WebSocketConfig.java
  62. 100 0
      src/main/java/com/dayou/service/websocket/WebSocketServer.java
  63. 168 0
      src/main/java/com/dayou/utils/ConvertUtil.java
  64. 12 0
      src/main/java/com/dayou/utils/Convertor.java
  65. 196 0
      src/main/java/com/dayou/utils/JwtTokenUtil.java
  66. 29 0
      src/main/java/com/dayou/utils/LoginContext.java
  67. 32 0
      src/main/java/com/dayou/vo/AnalysisResultVO.java
  68. 30 0
      src/main/java/com/dayou/vo/CycleVO.java
  69. 39 0
      src/main/java/com/dayou/vo/DocumentCycleVO.java
  70. 31 0
      src/main/java/com/dayou/vo/DocumentVO.java
  71. 22 0
      src/main/java/com/dayou/vo/LabelKeyVO.java
  72. 42 0
      src/main/java/com/dayou/vo/ProfessorResultVO.java
  73. 27 0
      src/main/java/com/dayou/vo/QuestionVO.java
  74. 26 0
      src/main/resources/application-local.yml
  75. 21 0
      src/main/resources/application-prod.yml
  76. 21 0
      src/main/resources/application-test.yml
  77. 79 0
      src/main/resources/application.yml
  78. 42 0
      src/main/resources/mapper/AnalysisResultMapper.xml
  79. 29 0
      src/main/resources/mapper/CycleMapper.xml
  80. 54 0
      src/main/resources/mapper/DocumentMapper.xml
  81. 64 0
      src/main/resources/mapper/ProfessorResultMapper.xml

+ 38 - 0
.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 0 - 0
.idea/.gitignore


+ 7 - 0
.idea/encodings.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="PROJECT" charset="UTF-8" />
+  </component>
+</project>

+ 14 - 0
.idea/misc.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 124 - 0
.idea/uiDesigner.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 208 - 0
.idea/workspace.xml

@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AutoImportSettings">
+    <option name="autoReloadType" value="SELECTIVE" />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="298c0123-5a38-45f2-a872-7d3a74d33353" name="Changes" comment="">
+      <change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/BaseApplication.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/BaseEntity.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/BusinessException.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/CacheConfig.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/DefaultPageIntecptor.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/ErrorCode.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/GlobalExceptionHandler.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/JwtConstants.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/MybatisPlusConfig.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/RestResponse.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/SpringContextHolder.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/WebConfig.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/configuration/annotation/IgnoreAuth.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/controller/CycleController.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/controller/DocumentController.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/controller/ProfessorResultController.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/controller/QuestionAnalysisController.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/controller/QuestionController.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/controller/UserController.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/CycleMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/DocumentMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/DocumentQuestionMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/ProfessorResultMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/QuestionAnalysisMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/QuestionMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dao/UserMapper.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dto/CommitDTO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dto/DocumentDTO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dto/LoginDTO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/dto/UserDTO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/Cycle.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/Document.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/DocumentQuestion.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/ProfessorResult.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/Question.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/QuestionAnalysis.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/entity/User.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/interceptor/LoginInterceptor.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/ICycleService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/IDocumentQuestionService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/IDocumentService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/IProfessorResultService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/IQuestionAnalysisService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/IQuestionService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/IUserService.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/CycleServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/DocumentQuestionServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/DocumentServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/ProfessorResultServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/QuestionAnalysisServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/QuestionServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/impl/UserServiceImpl.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/websocket/WebSocketConfig.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/service/websocket/WebSocketServer.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/utils/ConvertUtil.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/utils/Convertor.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/utils/JwtTokenUtil.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/utils/LoginContext.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/AnalysisResultVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/CycleVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/DocumentCycleVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/DocumentVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/LabelKeyVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/ProfessorResultVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/java/com/dayou/vo/QuestionVO.java" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/application-local.yml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/application-prod.yml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/application-test.yml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/application.yml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/mapper/AnalysisResultMapper.xml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/mapper/CycleMapper.xml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/mapper/DocumentMapper.xml" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/src/main/resources/mapper/ProfessorResultMapper.xml" afterDir="false" />
+    </list>
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="CompilerWorkspaceConfiguration">
+    <option name="MAKE_PROJECT_ON_SAVE" value="true" />
+  </component>
+  <component name="FileTemplateManagerImpl">
+    <option name="RECENT_TEMPLATES">
+      <list>
+        <option value="AnnotationType" />
+        <option value="Interface" />
+        <option value="Class" />
+      </list>
+    </option>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="JRebelWorkspace">
+    <option name="jrebelEnabledAutocompile" value="true" />
+  </component>
+  <component name="MarkdownSettingsMigration">
+    <option name="stateVersion" value="1" />
+  </component>
+  <component name="MavenImportPreferences">
+    <option name="generalSettings">
+      <MavenGeneralSettings>
+        <option name="mavenHome" value="$PROJECT_DIR$/../../maven/apache-maven-3.3.9" />
+        <option name="userSettingsFile" value="F:\development\maven\apache-maven-3.3.9\conf\settings.xml" />
+      </MavenGeneralSettings>
+    </option>
+  </component>
+  <component name="ProjectId" id="2SRzp2ShFi166anLE9P5w11I1qf" />
+  <component name="ProjectLevelVcsManager" settingsEditedManually="true">
+    <ConfirmationsSetting value="2" id="Add" />
+  </component>
+  <component name="ProjectViewState">
+    <option name="hideEmptyMiddlePackages" value="true" />
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent">{
+  &quot;keyToString&quot;: {
+    &quot;RequestMappingsPanelOrder0&quot;: &quot;0&quot;,
+    &quot;RequestMappingsPanelOrder1&quot;: &quot;1&quot;,
+    &quot;RequestMappingsPanelWidth0&quot;: &quot;75&quot;,
+    &quot;RequestMappingsPanelWidth1&quot;: &quot;75&quot;,
+    &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
+    &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
+    &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
+    &quot;last_opened_file_path&quot;: &quot;F:/development/kps-phase-web/kps-phase/src/main/resources/mapper&quot;,
+    &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
+    &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
+    &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
+    &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
+    &quot;project.structure.last.edited&quot;: &quot;Libraries&quot;,
+    &quot;project.structure.proportion&quot;: &quot;0.15&quot;,
+    &quot;project.structure.side.proportion&quot;: &quot;0.2&quot;,
+    &quot;settings.editor.selected.configurable&quot;: &quot;MavenSettings&quot;,
+    &quot;spring.configuration.checksum&quot;: &quot;636abdfb1ee207741bb2584aa0d1e115&quot;,
+    &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
+  }
+}</component>
+  <component name="RebelAgentSelection">
+    <selection>jr</selection>
+  </component>
+  <component name="RecentsManager">
+    <key name="CopyFile.RECENT_KEYS">
+      <recent name="F:\development\kps-phase-web\kps-phase\src\main\resources\mapper" />
+      <recent name="F:\development\kps-phase-web\kps-phase\src\main\resources" />
+      <recent name="F:\development\kps-phase-web\kps-phase\src\main\java\com\dayou" />
+    </key>
+    <key name="CopyClassDialog.RECENTS_KEY">
+      <recent name="com.dayou.utils" />
+      <recent name="com.dayou.gen" />
+      <recent name="com.dayou.configuration" />
+      <recent name="com.dayou" />
+    </key>
+  </component>
+  <component name="RunManager">
+    <configuration name="BASEAPPLICATION" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot">
+      <option name="ACTIVE_PROFILES" />
+      <option name="ALTERNATIVE_JRE_PATH" value="F:\development\java\jdk1.8.0_121\jre" />
+      <module name="kps-phase" />
+      <option name="SPRING_BOOT_MAIN_CLASS" value="com.dayou.BaseApplication" />
+      <method v="2">
+        <option name="Make" enabled="true" />
+      </method>
+    </configuration>
+  </component>
+  <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="298c0123-5a38-45f2-a872-7d3a74d33353" name="Changes" comment="" />
+      <created>1689124362016</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1689124362016</updated>
+      <workItem from="1689124364474" duration="9028000" />
+      <workItem from="1689209393490" duration="14343000" />
+      <workItem from="1689295368374" duration="5335000" />
+      <workItem from="1689560439669" duration="6825000" />
+      <workItem from="1689727659647" duration="15945000" />
+      <workItem from="1689814541193" duration="21345000" />
+      <workItem from="1689900018717" duration="15499000" />
+      <workItem from="1690160956840" duration="4572000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="3" />
+  </component>
+  <component name="Vcs.Log.Tabs.Properties">
+    <option name="TAB_STATES">
+      <map>
+        <entry key="MAIN">
+          <value>
+            <State />
+          </value>
+        </entry>
+      </map>
+    </option>
+  </component>
+</project>

+ 304 - 0
pom.xml

@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.dayou</groupId>
+    <artifactId>kps-phase</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <springboot.version>2.4.2</springboot.version>
+        <mybatis-plus.version>3.3.2</mybatis-plus.version>
+        <druid.version>1.1.10</druid.version>
+        <fastjson.version>1.2.72</fastjson.version>
+        <guava.version>26.0-jre</guava.version>
+        <commons-lang3.version>3.7</commons-lang3.version>
+        <commons.io.version>2.5</commons.io.version>
+        <commons.fileupload.version>1.3.3</commons.fileupload.version>
+        <mysql-connector-java.version>8.0.16</mysql-connector-java.version>
+        <resource.delimiter>@</resource.delimiter>
+        <poi.version>4.1.2</poi.version>
+        <hutool.version>5.3.3</hutool.version>
+        <pagehelper.boot.version>1.2.5</pagehelper.boot.version>
+        <spring.version>5.2.7.RELEASE</spring.version>
+        <jwt.version>0.9.0</jwt.version>
+        <liangbaika-validata>1.2.2</liangbaika-validata>
+        <aspectjweaver>1.9.5</aspectjweaver>
+    </properties>
+
+    <dependencies>
+        <!-- SpringBoot的依赖配置 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-dependencies</artifactId>
+            <version>${springboot.version}</version>
+            <type>pom</type>
+            <scope>import</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus</artifactId>
+            <version>${mybatis-plus.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatis-plus.version}</version>
+        </dependency>
+        <!-- pagehelper 分页插件 -->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+            <version>${pagehelper.boot.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3.version}</version>
+        </dependency>
+        <!--io常用工具类 -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons.io.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>${mysql-connector-java.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>3.2.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+            <version>1.18.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <optional>true</optional> <!-- 表示依赖不会传递 -->
+            <version>2.3.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>compile</scope>
+            <version>4.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+            <version>1.23</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>${springboot.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>log4j-to-slf4j</artifactId>
+                    <groupId>org.apache.logging.log4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>jul-to-slf4j</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>${jwt.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.liangbaika</groupId>
+            <artifactId>validate-spring-boot-starter</artifactId>
+            <version>${liangbaika-validata}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+            <version>2.11.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.11.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>${aspectjweaver}</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.dozer</groupId>
+            <artifactId>dozer</artifactId>
+            <version>5.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+            <version>2.4.9</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+                <version>3.6.0</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <version>3.0.2</version>
+                <configuration>
+                    <delimiters>
+                        <delimiter>@</delimiter>
+                    </delimiters>
+                    <useDefaultDelimiters>false</useDefaultDelimiters>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>2.4</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.3.1.RELEASE</version>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
+                    <!--                    <skip>true</skip>-->
+                    <mainClass>com.dayou.BaseApplication</mainClass>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <!--开启过滤,用指定的参数替换directory下的文件中的参数-->
+                <filtering>true</filtering>
+                <excludes>
+                    <exclude>**/*.xlsx</exclude>
+                    <exclude>*/*.docx</exclude>
+                </excludes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <!--开启过滤,用指定的参数替换directory下的文件中的参数-->
+                <filtering>false</filtering>
+                <includes>
+                    <include>**/*.xlsx</include>
+                    <include>*/*.docx</include>
+                </includes>
+            </resource>
+        </resources>
+    </build>
+    <profiles>
+        <profile>
+            <id>local</id>
+            <properties>
+                <spring.active>local</spring.active>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>test</id>
+            <properties>
+                <spring.active>test</spring.active>
+            </properties>
+        </profile>
+        <profile>
+            <id>prod</id>
+            <properties>
+                <spring.active>prod</spring.active>
+            </properties>
+        </profile>
+    </profiles>
+
+</project>

+ 54 - 0
src/main/java/com/dayou/BaseApplication.java

@@ -0,0 +1,54 @@
+package com.dayou;
+
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import com.dayou.configuration.SpringContextHolder;
+
+/**
+ * 类说明:启动类
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+@SpringBootApplication
+@MapperScan("com.dayou.dao")
+@EnableScheduling
+@EnableCaching
+@Slf4j
+@ServletComponentScan
+public class BaseApplication {
+
+    public static void main(String[] args) {
+        ConfigurableApplicationContext app = SpringApplication.run(BaseApplication.class, args);
+        printInfo(app, args);
+
+    }
+
+    private static void printInfo(ConfigurableApplicationContext app, String[] args) {
+        if (app != null) {
+            try {
+                String msg = "\r\n##################################################################";
+                msg += String.format(
+                        "\t\r\n系统[%s] 版本[%s],环境[%s] context-path[%s]于端口[%s]启动应用[%s] 成功! ",
+                        System.getProperty("os.name"),
+                        System.getProperty("os.version"),
+                        SpringContextHolder.getActiveProfile(),
+                        app.getEnvironment().getProperty("server.servlet.context-path"),
+                        app.getEnvironment().getProperty("server.port"),
+                        app.getEnvironment().getProperty("spring.application.name"));
+                msg += "\r\n##################################################################";
+                log.info("args ", args);
+                log.info(msg);
+            } catch (Exception e) {
+            }
+        }
+    }
+
+}

+ 41 - 0
src/main/java/com/dayou/configuration/BaseEntity.java

@@ -0,0 +1,41 @@
+package com.dayou.configuration;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BaseEntity {
+
+    /**
+     * 主键自增id
+     *
+     * @ignore
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    protected Long id;
+
+    /**
+     * 创建时间
+     *
+     * @ignore
+     */
+    private Date created;
+
+    /**
+     * 修改时间
+     *
+     * @ignore
+     */
+    private Date modified;
+
+    /**
+     * 标志位
+     *
+     * @ignore
+     */
+    private Boolean deleted;
+
+}

+ 38 - 0
src/main/java/com/dayou/configuration/BusinessException.java

@@ -0,0 +1,38 @@
+package com.dayou.configuration;
+
+/**
+ * 业务异常
+ *
+ * @author lq
+ */
+public class BusinessException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    protected final String message;
+
+    protected Integer code;
+
+
+    public BusinessException(String message) {
+        this.message = message;
+    }
+
+    public BusinessException(String message, String code) {
+        this.message = message;
+        this.code = Integer.valueOf(code);
+    }
+
+    public BusinessException(String message, Throwable e) {
+        super(message, e);
+        this.message = message;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+}

+ 29 - 0
src/main/java/com/dayou/configuration/CacheConfig.java

@@ -0,0 +1,29 @@
+package com.dayou.configuration;
+
+import com.dayou.entity.User;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Configuration
+public class CacheConfig {
+
+    @Bean
+    @Qualifier("loginCache")
+    public Cache<Long, User> loginCache(){
+        Cache<Long, User> cache = CacheBuilder.newBuilder().expireAfterAccess(JwtConstants.EXPIRATION, TimeUnit.SECONDS).build();
+        return cache;
+    }
+
+}

+ 113 - 0
src/main/java/com/dayou/configuration/DefaultPageIntecptor.java

@@ -0,0 +1,113 @@
+package com.dayou.configuration;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.Alias;
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.statement.select.*;
+import org.apache.ibatis.executor.statement.StatementHandler;
+import org.apache.ibatis.plugin.Intercepts;
+import org.apache.ibatis.plugin.Signature;
+
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 类说明:默认分页拦截器
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+@Setter
+@Accessors(chain = true)
+@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
+@Slf4j
+public class DefaultPageIntecptor extends PaginationInterceptor {
+
+    protected static final String DEFAULT_ORDER_CLOMUN = "id";
+
+    /**
+     * 尽可能的找出默认排序字段
+     * 查询SQL拼接Order By
+     * 优先取别名id 没取到再取id  如果已有排序 就不传
+     *
+     * @param originalSql 需要拼接的SQL
+     * @param page        page对象
+     * @return ignore
+     */
+    @Override
+    public String concatOrderBy(String originalSql, IPage<?> page) {
+        if (CollectionUtils.isEmpty(page.orders())) {
+            String defalutOrder = DEFAULT_ORDER_CLOMUN;
+            try {
+                Select selectStatement = (Select) CCJSqlParserUtil.parse(originalSql);
+                if (selectStatement.getSelectBody() instanceof PlainSelect) {
+                    PlainSelect plainSelect = (PlainSelect) selectStatement.getSelectBody();
+                    List<OrderByElement> orderByElements = plainSelect.getOrderByElements();
+                    FromItem fromItem = plainSelect.getFromItem();
+                    String oneAlis = getOneAlis(Lists.newArrayList(fromItem));
+                    String otherAlis = null;
+                    List<Join> joins = plainSelect.getJoins();
+                    if (CollUtil.isNotEmpty(joins)) {
+                        List<FromItem> collect = joins.stream().map(Join::getRightItem).collect(Collectors.toList());
+                        otherAlis = getOneAlis(collect);
+                    }
+                    String SPLITER = ".";
+                    defalutOrder = oneAlis == null ? (otherAlis == null ? DEFAULT_ORDER_CLOMUN : otherAlis + SPLITER + DEFAULT_ORDER_CLOMUN)
+                            : (oneAlis + SPLITER + DEFAULT_ORDER_CLOMUN);
+                    if (CollUtil.isNotEmpty(orderByElements)) {
+                        //sql里已有排序 就不添加默认排序
+                        defalutOrder = null;
+                    }
+                }
+            } catch (Exception e) {
+                defalutOrder = DEFAULT_ORDER_CLOMUN;
+            }
+
+            if (page instanceof Page && defalutOrder != null) {
+                List<OrderItem> item = new ArrayList<>();
+                OrderItem defaultOrderItem = new OrderItem();
+                //客户端不传排序的时候 全局按照id  降序排列  这里暂时写死id
+                defaultOrderItem.setColumn(defalutOrder);
+                defaultOrderItem.setAsc(false);
+                item.add(defaultOrderItem);
+                ((Page<?>) page).addOrder(item);
+            }
+        }
+        return super.concatOrderBy(originalSql, page);
+    }
+
+    /**
+     * 获取一个sql里有效的别名
+     *
+     * @param fromItems
+     * @return
+     */
+    protected static String getOneAlis(List<? extends FromItem> fromItems) {
+        if (CollUtil.isNotEmpty(fromItems)) {
+            for (FromItem fromItem : fromItems) {
+                if (fromItem == null) {
+                    continue;
+                }
+                Alias alias = fromItem.getAlias();
+                if (alias != null && StrUtil.isNotBlank(alias.getName())) {
+                    return alias.getName();
+                }
+            }
+        }
+        return null;
+    }
+
+}

+ 100 - 0
src/main/java/com/dayou/configuration/ErrorCode.java

@@ -0,0 +1,100 @@
+package com.dayou.configuration;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.util.Objects;
+
+/**
+ * Define the error id.
+ */
+public class ErrorCode {
+    public static final ErrorCode PWD_ERROR = ErrorCode("001", "账号/密码错误");
+    public static final ErrorCode FORM_EXPIRED = ErrorCode("002", "页面过期,请刷新后重试");
+    public static final ErrorCode FORM_DUPLICATE = ErrorCode("003", "请勿重复提交");
+    public static final ErrorCode DATA_NOT_EXISTS = ErrorCode("004", "数据不存在");
+
+    public static final ErrorCode RAS_IMPORT_ERROR = ErrorCode("10000", "导入excel出错 {0}");
+
+    public static final ErrorCode NO_AUTH = ErrorCode("10001", "用户无权限");
+    public static final ErrorCode UN_LOGIN = ErrorCode("10004", "用户未登录");
+    public static final ErrorCode LOGIN_EXPIRE = ErrorCode("10005", "登录过期");
+    public static final ErrorCode DEFAULTERROR = ErrorCode("10006", "系统繁忙");
+    public static final ErrorCode PARAM_ERROR = ErrorCode("10007", "参数错误");
+
+    public static final ErrorCode INVALID_TOKEN = ErrorCode("10008", "请登录");
+    public static final ErrorCode DATA_EXIST = ErrorCode("10009", "数据已存在");
+
+    public static final ErrorCode CUSTOM_ERROR = ErrorCode("10010", "{0}");
+
+
+    private String code;
+    private String errorMsg;
+
+    public static ErrorCode ErrorCode(String code, String errorMsg) {
+        return new ErrorCode(code, errorMsg);
+    }
+
+    private ErrorCode() {
+    }
+
+
+    public ErrorCode(String code, String errorMsg) {
+        this.code = code;
+        this.errorMsg = errorMsg;
+    }
+
+    public static void throwBusinessException(ErrorCode errorCode, Object... values) {
+        throw buildBusinessException(errorCode, values);
+    }
+
+    public static BusinessException buildBusinessException(ErrorCode errorCode, Object... values) {
+        String message = errorCode.errorMsg;
+        if (ArrayUtils.isNotEmpty(values)) {
+            for (int i = 0; i < values.length; i++) {
+                if (message.contains("{") && message.contains("}")) {
+                    message = message.replaceFirst("\\{" + i + "\\}", values[i].toString());
+                } else {
+                    message += " " + values[i].toString() + " ";
+                }
+            }
+        }
+
+        return new BusinessException(message, errorCode.code);
+    }
+
+    public static void throwBusinessException(String msg, String code) {
+        throw new BusinessException(msg, code == null ? DEFAULTERROR.getCode() : code);
+    }
+
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this)
+                .append("id", code)
+                .append("errorMsg", errorMsg)
+                .toString();
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+
+    public static void throwExceptionIfNull(Object o){
+        if(Objects.isNull(o)){
+            throwBusinessException(DATA_NOT_EXISTS);
+        }
+    }
+}

+ 103 - 0
src/main/java/com/dayou/configuration/GlobalExceptionHandler.java

@@ -0,0 +1,103 @@
+package com.dayou.configuration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.validation.BindException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+import java.util.List;
+
+/**
+ * 异常处理器
+ *
+ * @author wucl
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+
+    @ExceptionHandler(DuplicateKeyException.class)
+    public RestResponse handleDuplicateKeyException(DuplicateKeyException e) {
+        return RestResponse.error(ErrorCode.DATA_EXIST.getErrorMsg(), Integer.valueOf(ErrorCode.DATA_EXIST.getCode()));
+    }
+
+    @ExceptionHandler(NoHandlerFoundException.class)
+    public RestResponse handlerNoFoundException(Exception e) {
+        return RestResponse.error("404 资源不存在,请检查路径是否正确", HttpStatus.NOT_FOUND.value());
+    }
+
+
+    @ExceptionHandler(BusinessException.class)
+    public RestResponse handleBusinessException(BusinessException e) {
+        return RestResponse.error(e.getMessage(), e.getCode());
+    }
+
+
+    @ExceptionHandler(IllegalStateException.class)
+    public RestResponse handleBusinessException(IllegalStateException e) {
+        logger.error(e.getMessage(), e);
+        if (e.getMessage().contains("Duplicate key")) {
+            return RestResponse.error("基础数据重复 " + e.getMessage());
+        }
+        return RestResponse.error("系统出错了");
+    }
+
+    /**
+     * 请求方式不支持
+     */
+    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
+    @ResponseStatus(code = HttpStatus.METHOD_NOT_ALLOWED)
+    public RestResponse handleException(HttpRequestMethodNotSupportedException e) {
+        logger.error(e.getMessage(), e);
+        return RestResponse.error("不支持' " + e.getMethod() + "'请求");
+    }
+
+    /**
+     * 拦截未知的运行时异常
+     */
+    @ExceptionHandler(RuntimeException.class)
+    public RestResponse runtimeError(RuntimeException e) {
+        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
+            throw e;
+        }
+        logger.error("系统出错了:", e);
+        if (e.getMessage().contains("Data too long")) {
+            return RestResponse.error("存在数据过长字段,请检查。");
+        }
+        if ( e instanceof HttpMessageNotReadableException){
+            return RestResponse.error("参数格式不正确,请配置正确参数类型。");
+        }
+        return RestResponse.error("系统出错了");
+    }
+
+    /**
+     * 拦截未知的运行时异常
+     */
+    @ExceptionHandler(BindException.class)
+    public RestResponse bindError(BindException e) {
+        BindingResult bindingResult = e.getBindingResult();
+        List<ObjectError> allErrors = bindingResult.getAllErrors();
+        StringBuilder errMsg = new StringBuilder();
+        for (ObjectError allError : allErrors) {
+            FieldError fieldError = (FieldError) allError;
+            String field = fieldError.getField();
+            String defaultMessage = fieldError.getDefaultMessage();
+            errMsg.append(field + ":" + defaultMessage + ";  ");
+        }
+        logger.error("参数错误,原因:" + errMsg.toString());
+        return RestResponse.error(errMsg.toString(), Integer.valueOf(ErrorCode.PARAM_ERROR.getCode()));
+    }
+
+}

+ 31 - 0
src/main/java/com/dayou/configuration/JwtConstants.java

@@ -0,0 +1,31 @@
+package com.dayou.configuration;
+
+/**
+ * 类说明:Jwt相关配置
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+public interface JwtConstants {
+
+
+    String AUTH_HEADER = "Authorization";
+
+    String SECRET = "secret";
+    String SECRET_OAUTH = "dySecretForOAuth";
+
+    /**
+     * 过期时间(秒)
+     */
+    Long EXPIRATION = 60*60*24L;
+
+    String REST_TOKEN ="token";
+
+    String USER_CLAIM_KEY="user";
+
+    String USER_TYPE_CLAIM_KEY="userType";
+
+    //30分钟
+    Long GIS_EXPIRATION = 60*30L;
+}

+ 27 - 0
src/main/java/com/dayou/configuration/MybatisPlusConfig.java

@@ -0,0 +1,27 @@
+package com.dayou.configuration;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+
+    @Bean
+    @Order(Integer.MAX_VALUE - 1)
+    public PaginationInterceptor paginationInterceptor() {
+        return new DefaultPageIntecptor();
+    }
+
+
+}
+

+ 88 - 0
src/main/java/com/dayou/configuration/RestResponse.java

@@ -0,0 +1,88 @@
+package com.dayou.configuration;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 类说明:统一返回对象
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class RestResponse<T> implements Serializable {
+    /**
+     * code码
+     */
+    private Integer code;
+    /**
+     * 提示信息
+     */
+    private String msg;
+
+    /**
+     * 数据
+     */
+    private T data;
+
+    public RestResponse() {
+    }
+
+    public RestResponse(T t) {
+        this.data = t;
+    }
+
+
+    public static <T> RestResponse<T> success(T t, String msg, Integer code) {
+        RestResponse r2 = new RestResponse<T>(t);
+        r2.code = code;
+        r2.msg = msg;
+        return r2;
+    }
+
+    public static <T> RestResponse error(T t, String msg, Integer code) {
+        RestResponse r2 = new RestResponse<T>(t);
+        r2.code = code;
+        r2.msg = msg;
+        return r2;
+    }
+
+    public static <T> RestResponse<T> success(T t) {
+        return success(t, "success", 200);
+    }
+
+    public static <T> RestResponse<T> success() {
+        return success(null, "success", 200);
+    }
+
+    public static <T> RestResponse<T> approval() {
+        return success(null, "success", 250);
+    }
+
+    public static <T> RestResponse<T> data(T t) {
+        return success(t);
+    }
+
+    public static <T> RestResponse<T> data(T t, Integer code) {
+        return success(t, null, code);
+    }
+
+    public static <T> RestResponse error(String msg) {
+        return error(null, msg, 500);
+    }
+
+    public static <T> RestResponse error(String msg, Integer code) {
+        return error(null, msg, code);
+    }
+
+    public static <T> RestResponse error() {
+        return error(null, "发生了一些错误", 500);
+    }
+
+
+    public static <T> RestResponse<T> success(T t, String msg) {
+        return success(t, msg, 200);
+    }
+}

+ 102 - 0
src/main/java/com/dayou/configuration/SpringContextHolder.java

@@ -0,0 +1,102 @@
+package com.dayou.configuration;
+
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+@Slf4j
+@Service
+@Lazy(false)
+public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
+    private static ApplicationContext applicationContext = null;
+
+    /**
+     * 取得存储在静态变量中的ApplicationContext.
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /**
+     * 实现ApplicationContextAware接口, 注入Context到静态变量中.
+     */
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        SpringContextHolder.applicationContext = applicationContext;
+    }
+
+    /**
+     * 清除SpringContextHolder中的ApplicationContext为Null.
+     */
+    public static void clearHolder() {
+        if (log.isDebugEnabled()) {
+            log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
+        }
+        applicationContext = null;
+    }
+
+    /**
+     * 获取当前环境
+     *
+     * @return
+     */
+    public static String getActiveProfile() {
+        try {
+            String[] profiles = applicationContext.getEnvironment().getActiveProfiles();
+            if (profiles != null && profiles.length != 0 && profiles[0] != null) {
+                return profiles[0];
+            }
+        } catch (Exception e) {
+        }
+        // 不返回null
+        return "";
+    }
+
+    /**
+     * 发布事件
+     *
+     * @param event
+     */
+    public static void publishEvent(ApplicationEvent event) {
+        if (applicationContext == null) {
+            return;
+        }
+        applicationContext.publishEvent(event);
+    }
+
+    /**
+     * 实现DisposableBean接口, 在Context关闭时清理静态变量.
+     */
+    @Override
+    @SneakyThrows
+    public void destroy() {
+        SpringContextHolder.clearHolder();
+    }
+
+    /**
+     * 获取当前请求对象
+     *
+     * @return
+     */
+    public static HttpServletRequest currentReq() {
+        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = servletRequestAttributes.getRequest();
+        return request;
+    }
+}

+ 47 - 0
src/main/java/com/dayou/configuration/WebConfig.java

@@ -0,0 +1,47 @@
+package com.dayou.configuration;
+
+import com.dayou.interceptor.LoginInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.format.datetime.DateFormatter;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @Author kids
+ */
+@Configuration(proxyBeanMethods = false)
+public class WebConfig implements WebMvcConfigurer {
+
+
+    @Autowired
+    private LoginInterceptor loginInterceptor;
+
+
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**")
+                .allowedOrigins("*")
+                .allowCredentials(true)
+                .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
+                .allowedHeaders("X-Requested-With", "Content-Type", "token")
+                .maxAge(3600);
+    }
+
+
+    @Override
+    public void addFormatters(FormatterRegistry registry) {
+        registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+
+        registry.addInterceptor(loginInterceptor)
+                .addPathPatterns("/**")
+                .excludePathPatterns("/user/login", "/error");
+    }
+}

+ 16 - 0
src/main/java/com/dayou/configuration/annotation/IgnoreAuth.java

@@ -0,0 +1,16 @@
+package com.dayou.configuration.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IgnoreAuth {
+}

+ 41 - 0
src/main/java/com/dayou/controller/CycleController.java

@@ -0,0 +1,41 @@
+package com.dayou.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayou.configuration.RestResponse;
+import com.dayou.entity.Cycle;
+import com.dayou.service.ICycleService;
+import com.dayou.vo.CycleVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@RestController
+@RequestMapping("/cycle")
+@Slf4j
+public class CycleController {
+
+    @Autowired
+    private ICycleService cycleService;
+
+    @PostMapping("")
+    public RestResponse<Boolean> saveCycle(@RequestBody @Valid Cycle cycle){
+        Boolean result = cycleService.saveCycle(cycle);
+        return RestResponse.data(result);
+    }
+
+    @GetMapping("")
+    public RestResponse<IPage<CycleVO>> getPage(Page page, CycleVO cycleVO){
+        IPage<CycleVO> result = cycleService.getPage(page,cycleVO);
+        return RestResponse.data(result);
+    }
+}

+ 82 - 0
src/main/java/com/dayou/controller/DocumentController.java

@@ -0,0 +1,82 @@
+package com.dayou.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayou.configuration.RestResponse;
+import com.dayou.configuration.annotation.IgnoreAuth;
+import com.dayou.dto.CommitDTO;
+import com.dayou.dto.DocumentDTO;
+import com.dayou.entity.Document;
+import com.dayou.service.IDocumentService;
+import com.dayou.service.IProfessorResultService;
+import com.dayou.vo.DocumentCycleVO;
+import com.dayou.vo.DocumentVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@RestController
+@RequestMapping("/document")
+@Slf4j
+public class DocumentController {
+
+    @Autowired
+    private IDocumentService documentService;
+
+    @Autowired
+    private IProfessorResultService professorResultService;
+
+    /**
+     * 获取当前可用的问卷文档
+     * @return
+     */
+    @IgnoreAuth
+    @GetMapping("/current")
+    public RestResponse<DocumentCycleVO> getDocument(){
+        DocumentCycleVO documentCycleVO = documentService.getDocumentCycleVO();
+        return RestResponse.data(documentCycleVO);
+    }
+
+    /**
+     * 提交问卷
+     * @return
+     */
+    @IgnoreAuth
+    @PostMapping("/commit")
+    public RestResponse<Boolean> commitDocument(@RequestBody @Valid DocumentCycleVO documentCycleVO){
+        Boolean result = professorResultService.commitDocument(documentCycleVO);
+        return RestResponse.data(result);
+    }
+
+    /**
+     * 问卷列表
+     * @param documentVO
+     * @param page
+     * @return
+     */
+    @GetMapping("")
+    public RestResponse<IPage<DocumentVO>> gePage(Page page, DocumentVO documentVO ){
+        IPage<DocumentVO> result = documentService.getPage(documentVO,page);
+        return RestResponse.data(result);
+    }
+
+    /**
+     * 新增问卷
+     * @param documentDTO
+     * @return
+     */
+    @PostMapping("")
+    public RestResponse<Boolean> saveDocument(@RequestBody DocumentDTO documentDTO){
+        Boolean result = documentService.saveDocument(documentDTO);
+        return RestResponse.data(result);
+    }
+}

+ 48 - 0
src/main/java/com/dayou/controller/ProfessorResultController.java

@@ -0,0 +1,48 @@
+package com.dayou.controller;
+
+import com.dayou.configuration.RestResponse;
+import com.dayou.configuration.annotation.IgnoreAuth;
+import com.dayou.service.IProfessorResultService;
+import com.dayou.vo.AnalysisResultVO;
+import com.dayou.vo.ProfessorResultVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@RestController
+@RequestMapping("/professor")
+@Slf4j
+public class ProfessorResultController {
+
+    @Autowired
+    private IProfessorResultService professorResultService;
+
+    @IgnoreAuth
+    @GetMapping("/current")
+    public RestResponse<List<ProfessorResultVO>> getResultList(){
+        List<ProfessorResultVO> list = professorResultService.getResultList();
+        return RestResponse.data(list);
+    }
+
+    @GetMapping("/cycle/{id}")
+    public RestResponse<List<ProfessorResultVO>> getResultByCycleId(@PathVariable("id") Long id){
+        List<ProfessorResultVO> list = professorResultService.getResultByCycleId(id);
+        return RestResponse.data(list);
+    }
+
+    @DeleteMapping("/{id}")
+    public RestResponse<Boolean> removeScore(@PathVariable("id") Long id){
+        boolean b = professorResultService.removeScore(id);
+        return RestResponse.data(b);
+    }
+
+}

+ 43 - 0
src/main/java/com/dayou/controller/QuestionAnalysisController.java

@@ -0,0 +1,43 @@
+package com.dayou.controller;
+
+import com.dayou.configuration.RestResponse;
+import com.dayou.configuration.annotation.IgnoreAuth;
+import com.dayou.service.IQuestionAnalysisService;
+import com.dayou.vo.AnalysisResultVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@RestController
+@RequestMapping("/analysis")
+@Slf4j
+public class QuestionAnalysisController {
+
+    @Autowired
+    private IQuestionAnalysisService questionAnalysisService;
+
+    @IgnoreAuth
+    @GetMapping("/current")
+    public RestResponse<List<AnalysisResultVO>> getAnalysisList(){
+        List<AnalysisResultVO> list = questionAnalysisService.getAnalysisList();
+        return RestResponse.data(list);
+    }
+
+    @GetMapping("/cycle/{id}")
+    public RestResponse<List<AnalysisResultVO>> getAnalysisListByCycleId(@PathVariable("id") Long id){
+        List<AnalysisResultVO> list = questionAnalysisService.getAnalysisListByCycleId(id);
+        return RestResponse.data(list);
+    }
+}

+ 58 - 0
src/main/java/com/dayou/controller/QuestionController.java

@@ -0,0 +1,58 @@
+package com.dayou.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayou.configuration.BaseEntity;
+import com.dayou.configuration.RestResponse;
+import com.dayou.entity.Question;
+import com.dayou.service.IQuestionService;
+import com.dayou.utils.ConvertUtil;
+import com.dayou.vo.LabelKeyVO;
+import com.dayou.vo.QuestionVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@RestController
+@RequestMapping("/question")
+@Slf4j
+public class QuestionController {
+
+    @Autowired
+    private IQuestionService questionService;
+
+    @GetMapping("")
+    public RestResponse<IPage<QuestionVO>> getQuestion(Question question, Page page){
+        Page xPage = questionService.page(page, new LambdaQueryWrapper<Question>()
+                .like(StrUtil.isNotBlank(question.getName()), Question::getName, question.getName()));
+        return RestResponse.data(xPage);
+    }
+
+    @PostMapping("")
+    public RestResponse<Boolean> saveQuestion(@RequestBody @Valid Question question){
+        return RestResponse.data(questionService.save(question));
+    }
+
+    @GetMapping("/simpleAll")
+    public RestResponse<List<LabelKeyVO>> getList(){
+        List<Question> list = questionService.list(new LambdaQueryWrapper<Question>().select(BaseEntity::getId, Question::getName));
+        List<LabelKeyVO> labelKeyVOS = ConvertUtil.copyList(list, LabelKeyVO.class);
+        labelKeyVOS.stream().forEach(x->{
+            x.setKey(x.getId());
+            x.setLabel(x.getName());
+        });
+        return RestResponse.data(labelKeyVOS);
+    }
+}

+ 40 - 0
src/main/java/com/dayou/controller/UserController.java

@@ -0,0 +1,40 @@
+package com.dayou.controller;
+
+import com.dayou.configuration.RestResponse;
+import com.dayou.dto.LoginDTO;
+import com.dayou.dto.UserDTO;
+import com.dayou.service.IUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@RestController
+@RequestMapping("/user")
+@Slf4j
+public class UserController {
+
+    @Autowired
+    private IUserService userService;
+
+    /**
+     * 登录
+     *
+     * @param userDTO
+     * @return
+     */
+    @PostMapping("/login")
+    public RestResponse<LoginDTO> login(@RequestBody @Valid UserDTO userDTO) {
+        LoginDTO loginDTO = userService.login(userDTO);
+        return RestResponse.data(loginDTO);
+    }
+
+}

+ 19 - 0
src/main/java/com/dayou/dao/CycleMapper.java

@@ -0,0 +1,19 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayou.entity.Cycle;
+import com.dayou.vo.CycleVO;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+public interface CycleMapper extends BaseMapper<Cycle> {
+    IPage<CycleVO> getPage(Page page, @Param("cycle") CycleVO cycleVO);
+}

+ 22 - 0
src/main/java/com/dayou/dao/DocumentMapper.java

@@ -0,0 +1,22 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.dayou.entity.Document;
+import com.dayou.vo.DocumentCycleVO;
+import com.dayou.vo.DocumentVO;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+public interface DocumentMapper extends BaseMapper<Document> {
+    DocumentCycleVO getDocumentCycleVO();
+
+    IPage<DocumentVO> getPage(Page page, @Param("document") DocumentVO documentVO);
+}

+ 14 - 0
src/main/java/com/dayou/dao/DocumentQuestionMapper.java

@@ -0,0 +1,14 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dayou.entity.DocumentQuestion;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+public interface DocumentQuestionMapper extends BaseMapper<DocumentQuestion> {
+}

+ 27 - 0
src/main/java/com/dayou/dao/ProfessorResultMapper.java

@@ -0,0 +1,27 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dayou.entity.ProfessorResult;
+import com.dayou.entity.QuestionAnalysis;
+import com.dayou.vo.ProfessorResultVO;
+import com.dayou.vo.QuestionVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+public interface ProfessorResultMapper extends BaseMapper<ProfessorResult> {
+    List<QuestionAnalysis> getAvgScore(@Param("cycleId") Long cycleId, @Param("questionId")Long questionId);
+
+
+    List<ProfessorResultVO> getResultList();
+
+    List<ProfessorResultVO> getResultByCycleId(@Param("id") Long id);
+
+}

+ 21 - 0
src/main/java/com/dayou/dao/QuestionAnalysisMapper.java

@@ -0,0 +1,21 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dayou.entity.QuestionAnalysis;
+import com.dayou.vo.AnalysisResultVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+public interface QuestionAnalysisMapper extends BaseMapper<QuestionAnalysis> {
+    List<AnalysisResultVO> getAnalysisList();
+
+    List<AnalysisResultVO> getAnalysisListByCycleId(@Param("id") Long id);
+}

+ 14 - 0
src/main/java/com/dayou/dao/QuestionMapper.java

@@ -0,0 +1,14 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dayou.entity.Question;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+public interface QuestionMapper extends BaseMapper<Question> {
+}

+ 14 - 0
src/main/java/com/dayou/dao/UserMapper.java

@@ -0,0 +1,14 @@
+package com.dayou.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.dayou.entity.User;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+public interface UserMapper extends BaseMapper<User> {
+}

+ 25 - 0
src/main/java/com/dayou/dto/CommitDTO.java

@@ -0,0 +1,25 @@
+package com.dayou.dto;
+
+import com.github.liangbaika.validate.annations.AbcValidate;
+import com.github.liangbaika.validate.enums.Check;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Map;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class CommitDTO {
+
+    @AbcValidate(required = true,message = "专家编号不能为空",fun = Check.NotEmpty)
+    private String professorNo;
+
+    @AbcValidate(required = true,message = "答案不能为空",fun = Check.NotNull)
+    private Map<Long, BigDecimal> result;
+}

+ 25 - 0
src/main/java/com/dayou/dto/DocumentDTO.java

@@ -0,0 +1,25 @@
+package com.dayou.dto;
+
+import com.dayou.vo.QuestionVO;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class DocumentDTO {
+
+    private String itemName;
+
+    private String scope;
+
+    private String type;
+
+    private List<Long> questions;
+}

+ 18 - 0
src/main/java/com/dayou/dto/LoginDTO.java

@@ -0,0 +1,18 @@
+package com.dayou.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Data
+@Builder
+public class LoginDTO {
+
+    private String token;
+}

+ 22 - 0
src/main/java/com/dayou/dto/UserDTO.java

@@ -0,0 +1,22 @@
+package com.dayou.dto;
+
+import com.github.liangbaika.validate.annations.AbcValidate;
+import com.github.liangbaika.validate.enums.Check;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class UserDTO {
+
+    @AbcValidate(required = true,message = "用户账号不能为空",fun = Check.NotEmpty)
+    private String account;
+
+    @AbcValidate(required = true,message = "用户密码不能为空",fun = Check.NotEmpty)
+    private String password;
+}

+ 23 - 0
src/main/java/com/dayou/entity/Cycle.java

@@ -0,0 +1,23 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import com.github.liangbaika.validate.annations.AbcValidate;
+import com.github.liangbaika.validate.enums.Check;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class Cycle extends BaseEntity {
+
+    @AbcValidate(required = true,message = "问卷ID不能为空",fun = Check.NotNull)
+    private Long documentId;
+
+    @AbcValidate(required = true,message = "轮数不能为空",fun = Check.NotEmpty)
+    private String cycleName;
+}

+ 23 - 0
src/main/java/com/dayou/entity/Document.java

@@ -0,0 +1,23 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class Document extends BaseEntity {
+
+    private String itemName;
+
+    private String type;
+
+    private String scope;
+
+}

+ 21 - 0
src/main/java/com/dayou/entity/DocumentQuestion.java

@@ -0,0 +1,21 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class DocumentQuestion extends BaseEntity {
+
+    private Long documentId;
+
+    private Long questionId;
+
+}

+ 23 - 0
src/main/java/com/dayou/entity/ProfessorResult.java

@@ -0,0 +1,23 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class ProfessorResult extends BaseEntity {
+
+    private String professorNo;
+    private Long cycleId;
+    private Long questionId;
+    private BigDecimal score;
+}

+ 22 - 0
src/main/java/com/dayou/entity/Question.java

@@ -0,0 +1,22 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import com.github.liangbaika.validate.annations.AbcValidate;
+import com.github.liangbaika.validate.enums.Check;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class Question extends BaseEntity {
+
+    @AbcValidate(required = true,message = "题目名称不能为空" ,fun = Check.NotEmpty)
+    private String name;
+
+}

+ 23 - 0
src/main/java/com/dayou/entity/QuestionAnalysis.java

@@ -0,0 +1,23 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class QuestionAnalysis extends BaseEntity {
+
+    private Long cycleId;
+
+    private Long questionId;
+
+    private BigDecimal avgScore;
+}

+ 22 - 0
src/main/java/com/dayou/entity/User.java

@@ -0,0 +1,22 @@
+package com.dayou.entity;
+
+import com.dayou.configuration.BaseEntity;
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class User extends BaseEntity {
+
+    private String account;
+
+    private String password;
+
+    private String name;
+
+}

+ 112 - 0
src/main/java/com/dayou/interceptor/LoginInterceptor.java

@@ -0,0 +1,112 @@
+package com.dayou.interceptor;
+
+import cn.hutool.core.util.StrUtil;
+import com.dayou.configuration.BusinessException;
+import com.dayou.configuration.ErrorCode;
+import com.dayou.configuration.JwtConstants;
+import com.dayou.configuration.annotation.IgnoreAuth;
+import com.dayou.entity.User;
+import com.dayou.utils.JwtTokenUtil;
+import com.dayou.utils.LoginContext;
+import com.google.common.cache.Cache;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.text.MessageFormat;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Component
+@Slf4j
+public class LoginInterceptor implements HandlerInterceptor {
+
+    @Autowired
+    @Qualifier("loginCache")
+    private Cache<Long, User> loginCache;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        Boolean ignore = checkIgnore(handler);
+
+        String token = request.getHeader(JwtConstants.REST_TOKEN);
+
+        if (StrUtil.isBlank(token)){
+            token = request.getParameter(JwtConstants.REST_TOKEN);
+        }
+        if (StringUtils.isBlank(token) && !ignore) {
+            ErrorCode.throwBusinessException(ErrorCode.UN_LOGIN);
+        }
+
+        User user = null;
+
+        try {
+            if (StrUtil.isNotBlank(token)){
+                Claims claims = JwtTokenUtil.getClaimFromToken(token, JwtConstants.SECRET);
+                String subject = claims.getSubject();
+                Long userId = Long.valueOf(subject);
+                user = loginCache.getIfPresent(userId);
+                if (user == null) {
+                    ErrorCode.throwBusinessException(ErrorCode.LOGIN_EXPIRE);
+                }
+                LoginContext.setUser(user);
+            }
+        } catch (ExpiredJwtException ee){
+            //判断token是否过期
+            ErrorCode.throwBusinessException(ErrorCode.LOGIN_EXPIRE);
+        }
+        catch (Exception e) {
+            if (e instanceof BusinessException) {
+                throw e;
+            }
+            log.warn(MessageFormat.format("非法token,token:{0}", token));
+            ErrorCode.throwBusinessException(ErrorCode.INVALID_TOKEN);
+        }
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        LoginContext.removeAll();
+    }
+
+    private Boolean checkIgnore(Object handler) {
+        if (handler == null){
+            return true;
+        }
+        if (!(handler instanceof HandlerMethod)){
+            return true;
+        }
+        HandlerMethod handlerMethod = (HandlerMethod) handler;
+        IgnoreAuth ignoreAuthOnMethod = handlerMethod.getMethodAnnotation(IgnoreAuth.class);
+
+        if (ignoreAuthOnMethod != null){
+            return true;
+        }
+
+        Class<?> controllerBean = ((HandlerMethod) handler).getBeanType();
+        IgnoreAuth ignoreAuthOnClass = controllerBean.getAnnotation(IgnoreAuth.class);
+        if (null != ignoreAuthOnClass) {
+            return true;
+        }
+        return false;
+    }
+}

+ 20 - 0
src/main/java/com/dayou/service/ICycleService.java

@@ -0,0 +1,20 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.entity.Cycle;
+import com.dayou.vo.CycleVO;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+public interface ICycleService extends IService<Cycle> {
+    IPage<CycleVO> getPage(Page page, CycleVO cycleVO);
+
+    Boolean saveCycle(Cycle cycle);
+}

+ 14 - 0
src/main/java/com/dayou/service/IDocumentQuestionService.java

@@ -0,0 +1,14 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.entity.DocumentQuestion;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+public interface IDocumentQuestionService extends IService<DocumentQuestion> {
+}

+ 24 - 0
src/main/java/com/dayou/service/IDocumentService.java

@@ -0,0 +1,24 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.dto.DocumentDTO;
+import com.dayou.entity.Document;
+import com.dayou.vo.DocumentCycleVO;
+import com.dayou.vo.DocumentVO;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+public interface IDocumentService extends IService<Document> {
+    DocumentCycleVO getDocumentCycleVO();
+
+    IPage<DocumentVO> getPage(DocumentVO documentVO, Page page);
+
+    Boolean saveDocument(DocumentDTO documentDTO);
+}

+ 28 - 0
src/main/java/com/dayou/service/IProfessorResultService.java

@@ -0,0 +1,28 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.dto.CommitDTO;
+import com.dayou.entity.ProfessorResult;
+import com.dayou.vo.AnalysisResultVO;
+import com.dayou.vo.DocumentCycleVO;
+import com.dayou.vo.ProfessorResultVO;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+public interface IProfessorResultService extends IService<ProfessorResult> {
+    Boolean commitDocument(DocumentCycleVO documentCycleVO);
+
+    List<ProfessorResultVO> getResultList();
+
+
+    List<ProfessorResultVO> getResultByCycleId(Long id);
+
+    boolean removeScore(Long id);
+}

+ 20 - 0
src/main/java/com/dayou/service/IQuestionAnalysisService.java

@@ -0,0 +1,20 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.entity.QuestionAnalysis;
+import com.dayou.vo.AnalysisResultVO;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+public interface IQuestionAnalysisService extends IService<QuestionAnalysis> {
+    List<AnalysisResultVO> getAnalysisList();
+
+    List<AnalysisResultVO> getAnalysisListByCycleId(Long id);
+}

+ 14 - 0
src/main/java/com/dayou/service/IQuestionService.java

@@ -0,0 +1,14 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.entity.Question;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+public interface IQuestionService extends IService<Question> {
+}

+ 18 - 0
src/main/java/com/dayou/service/IUserService.java

@@ -0,0 +1,18 @@
+package com.dayou.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.dayou.dto.LoginDTO;
+import com.dayou.dto.UserDTO;
+import com.dayou.entity.User;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+public interface IUserService extends IService<User> {
+
+    public LoginDTO login(UserDTO userDTO);
+}

+ 49 - 0
src/main/java/com/dayou/service/impl/CycleServiceImpl.java

@@ -0,0 +1,49 @@
+package com.dayou.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.configuration.BaseEntity;
+import com.dayou.configuration.ErrorCode;
+import com.dayou.dao.CycleMapper;
+import com.dayou.entity.Cycle;
+import com.dayou.service.ICycleService;
+import com.dayou.vo.CycleVO;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class CycleServiceImpl extends ServiceImpl<CycleMapper, Cycle> implements ICycleService {
+
+    @Autowired
+    private CycleMapper cycleMapper;
+
+    @Override
+    public IPage<CycleVO> getPage(Page page, CycleVO cycleVO) {
+        IPage<CycleVO> result = cycleMapper.getPage(page,cycleVO);
+        return result;
+    }
+
+    @Override
+    public Boolean saveCycle(Cycle cycle) {
+        List<Cycle> list = this.list(new LambdaQueryWrapper<Cycle>().eq(Cycle::getDocumentId, cycle.getDocumentId())
+                .eq(Cycle::getCycleName, cycle.getCycleName()).eq(BaseEntity::getDeleted, Boolean.FALSE));
+        if (CollectionUtils.isEmpty(list)){
+            return this.save(cycle);
+        }else {
+            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"该问卷此轮已存在。");
+            return Boolean.FALSE;
+        }
+    }
+}

+ 18 - 0
src/main/java/com/dayou/service/impl/DocumentQuestionServiceImpl.java

@@ -0,0 +1,18 @@
+package com.dayou.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.dao.DocumentQuestionMapper;
+import com.dayou.entity.DocumentQuestion;
+import com.dayou.service.IDocumentQuestionService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class DocumentQuestionServiceImpl extends ServiceImpl<DocumentQuestionMapper, DocumentQuestion> implements IDocumentQuestionService {
+}

+ 64 - 0
src/main/java/com/dayou/service/impl/DocumentServiceImpl.java

@@ -0,0 +1,64 @@
+package com.dayou.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.dao.DocumentMapper;
+import com.dayou.dto.DocumentDTO;
+import com.dayou.entity.Document;
+import com.dayou.entity.DocumentQuestion;
+import com.dayou.service.IDocumentQuestionService;
+import com.dayou.service.IDocumentService;
+import com.dayou.vo.DocumentCycleVO;
+import com.dayou.vo.DocumentVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class DocumentServiceImpl extends ServiceImpl<DocumentMapper, Document> implements IDocumentService {
+
+    @Autowired
+    private DocumentMapper documentMapper;
+
+    @Autowired
+    private IDocumentQuestionService documentQuestionService;
+    @Override
+    public DocumentCycleVO getDocumentCycleVO() {
+        DocumentCycleVO documentCycleVO = documentMapper.getDocumentCycleVO();
+        return documentCycleVO;
+    }
+
+    @Override
+    public IPage<DocumentVO> getPage(DocumentVO documentVO, Page page) {
+        IPage<DocumentVO> xPage = documentMapper.getPage(page,documentVO);
+        return xPage;
+    }
+
+    @Transactional
+    @Override
+    public Boolean saveDocument(DocumentDTO documentDTO) {
+        Document document = BeanUtil.copyProperties(documentDTO, Document.class);
+        this.save(document);
+        List<Long> questions = documentDTO.getQuestions();
+        Long documentId = document.getId();
+        List<DocumentQuestion> collect = questions.stream().map(x -> {
+            DocumentQuestion dq = new DocumentQuestion();
+            dq.setDocumentId(documentId);
+            dq.setQuestionId(x);
+            return dq;
+        }).collect(Collectors.toList());
+        return documentQuestionService.saveBatch(collect);
+    }
+}

+ 108 - 0
src/main/java/com/dayou/service/impl/ProfessorResultServiceImpl.java

@@ -0,0 +1,108 @@
+package com.dayou.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.configuration.BaseEntity;
+import com.dayou.dao.ProfessorResultMapper;
+import com.dayou.entity.ProfessorResult;
+import com.dayou.entity.QuestionAnalysis;
+import com.dayou.service.IProfessorResultService;
+import com.dayou.service.IQuestionAnalysisService;
+import com.dayou.service.websocket.WebSocketServer;
+import com.dayou.vo.DocumentCycleVO;
+import com.dayou.vo.ProfessorResultVO;
+import com.dayou.vo.QuestionVO;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class ProfessorResultServiceImpl extends ServiceImpl<ProfessorResultMapper, ProfessorResult> implements IProfessorResultService {
+
+    @Autowired
+    private ProfessorResultMapper professorResultMapper;
+
+    @Autowired
+    private IQuestionAnalysisService questionAnalysisService;
+
+    @Autowired
+    private WebSocketServer webSocketServer;
+
+    @Transactional
+    @Override
+    public synchronized Boolean commitDocument(DocumentCycleVO documentCycleVO) {
+        List<QuestionVO> questions = documentCycleVO.getQuestions();
+        String professorNo = documentCycleVO.getProfessorNo();
+        Long cycleId = documentCycleVO.getId();
+
+        List<ProfessorResult> list = this.list(new LambdaQueryWrapper<ProfessorResult>()
+                .eq(ProfessorResult::getCycleId, cycleId).eq(ProfessorResult::getProfessorNo, professorNo).eq(BaseEntity::getDeleted, Boolean.FALSE));
+        if (CollectionUtils.isEmpty(list)){
+            List<ProfessorResult> collect = questions.stream().map(x -> {
+                ProfessorResult professorResult = new ProfessorResult();
+                professorResult.setProfessorNo(professorNo);
+                professorResult.setScore(x.getScore());
+                professorResult.setCycleId(cycleId);
+                professorResult.setQuestionId(x.getId());
+                return professorResult;
+            }).collect(Collectors.toList());
+            this.saveBatch(collect);
+        }
+        else {
+            for (QuestionVO questionVO : questions){
+                for (ProfessorResult professorResult :list){
+                    if (professorResult.getQuestionId().equals(questionVO.getId())){
+                        professorResult.setScore(questionVO.getScore());
+                    }
+                }
+            }
+            this.updateBatchById(list);
+        }
+
+        List<Long> questionIds = questions.stream().map(QuestionVO::getId).collect(Collectors.toList());
+        analysisScore(cycleId,questionIds);
+        webSocketServer.sendSocket("data");
+        return Boolean.TRUE;
+    }
+
+    @Override
+    public List<ProfessorResultVO> getResultList() {
+        List<ProfessorResultVO> list = professorResultMapper.getResultList();
+        return list;
+    }
+
+    @Override
+    public List<ProfessorResultVO> getResultByCycleId(Long id) {
+        List<ProfessorResultVO> list = professorResultMapper.getResultByCycleId(id);
+        return list;
+    }
+
+    @Override
+    public boolean removeScore(Long id) {
+        ProfessorResult pr = this.getById(id);
+        this.removeById(id);
+        Long cycleId = pr.getCycleId();
+        Long questionId = pr.getQuestionId();
+        List<QuestionAnalysis> avgScores = professorResultMapper.getAvgScore(cycleId,questionId);
+        return questionAnalysisService.saveOrUpdateBatch(avgScores);
+    }
+
+    private Boolean analysisScore(Long cycleId,List<Long> questionIds){
+        for (Long questionId : questionIds){
+            List<QuestionAnalysis> avgScores = professorResultMapper.getAvgScore(cycleId,questionId);
+            questionAnalysisService.saveOrUpdateBatch(avgScores);
+        }
+        return Boolean.TRUE;
+    }
+}

+ 35 - 0
src/main/java/com/dayou/service/impl/QuestionAnalysisServiceImpl.java

@@ -0,0 +1,35 @@
+package com.dayou.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.dao.QuestionAnalysisMapper;
+import com.dayou.entity.QuestionAnalysis;
+import com.dayou.service.IQuestionAnalysisService;
+import com.dayou.vo.AnalysisResultVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class QuestionAnalysisServiceImpl extends ServiceImpl<QuestionAnalysisMapper, QuestionAnalysis> implements IQuestionAnalysisService {
+
+    @Autowired
+    private QuestionAnalysisMapper questionAnalysisMapper;
+
+    @Override
+    public List<AnalysisResultVO> getAnalysisList() {
+        return questionAnalysisMapper.getAnalysisList();
+    }
+
+    @Override
+    public List<AnalysisResultVO> getAnalysisListByCycleId(Long id) {
+        return questionAnalysisMapper.getAnalysisListByCycleId(id);
+    }
+}

+ 18 - 0
src/main/java/com/dayou/service/impl/QuestionServiceImpl.java

@@ -0,0 +1,18 @@
+package com.dayou.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.dao.QuestionMapper;
+import com.dayou.entity.Question;
+import com.dayou.service.IQuestionService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {
+}

+ 67 - 0
src/main/java/com/dayou/service/impl/UserServiceImpl.java

@@ -0,0 +1,67 @@
+package com.dayou.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayou.configuration.BaseEntity;
+import com.dayou.configuration.ErrorCode;
+import com.dayou.dao.UserMapper;
+import com.dayou.dto.LoginDTO;
+import com.dayou.dto.UserDTO;
+import com.dayou.entity.User;
+import com.dayou.service.IUserService;
+import com.dayou.utils.JwtTokenUtil;
+import com.dayou.utils.LoginContext;
+import com.google.common.cache.Cache;
+import com.google.common.collect.Maps;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+@Service
+public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
+
+    @Autowired
+    @Qualifier("loginCache")
+    private Cache<Long,User> loginCache;
+
+    @Override
+    public LoginDTO login(UserDTO userDTO) {
+        String account = userDTO.getAccount();
+        String password = userDTO.getPassword();
+
+        User user = checkUser(account,password);
+
+        HashMap<String, Object> claims = Maps.newHashMap();
+
+        String token = JwtTokenUtil.doGenerateToken(claims, String.valueOf(user.getId()));
+
+        cacheUserLoginInfo(user);
+        return LoginDTO.builder().token(token).build();
+    }
+
+    private void cacheUserLoginInfo(User user) {
+        loginCache.put(user.getId(),user);
+        LoginContext.setUser(user);
+    }
+
+    private User checkUser(String account, String password) {
+        User user = this.getOne(new LambdaQueryWrapper<User>()
+                .eq(User::getAccount, account)
+                .eq(User::getPassword, password)
+                .eq(BaseEntity::getDeleted,Boolean.FALSE));
+
+        if (user == null){
+            ErrorCode.throwBusinessException(ErrorCode.PWD_ERROR);
+        }
+        return user;
+    }
+}

+ 29 - 0
src/main/java/com/dayou/service/websocket/WebSocketConfig.java

@@ -0,0 +1,29 @@
+package com.dayou.service.websocket;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+import javax.websocket.ClientEndpointConfig;
+import javax.websocket.server.ServerEndpointConfig;
+
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Configuration
+public class WebSocketConfig extends ServerEndpointConfig.Configurator {
+    /**
+     * 注入ServerEndpointExporter,@Bean会自动注册使用@ServerEndpoint注解声明的websocket端点endpoint
+     * @return
+     */
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter(){
+        return new ServerEndpointExporter();
+    }
+}
+

+ 100 - 0
src/main/java/com/dayou/service/websocket/WebSocketServer.java

@@ -0,0 +1,100 @@
+package com.dayou.service.websocket;
+
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Component
+@ServerEndpoint(value="/ws",configurator = WebSocketConfig.class)
+public class WebSocketServer {
+    private static AtomicInteger atomicInteger = new AtomicInteger(0);
+
+    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
+
+    private Session session;
+
+    private static final String MSG = "{\"data\":\"*\"}";
+
+    /**
+     * 连接建立成功调用的方法
+     * @param session
+     */
+    @OnOpen
+    public void onOpen(Session session){
+        atomicInteger.incrementAndGet();
+        String sessionId = session.getId();
+        this.session = session;
+        System.out.println("建立连接成功 onOpen 线程数量:"+atomicInteger.get()+" sessionID:"+ session.getId());
+        System.out.println("当前socket连接数量:" + webSocketMap.size());
+        webSocketMap.put(sessionId,this);
+        sendSocket("userSize");
+    }
+
+    /**
+     * 连接关闭调用的方法
+     * @param session
+     */
+    @OnClose
+    public void onClose(Session session){
+        System.out.println("一个客户端断开连接:" + session.getId());
+        atomicInteger.incrementAndGet();
+        webSocketMap.remove(session.getId());
+        sendSocket("userSize");
+
+    }
+
+    /**
+     * 接收到客户端消息后调用的方法
+     * @param msg 客户端发送的消息
+     * @param session
+     */
+    @OnMessage
+    public void onMessage(String msg, Session session) throws IOException {
+        atomicInteger.incrementAndGet();
+        System.out.println("接收到客户端发送的消息 onMessage:"+ msg+" 线程数量:"+atomicInteger.get()+" sessionID:"+session.getId());
+        session.getBasicRemote().sendText(msg);
+    }
+
+    /**
+     * 出现错误时调用的方法
+     * @param session
+     * @param throwable
+     */
+    @OnError
+    public void onError(Session session, Throwable throwable){
+        atomicInteger.incrementAndGet();
+        System.out.println("错误 onError 线程数量:"+atomicInteger.get()+" sessionID:"+session.getId());
+        throwable.printStackTrace();
+    }
+
+    public void sendSocket(String key){
+        System.out.println("sessions:"+webSocketMap.size());
+        if (webSocketMap.size()>0){
+            for(Map.Entry<String, WebSocketServer> map : webSocketMap.entrySet()){
+                try {
+                    if (key.equals("data")){
+                        map.getValue().session.getBasicRemote().sendText(MSG);
+                    }
+                    else {
+                        String userSize = "{\"userSize\":"+webSocketMap.size()+"}";
+                        map.getValue().session.getBasicRemote().sendText(userSize);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}

+ 168 - 0
src/main/java/com/dayou/utils/ConvertUtil.java

@@ -0,0 +1,168 @@
+package com.dayou.utils;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.dozer.DozerBeanMapper;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 类说明:类型转换器 包括VO DTO entity间的转化
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+public class ConvertUtil {
+
+    //对象转换核心实例
+    private final static DozerBeanMapper dozer = new DozerBeanMapper() {
+    };
+
+    private ConvertUtil() {
+    }
+
+    /**
+     * 将src对象中的属性值复制到desc对象的同名属性中
+     *
+     * @param src  源
+     * @param desc 目标
+     */
+    public static void copyProperties(Object src, Object desc) {
+        if (src == null || desc == null) {
+            throw new IllegalArgumentException("param must not be null");
+        }
+        dozer.map(src, desc);
+    }
+
+    /**
+     * 将src对象中的属性值复制到新建的desc对象的同名属性中
+     *
+     * @param src       源
+     * @param descClass
+     * @return 结果
+     */
+    public static <T> T copyProperties(Object src, Class<T> descClass) {
+        if (src == null || descClass == null) {
+            throw new IllegalArgumentException("param must not be null");
+        }
+        return (T) dozer.map(src, descClass);
+    }
+
+    /**
+     * 将srcList中的元素复制到元素类型为descClass的List集合中
+     *
+     * @param srcList   源
+     * @param descClass
+     * @return 结果
+     */
+    public static <T> List<T> copyList(@SuppressWarnings("rawtypes") List srcList, Class<T> descClass) {
+        if (CollectionUtils.isEmpty(srcList)) {
+            return Collections.EMPTY_LIST;
+        }
+        if (srcList == null || descClass == null) {
+            throw new IllegalArgumentException("param must not be null");
+        }
+        List<T> descList = new ArrayList<T>();
+        if (srcList != null) {
+            for (Object obj : srcList) {
+                T t = copyProperties(obj, descClass);
+                descList.add(t);
+            }
+        }
+        return descList;
+    }
+
+    /**
+     * 转换为字符串<br>
+     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
+     * 转换失败不会报错
+     *
+     * @param value 被转换的值
+     * @return 结果
+     */
+    public static String toStr(Object value) {
+        return toStr(value, null);
+    }
+
+    /**
+     * 转换为字符串<br>
+     * 如果给定的值为null,或者转换失败,返回默认值<br>
+     * 转换失败不会报错
+     *
+     * @param value        被转换的值
+     * @param defaultValue 转换错误时的默认值
+     * @return 结果
+     */
+    public static String toStr(Object value, String defaultValue) {
+        if (null == value) {
+            return defaultValue;
+        }
+        if (value instanceof String) {
+            return (String) value;
+        }
+        return value.toString();
+    }
+
+    /*    *//**
+     * 将srcList中的元素复制到元素类型为descClass的List集合中
+     *
+     * @param srcList 源
+     * @return 结果
+     *//*
+    public static void copyList(@SuppressWarnings("rawtypes") List srcList, List list) {
+        if (CollectionUtils.isEmpty(srcList)) {
+            return;
+        }
+        if (srcList == null || list == null) {
+            throw new IllegalArgumentException("param must not be null");
+        }
+        if (srcList != null) {
+            dozer.map(srcList, list);
+        }
+    }*/
+
+    /**
+     * 将srcList中的元素复制到元素类型为descClass的List集合中
+     *
+     * @param collections 源
+     * @param descClass
+     * @return 结果
+     */
+    public static <T> Set<T> copySet(@SuppressWarnings("rawtypes") Collection collections, Class<T> descClass) {
+        if (descClass == null) {
+            throw new IllegalArgumentException("param must not be null");
+        }
+        Set<T> descSet = new HashSet<>();
+        if (collections != null) {
+            for (Object obj : collections) {
+                T t = copyProperties(obj, descClass);
+                descSet.add(t);
+            }
+        }
+        return descSet;
+    }
+
+    public static void copySet(@SuppressWarnings("rawtypes") Collection collections, Set set) {
+        if (set == null) {
+            throw new IllegalArgumentException("param must not be null");
+        }
+        if (collections != null) {
+            dozer.map(collections, set);
+        }
+    }
+
+    public static <T, S> T copyBean(S s, Convertor<S, T> convertor) {
+        return convertor.convert(s);
+    }
+
+    public static <T, S> List<T> copyList(List<S> sourceList, Convertor<S, T> convertor) {
+        if (CollectionUtils.isEmpty(sourceList)) {
+            return Collections.EMPTY_LIST;
+        }
+
+        List<T> targetList = sourceList.stream().map(x -> copyBean(x, convertor)).collect(Collectors.toList());
+        return targetList;
+    }
+
+}

+ 12 - 0
src/main/java/com/dayou/utils/Convertor.java

@@ -0,0 +1,12 @@
+package com.dayou.utils;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2022/11/28
+ * created with IntelliJ IDEA.
+ */
+public interface Convertor<S,T> {
+    T convert(S s);
+}

+ 196 - 0
src/main/java/com/dayou/utils/JwtTokenUtil.java

@@ -0,0 +1,196 @@
+package com.dayou.utils;
+
+import cn.hutool.core.util.RandomUtil;
+import com.dayou.configuration.JwtConstants;
+import com.dayou.configuration.ErrorCode;
+import io.jsonwebtoken.*;
+import io.jsonwebtoken.impl.DefaultClaims;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>jwt token工具类</p>
+ * <pre>
+ *     jwt的claim里一般包含以下几种数据:
+ *         1. iss -- token的发行者
+ *         2. sub -- 该JWT所面向的用户
+ *         3. aud -- 接收该JWT的一方
+ *         4. exp -- token的失效时间
+ *         5. nbf -- 在此时间段之前,不会被处理
+ *         6. iat -- jwt发布时间
+ *         7. jti -- jwt唯一标识,防止重复使用
+ * </pre>
+ *
+ * @author wucl
+ * @Date 2017/8/25 10:59
+ */
+@Component
+public class JwtTokenUtil {
+
+    /**
+     * 获取用户名从token中
+     */
+    public static String getUsernameFromToken(String token) {
+        return getClaimFromToken(token).getSubject();
+    }
+
+    /**
+     * 获取jwt发布时间
+     */
+    public static Date getIssuedAtDateFromToken(String token) {
+        return getClaimFromToken(token).getIssuedAt();
+    }
+
+    /**
+     * 获取jwt失效时间
+     */
+    public static Date getExpirationDateFromToken(String token) {
+        return getClaimFromToken(token).getExpiration();
+    }
+
+    /**
+     * 获取jwt接收者
+     */
+    public static String getAudienceFromToken(String token) {
+        return getClaimFromToken(token).getAudience();
+    }
+
+    /**
+     * 获取私有的jwt claim
+     */
+    public static String getPrivateClaimFromToken(String token, String key) {
+        return getClaimFromToken(token).get(key).toString();
+    }
+
+
+    /**
+     * 获取jwt的payload部分
+     */
+    public static Claims getClaimFromToken(String token, String signKey) {
+        Claims claims = null;
+        try {
+            claims = Jwts.parser()
+                    .setSigningKey(signKey)
+                    .parseClaimsJws(token)
+                    .getBody();
+        } catch (SignatureException e) {
+            ErrorCode.throwBusinessException(ErrorCode.LOGIN_EXPIRE);
+        }
+        return claims;
+    }
+
+    /**
+     * 获取jwt的payload部分
+     */
+    public static Claims getClaimFromToken(String token) {
+        return getClaimFromToken(token, JwtConstants.SECRET);
+    }
+
+    /**
+     * 解析token是否正确,不正确会报异常<br>
+     */
+    public static void parseToken(String token) throws JwtException {
+        Jwts.parser().setSigningKey(JwtConstants.SECRET).parseClaimsJws(token).getBody();
+    }
+
+    /**
+     * <pre>
+     *  验证token是否失效
+     *  true:过期   false:没过期
+     * </pre>
+     */
+    public static Boolean isTokenExpired(String token) {
+        try {
+            final Date expiration = getExpirationDateFromToken(token);
+            return expiration.before(new Date());
+        } catch (ExpiredJwtException expiredJwtException) {
+            return true;
+        }
+    }
+
+    public static Boolean isTokenExpired(Claims claims) {
+        Date expiredDate = claims.getExpiration();
+        return expiredDate.getTime() < System.currentTimeMillis();
+    }
+
+    /**
+     * 生成token(通过用户名和签名时候用的随机数)
+     */
+    public static String generateToken(String userId) {
+        Map<String, Object> claims = new HashMap<>();
+        return doGenerateToken(claims, userId);
+    }
+
+    /**
+     * 生成token
+     */
+    public static String doGenerateToken(Map<String, Object> claims, String subject) {
+        final Date createdDate = new Date();
+        final Date expirationDate = new Date(createdDate.getTime() + JwtConstants.EXPIRATION * 1000);
+
+        return Jwts.builder()
+                .setClaims(claims)
+                .setSubject(subject)
+                .setIssuedAt(createdDate)
+                .setExpiration(expirationDate)
+                .signWith(SignatureAlgorithm.HS512, JwtConstants.SECRET)
+                .compact();
+    }
+
+    /**
+     * 生成token
+     */
+    public static String generateTokenForOAuth(Map<String, Object> claims, String subject) {
+        final Date createdDate = new Date();
+        final Date expirationDate = new Date(createdDate.getTime() + JwtConstants.EXPIRATION * 1000);
+
+        return Jwts.builder()
+                .setClaims(claims)
+                .setSubject(subject)
+                .setIssuedAt(createdDate)
+                .setExpiration(expirationDate)
+                .signWith(SignatureAlgorithm.HS512, JwtConstants.SECRET_OAUTH)
+                .compact();
+    }
+
+    /**
+     * 获取混淆MD5签名用的随机字符串
+     */
+    public static String getRandomKey() {
+        return RandomUtil.randomString(6);
+    }
+
+
+    public static String generateToken(Long userId, long tokenExpireDate) {
+        Date createdDate = new Date();
+        Date expirationDate = new Date(createdDate.getTime() + tokenExpireDate);
+        Claims claims = new DefaultClaims();
+        return Jwts.builder()
+                .setClaims(claims)
+                .setSubject(String.valueOf(userId))
+                .setIssuedAt(createdDate)
+                .setExpiration(expirationDate)
+                .signWith(SignatureAlgorithm.HS512, JwtConstants.SECRET)
+                .compact();
+
+    }
+
+    public static String generateTokenForYN(String secretKey, long tokenExpireDate) {
+        Date createdDate = new Date();
+        Date expirationDate = new Date(createdDate.getTime() + tokenExpireDate);
+        Claims claims = new DefaultClaims();
+        return Jwts.builder()
+                .setClaims(claims)
+                .setSubject(secretKey)
+                .setIssuedAt(createdDate)
+                .setExpiration(expirationDate)
+                .signWith(SignatureAlgorithm.HS512, JwtConstants.SECRET)
+                .compact();
+
+    }
+
+
+}

+ 29 - 0
src/main/java/com/dayou/utils/LoginContext.java

@@ -0,0 +1,29 @@
+package com.dayou.utils;
+
+import com.dayou.entity.User;
+
+import java.util.Optional;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/12
+ * created with IntelliJ IDEA.
+ */
+public class LoginContext {
+
+    private static final ThreadLocal<User> loginThreadLocal = new ThreadLocal<>();
+
+    public static void setUser(User  user){
+        loginThreadLocal.set(user);
+    }
+
+    public static User getCurrentUser(){
+        return Optional.ofNullable(loginThreadLocal.get()).orElseGet(User::new);
+    }
+
+    public static void removeAll() {
+        loginThreadLocal.remove();
+    }
+}

+ 32 - 0
src/main/java/com/dayou/vo/AnalysisResultVO.java

@@ -0,0 +1,32 @@
+package com.dayou.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class AnalysisResultVO {
+
+    private Long documentId;
+
+    private Long cycleId;
+
+    private String itemName;
+
+    private String scope;
+
+    private String cycleName;
+
+    private Long questionId;
+
+    private String questionName;
+
+    private BigDecimal avgScore;
+}

+ 30 - 0
src/main/java/com/dayou/vo/CycleVO.java

@@ -0,0 +1,30 @@
+package com.dayou.vo;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class CycleVO {
+
+    private Long id;
+
+    private Long documentId;
+
+    private String cycleName;
+
+    private String itemName;
+
+    private String type;
+
+    private String scope;
+
+    private LocalDateTime created;
+}

+ 39 - 0
src/main/java/com/dayou/vo/DocumentCycleVO.java

@@ -0,0 +1,39 @@
+package com.dayou.vo;
+
+import com.github.liangbaika.validate.annations.AbcValidate;
+import com.github.liangbaika.validate.enums.Check;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class DocumentCycleVO {
+
+    private Long id;
+
+    private Long documentId;
+
+    private String cycleName;
+
+    private String itemName;
+
+    private String type;
+
+    private String scope;
+
+    private List<QuestionVO> questions;
+
+    private LocalDateTime created;
+
+    @AbcValidate(required = true,message = "专家编号不能为空",fun = Check.NotEmpty)
+    private String professorNo;
+}

+ 31 - 0
src/main/java/com/dayou/vo/DocumentVO.java

@@ -0,0 +1,31 @@
+package com.dayou.vo;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class DocumentVO {
+
+    private Long id;
+
+    private String itemName;
+
+    private String scope;
+
+    private String type;
+
+    private List<QuestionVO> questions;
+
+    private LocalDateTime created;
+
+}

+ 22 - 0
src/main/java/com/dayou/vo/LabelKeyVO.java

@@ -0,0 +1,22 @@
+package com.dayou.vo;
+
+import lombok.Data;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/20
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class LabelKeyVO {
+
+    private Long id;
+
+    private String name;
+
+    private Long key;
+
+    private String label;
+}

+ 42 - 0
src/main/java/com/dayou/vo/ProfessorResultVO.java

@@ -0,0 +1,42 @@
+package com.dayou.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/19
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class ProfessorResultVO {
+
+    private Long id;
+
+    private Long cycleId;
+
+    private String cycleName;
+
+    private Long documentId;
+
+    private String itemName;
+
+    private String scope;
+
+    private String type;
+
+    private Long questionId;
+
+    private String questionName;
+
+    private String professorNo;
+
+    private BigDecimal score;
+
+    private LocalDateTime created;
+}

+ 27 - 0
src/main/java/com/dayou/vo/QuestionVO.java

@@ -0,0 +1,27 @@
+package com.dayou.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 类说明:
+ *
+ * @author: wucl
+ * @since: 2023/7/13
+ * created with IntelliJ IDEA.
+ */
+@Data
+public class QuestionVO {
+
+    private Long id;
+
+    private String name;
+
+    private BigDecimal score;
+
+    private LocalDateTime created;
+}

+ 26 - 0
src/main/resources/application-local.yml

@@ -0,0 +1,26 @@
+server:
+  port: 8090
+
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:3306/kps?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
+    username: root
+    password: 914851221
+    initialSize: 10 #初始化连接数D
+    minIdle: 10 #最小空闲连接数
+    max-active: 100 #最大连接数
+    maxWait: 60000 #最大等待时间ms(获取不到连接后多久超时)
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 200
+      connection-timeout: 30000
+      idle-timeout: 600000
+      max-lifetime: 1800000
+
+
+
+
+
+
+
+

+ 21 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,21 @@
+server:
+  port: 8090
+
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:1230/kps?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true
+    username: root
+    password: Dypg@1996
+    initialSize: 10 #初始化连接数
+    minIdle: 10 #最小空闲连接数
+    max-active: 100 #最大连接数
+    maxWait: 60000 #最大等待时间ms(获取不到连接后多久超时)
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 200
+      connection-timeout: 30000
+      idle-timeout: 600000
+      max-lifetime: 1800000
+
+
+

+ 21 - 0
src/main/resources/application-test.yml

@@ -0,0 +1,21 @@
+server:
+  port: 8089
+
+spring:
+  datasource:
+    url: jdbc:mysql://47.108.172.52:1230/kps?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&characterEncoding=UTF-8&nullCatalogMeansCurrent=true
+    username: root
+    password: Dypg@1996
+    initialSize: 10 #初始化连接数
+    minIdle: 10 #最小空闲连接数
+    max-active: 100 #最大连接数
+    maxWait: 60000 #最大等待时间ms(获取不到连接后多久超时)
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 200
+      connection-timeout: 30000
+      idle-timeout: 600000
+      max-lifetime: 1800000
+
+
+

+ 79 - 0
src/main/resources/application.yml

@@ -0,0 +1,79 @@
+spring:
+  profiles:
+    active: "@spring.active@"
+  mvc:
+    format:
+      date: yyyy-MM-dd HH:mm:ss
+    throw-exception-if-no-handler-found: true
+  application:
+    name: kps-phase
+  devtools:
+    livereload:
+      enabled: true
+      port: 9257
+    restart:
+      enabled: false
+  main:
+    allow-bean-definition-overriding: true
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+    default-property-inclusion: always
+
+  servlet:
+    multipart:
+      maxFileSize: 50MB  #单位必须大写MB或不写(即为B)
+      maxRequestSize: 100MB
+
+
+  resources:
+    add-mappings: false
+## MyBatis
+#mybatis:
+#  # 搜索指定包别名
+#  typeAliasesPackage: com.wucl.bike
+#  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+#  mapperLocations: classpath*:mapper/**/*Mapper.xml
+mybatis-plus:
+  mapper-locations: classpath*:mapper/**/*Mapper.xml
+  type-aliases-package: com.dayou.entity
+  #debug
+  configuration:
+#关闭:org.apache.ibatis.logging.nologging.NoLoggingImpl    开启:org.apache.ibatis.logging.stdout.StdOutImpl
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      id-type: auto
+      logic-delete-field: deleted
+      logic-delete-value: 1
+      logic-not-delete-value: 0
+mapper:
+  not-empty: true
+  identity: MYSQL
+
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  reasonable: true
+  supportMethodsArguments: true
+  params: count=countSql
+server:
+  servlet:
+    context-path: /apo
+  compression:
+    enabled: true
+    mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
+    min-response-size: 1024
+  tomcat:
+    max-connections: 1000
+    threads:
+      min-spare: 20
+      max: 200
+    accept-count: 200
+
+# 日志配置
+logging:
+  level:
+    com.local: info
+    org.springframework: info
+

+ 42 - 0
src/main/resources/mapper/AnalysisResultMapper.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dayou.dao.QuestionAnalysisMapper">
+
+    <select id="getAnalysisList" resultType="com.dayou.vo.AnalysisResultVO">
+        SELECT
+            t.id AS cycle_id,
+            qa.question_id,
+            t.cycle_name,
+            q.NAME AS questionName,
+            d.item_name,
+            d.scope,
+            qa.avg_score,
+            t.document_id
+        FROM
+            question_analysis qa
+                RIGHT JOIN ( SELECT id, document_id, cycle_name FROM cycle ORDER BY created DESC LIMIT 1 ) t ON t.id = qa.cycle_id
+                LEFT JOIN question q ON q.id = qa.question_id
+                LEFT JOIN document d ON d.id = t.document_id
+        ORDER BY
+            q.created
+    </select>
+
+    <select id="getAnalysisListByCycleId" parameterType="java.lang.Long" resultType="com.dayou.vo.AnalysisResultVO">
+        SELECT
+            t.id AS cycle_id,
+            qa.question_id,
+            t.cycle_name,
+            q.NAME AS questionName,
+            d.item_name,
+            d.scope,
+            qa.avg_score,
+            t.document_id
+        FROM
+            question_analysis qa
+                RIGHT JOIN ( SELECT id, document_id, cycle_name FROM cycle where id = #{id} ) t ON t.id = qa.cycle_id
+                LEFT JOIN question q ON q.id = qa.question_id
+                LEFT JOIN document d ON d.id = t.document_id
+        ORDER BY
+            q.created
+    </select>
+</mapper>

+ 29 - 0
src/main/resources/mapper/CycleMapper.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dayou.dao.CycleMapper">
+
+    <select id="getPage" parameterType="com.dayou.vo.CycleVO" resultType="com.dayou.vo.CycleVO">
+        SELECT
+            c.id,
+            d.id as documentId,
+            d.item_name,
+            d.scope,
+            d.type,
+            c.cycle_name,
+            c.created
+        FROM
+            cycle c
+                LEFT JOIN document d ON d.id = c.document_id
+            <where>
+                c.deleted = 0 and d.deleted = 0
+                <if test="cycle!=null and cycle.itemName!=null and cycle.itemName!='' ">
+                    and d.item_name like concat('%',#{cycle.itemName},'%')
+                </if>
+                <if test="cycle!=null and cycle.cycleName!=null and cycle.cycleName!='' ">
+                    and c.cycle_name like concat('%',#{cycle.cycleName},'%')
+                </if>
+            </where>
+        order by c.created DESC
+    </select>
+
+</mapper>

+ 54 - 0
src/main/resources/mapper/DocumentMapper.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dayou.dao.DocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="documentCycleMap" type="com.dayou.vo.DocumentCycleVO">
+        <result column="id" property="id" />
+        <result column="document_id" property="documentId" />
+        <result column="cycle_name" property="cycleName" />
+        <result column="scope" property="scope" />
+        <result column="type" property="type" />
+        <result column="item_name" property="itemName" />
+        <result column="created" property="created" />
+        <collection property="questions"  ofType="com.dayou.vo.QuestionVO" select="selectQuestion" column="document_id"/>
+    </resultMap>
+
+    <resultMap id="documentMap" type="com.dayou.vo.DocumentVO">
+        <result column="id" property="id" />
+        <result column="item_name" property="itemName" />
+        <result column="scope" property="scope" />
+        <result column="type" property="type" />
+        <result column="created" property="created" />
+        <collection property="questions"  ofType="com.dayou.vo.QuestionVO" select="selectQuestion" column="id"/>
+    </resultMap>
+
+
+    <select id="getDocumentCycleVO" resultMap="documentCycleMap">
+        SELECT
+            d.item_name,
+            d.scope,
+            d.type,
+            t.cycle_name,
+            d.id AS document_id,
+            t.id,
+            t.created
+        FROM
+            document d
+                RIGHT JOIN ( SELECT id, document_id, cycle_name, created FROM cycle WHERE deleted = 0 ORDER BY created DESC LIMIT 1 ) t ON t.document_id = d.id
+        WHERE
+            d.deleted = 0
+    </select>
+    
+    <select id="selectQuestion" parameterType="java.lang.Long" resultType="com.dayou.vo.QuestionVO">
+        select q.id,q.name,q.created from document_question dq left join question q on q.id = dq.question_id where dq.document_id = #{id} and dq.deleted = 0 and q.deleted = 0
+    </select>
+
+    <select id="getPage" parameterType="com.dayou.vo.DocumentVO" resultMap="documentMap">
+        select id,item_name,type,scope,created from document where  deleted = 0
+        <if test="document!=null and document.itemName!=null and document.itemName!='' ">
+            and item_name like concat ('%',#{document.itemName},'%')
+        </if>
+        order by created DESC
+    </select>
+</mapper>

+ 64 - 0
src/main/resources/mapper/ProfessorResultMapper.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.dayou.dao.ProfessorResultMapper">
+
+    <select id="getAvgScore" resultType="com.dayou.entity.QuestionAnalysis">
+        SELECT
+            qa.id,
+            t.cycle_id,
+            t.question_id,
+            t.avg_score,
+            qa.created,
+            qa.deleted,
+            qa.modified
+        FROM
+            question_analysis qa
+                RIGHT JOIN ( SELECT cycle_id, question_id, avg( score ) AS avg_score FROM professor_result WHERE cycle_id = #{cycleId} AND deleted = 0 GROUP BY question_id ) t ON qa.cycle_id = t.cycle_id
+                AND qa.question_id = t.question_id
+    </select>
+
+
+    <select id="getResultList" resultType="com.dayou.vo.ProfessorResultVO">
+        SELECT
+            pr.professor_no,
+            pr.score,
+            t.id AS cycle_id,
+            pr.question_id,
+            t.cycle_name,
+            q.NAME AS questionName,
+            d.item_name,
+            d.scope,
+            d.type,
+            pr.created,
+            t.document_id
+        FROM
+            professor_result pr
+                RIGHT JOIN ( SELECT id, document_id, cycle_name FROM cycle ORDER BY created DESC LIMIT 1 ) t ON t.id = pr.cycle_id
+                LEFT JOIN question q ON q.id = pr.question_id
+                LEFT JOIN document d ON d.id = t.document_id
+        where pr.deleted = 0
+        order by pr.created DESC
+    </select>
+
+    <select id="getResultByCycleId" parameterType="java.lang.Long" resultType="com.dayou.vo.ProfessorResultVO">
+        SELECT
+            pr.id,
+            pr.professor_no,
+            pr.score,
+            t.id AS cycle_id,
+            pr.question_id,
+            t.cycle_name,
+            q.NAME AS questionName,
+            d.item_name,
+            d.scope,
+            pr.created,
+            t.document_id
+        FROM
+            professor_result pr
+                RIGHT JOIN ( SELECT id, document_id, cycle_name FROM cycle where id = #{id} ) t ON t.id = pr.cycle_id
+                LEFT JOIN question q ON q.id = pr.question_id
+                LEFT JOIN document d ON d.id = t.document_id
+        where pr.deleted = 0
+        order by pr.created DESC
+    </select>
+</mapper>