commit 97f1ac93cf55b82120d7a9064f4ae2b88c578d64
Author: chx <2035634377@qq.com>
Date: Wed Dec 25 11:51:09 2024 +0800
整合学生端,教师端,管理员端的前后端代码
diff --git a/ExamSphere/.gitignore b/ExamSphere/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/ExamSphere/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar.zip b/ExamSphere/out/artifacts/ExamSphere_jar.zip
new file mode 100644
index 0000000..c55d030
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar.zip differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/ExamSphere.jar b/ExamSphere/out/artifacts/ExamSphere_jar/ExamSphere.jar
new file mode 100644
index 0000000..3bad18b
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/ExamSphere.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/HikariCP-4.0.3.jar b/ExamSphere/out/artifacts/ExamSphere_jar/HikariCP-4.0.3.jar
new file mode 100644
index 0000000..f328920
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/HikariCP-4.0.3.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/byte-buddy-1.11.22.jar b/ExamSphere/out/artifacts/ExamSphere_jar/byte-buddy-1.11.22.jar
new file mode 100644
index 0000000..e5fa216
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/byte-buddy-1.11.22.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/classmate-1.5.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/classmate-1.5.1.jar
new file mode 100644
index 0000000..819f5ea
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/classmate-1.5.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/commons-codec-1.15.jar b/ExamSphere/out/artifacts/ExamSphere_jar/commons-codec-1.15.jar
new file mode 100644
index 0000000..f14985a
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/commons-codec-1.15.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/commons-collections-3.2.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/commons-collections-3.2.1.jar
new file mode 100644
index 0000000..c35fa1f
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/commons-collections-3.2.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/commons-lang-2.4.jar b/ExamSphere/out/artifacts/ExamSphere_jar/commons-lang-2.4.jar
new file mode 100644
index 0000000..532939e
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/commons-lang-2.4.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/guava-20.0.jar b/ExamSphere/out/artifacts/ExamSphere_jar/guava-20.0.jar
new file mode 100644
index 0000000..632772f
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/guava-20.0.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/hutool-all-5.7.20.jar b/ExamSphere/out/artifacts/ExamSphere_jar/hutool-all-5.7.20.jar
new file mode 100644
index 0000000..c3de2cf
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/hutool-all-5.7.20.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jackson-annotations-2.13.4.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-annotations-2.13.4.jar
new file mode 100644
index 0000000..0c5e9c1
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-annotations-2.13.4.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jackson-core-2.13.4.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-core-2.13.4.jar
new file mode 100644
index 0000000..0cb7a37
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-core-2.13.4.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jackson-databind-2.13.4.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-databind-2.13.4.2.jar
new file mode 100644
index 0000000..5b653d6
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-databind-2.13.4.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jackson-datatype-jdk8-2.13.4.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-datatype-jdk8-2.13.4.jar
new file mode 100644
index 0000000..e98483e
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-datatype-jdk8-2.13.4.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jackson-datatype-jsr310-2.13.4.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-datatype-jsr310-2.13.4.jar
new file mode 100644
index 0000000..102cf12
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-datatype-jsr310-2.13.4.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jackson-module-parameter-names-2.13.4.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-module-parameter-names-2.13.4.jar
new file mode 100644
index 0000000..d3da4de
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jackson-module-parameter-names-2.13.4.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jakarta.annotation-api-1.3.5.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jakarta.annotation-api-1.3.5.jar
new file mode 100644
index 0000000..606d992
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jakarta.annotation-api-1.3.5.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/java-jwt-3.10.3.jar b/ExamSphere/out/artifacts/ExamSphere_jar/java-jwt-3.10.3.jar
new file mode 100644
index 0000000..4901b96
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/java-jwt-3.10.3.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/javassist-3.25.0-GA.jar b/ExamSphere/out/artifacts/ExamSphere_jar/javassist-3.25.0-GA.jar
new file mode 100644
index 0000000..bf8cf7b
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/javassist-3.25.0-GA.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jsqlparser-4.6.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jsqlparser-4.6.jar
new file mode 100644
index 0000000..9ad812a
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jsqlparser-4.6.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/jul-to-slf4j-1.7.36.jar b/ExamSphere/out/artifacts/ExamSphere_jar/jul-to-slf4j-1.7.36.jar
new file mode 100644
index 0000000..ae8f815
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/jul-to-slf4j-1.7.36.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/log4j-api-2.17.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/log4j-api-2.17.2.jar
new file mode 100644
index 0000000..16d9061
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/log4j-api-2.17.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/log4j-to-slf4j-2.17.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/log4j-to-slf4j-2.17.2.jar
new file mode 100644
index 0000000..d6c35f4
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/log4j-to-slf4j-2.17.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/logback-classic-1.2.11.jar b/ExamSphere/out/artifacts/ExamSphere_jar/logback-classic-1.2.11.jar
new file mode 100644
index 0000000..b70c0e6
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/logback-classic-1.2.11.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/logback-core-1.2.11.jar b/ExamSphere/out/artifacts/ExamSphere_jar/logback-core-1.2.11.jar
new file mode 100644
index 0000000..e3038da
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/logback-core-1.2.11.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/lombok-1.18.24.jar b/ExamSphere/out/artifacts/ExamSphere_jar/lombok-1.18.24.jar
new file mode 100644
index 0000000..3a985fe
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/lombok-1.18.24.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mapstruct-1.2.0.Final.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mapstruct-1.2.0.Final.jar
new file mode 100644
index 0000000..ab1265e
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mapstruct-1.2.0.Final.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-3.5.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-3.5.13.jar
new file mode 100644
index 0000000..c93a218
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-3.5.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-3.5.4.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-3.5.4.1.jar
new file mode 100644
index 0000000..4836543
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-3.5.4.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-annotation-3.5.4.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-annotation-3.5.4.1.jar
new file mode 100644
index 0000000..ac7cb27
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-annotation-3.5.4.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-boot-starter-3.5.4.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-boot-starter-3.5.4.1.jar
new file mode 100644
index 0000000..446459f
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-boot-starter-3.5.4.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-core-3.5.4.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-core-3.5.4.1.jar
new file mode 100644
index 0000000..7b6d2f3
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-core-3.5.4.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-extension-3.5.4.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-extension-3.5.4.1.jar
new file mode 100644
index 0000000..db52ac6
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-extension-3.5.4.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-generator-3.5.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-generator-3.5.1.jar
new file mode 100644
index 0000000..73173e3
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-generator-3.5.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-spring-boot-autoconfigure-3.5.4.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-spring-boot-autoconfigure-3.5.4.1.jar
new file mode 100644
index 0000000..34e9abf
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-plus-spring-boot-autoconfigure-3.5.4.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-spring-2.1.1.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-spring-2.1.1.jar
new file mode 100644
index 0000000..690550a
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mybatis-spring-2.1.1.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/mysql-connector-j-8.0.31.jar b/ExamSphere/out/artifacts/ExamSphere_jar/mysql-connector-j-8.0.31.jar
new file mode 100644
index 0000000..f9154ff
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/mysql-connector-j-8.0.31.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/slf4j-api-1.7.36.jar b/ExamSphere/out/artifacts/ExamSphere_jar/slf4j-api-1.7.36.jar
new file mode 100644
index 0000000..7d3ce68
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/slf4j-api-1.7.36.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/snakeyaml-1.29.jar b/ExamSphere/out/artifacts/ExamSphere_jar/snakeyaml-1.29.jar
new file mode 100644
index 0000000..b7db248
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/snakeyaml-1.29.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-aop-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-aop-5.3.23.jar
new file mode 100644
index 0000000..c7ee78d
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-aop-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-beans-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-beans-5.3.23.jar
new file mode 100644
index 0000000..fcc7cfd
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-beans-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-2.6.13.jar
new file mode 100644
index 0000000..527e48f
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-autoconfigure-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-autoconfigure-2.6.13.jar
new file mode 100644
index 0000000..e07146e
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-autoconfigure-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-devtools-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-devtools-2.6.13.jar
new file mode 100644
index 0000000..678bf89
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-devtools-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-2.6.13.jar
new file mode 100644
index 0000000..13c440d
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-jdbc-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-jdbc-2.6.13.jar
new file mode 100644
index 0000000..23eeed7
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-jdbc-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-json-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-json-2.6.13.jar
new file mode 100644
index 0000000..2e917db
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-json-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-logging-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-logging-2.6.13.jar
new file mode 100644
index 0000000..61a3890
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-logging-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-tomcat-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-tomcat-2.6.13.jar
new file mode 100644
index 0000000..4852133
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-tomcat-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-web-2.6.13.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-web-2.6.13.jar
new file mode 100644
index 0000000..a9fa5c6
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-boot-starter-web-2.6.13.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-context-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-context-5.3.23.jar
new file mode 100644
index 0000000..e80b5da
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-context-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-core-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-core-5.3.23.jar
new file mode 100644
index 0000000..78ff1ca
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-core-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-expression-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-expression-5.3.23.jar
new file mode 100644
index 0000000..3d10ece
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-expression-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-jcl-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-jcl-5.3.23.jar
new file mode 100644
index 0000000..98da8e2
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-jcl-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-jdbc-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-jdbc-5.3.23.jar
new file mode 100644
index 0000000..2322be7
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-jdbc-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-plugin-core-1.2.0.RELEASE.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-plugin-core-1.2.0.RELEASE.jar
new file mode 100644
index 0000000..c290363
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-plugin-core-1.2.0.RELEASE.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-plugin-metadata-1.2.0.RELEASE.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-plugin-metadata-1.2.0.RELEASE.jar
new file mode 100644
index 0000000..6eaa98c
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-plugin-metadata-1.2.0.RELEASE.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-tx-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-tx-5.3.23.jar
new file mode 100644
index 0000000..aad7465
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-tx-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-web-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-web-5.3.23.jar
new file mode 100644
index 0000000..790d148
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-web-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/spring-webmvc-5.3.23.jar b/ExamSphere/out/artifacts/ExamSphere_jar/spring-webmvc-5.3.23.jar
new file mode 100644
index 0000000..9a29a87
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/spring-webmvc-5.3.23.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-core-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-core-2.9.2.jar
new file mode 100644
index 0000000..c268979
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-core-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-schema-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-schema-2.9.2.jar
new file mode 100644
index 0000000..353ca0f
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-schema-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-spi-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-spi-2.9.2.jar
new file mode 100644
index 0000000..41de84e
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-spi-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-spring-web-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-spring-web-2.9.2.jar
new file mode 100644
index 0000000..5457d6a
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-spring-web-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger-common-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger-common-2.9.2.jar
new file mode 100644
index 0000000..77d18b5
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger-common-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger-ui-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger-ui-2.9.2.jar
new file mode 100644
index 0000000..ceaf502
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger-ui-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger2-2.9.2.jar b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger2-2.9.2.jar
new file mode 100644
index 0000000..8cac19e
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/springfox-swagger2-2.9.2.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/swagger-annotations-1.5.20.jar b/ExamSphere/out/artifacts/ExamSphere_jar/swagger-annotations-1.5.20.jar
new file mode 100644
index 0000000..dad5f4d
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/swagger-annotations-1.5.20.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/swagger-bootstrap-ui-1.9.6.jar b/ExamSphere/out/artifacts/ExamSphere_jar/swagger-bootstrap-ui-1.9.6.jar
new file mode 100644
index 0000000..3cc3032
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/swagger-bootstrap-ui-1.9.6.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/swagger-models-1.5.20.jar b/ExamSphere/out/artifacts/ExamSphere_jar/swagger-models-1.5.20.jar
new file mode 100644
index 0000000..9294d3b
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/swagger-models-1.5.20.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-core-9.0.68.jar b/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-core-9.0.68.jar
new file mode 100644
index 0000000..87dd471
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-core-9.0.68.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-el-9.0.68.jar b/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-el-9.0.68.jar
new file mode 100644
index 0000000..967746f
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-el-9.0.68.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-websocket-9.0.68.jar b/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-websocket-9.0.68.jar
new file mode 100644
index 0000000..38230eb
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/tomcat-embed-websocket-9.0.68.jar differ
diff --git a/ExamSphere/out/artifacts/ExamSphere_jar/velocity-1.7.jar b/ExamSphere/out/artifacts/ExamSphere_jar/velocity-1.7.jar
new file mode 100644
index 0000000..ae936d3
Binary files /dev/null and b/ExamSphere/out/artifacts/ExamSphere_jar/velocity-1.7.jar differ
diff --git a/ExamSphere/pom.xml b/ExamSphere/pom.xml
new file mode 100644
index 0000000..525a4fb
--- /dev/null
+++ b/ExamSphere/pom.xml
@@ -0,0 +1,167 @@
+
+
+ 4.0.0
+ com.exam
+ ExamSphere
+ 0.0.1-SNAPSHOT
+ ExamSphere
+ ExamSphere
+
+ 1.8
+ UTF-8
+ UTF-8
+ 2.6.13
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.baomidou
+ mybatis-plus-boot-starter
+ 3.5.4.1
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+ com.github.xiaoymin
+ swagger-bootstrap-ui
+ 1.9.6
+
+
+
+ com.baomidou
+ mybatis-plus-generator
+ 3.5.1
+
+
+ org.apache.velocity
+ velocity
+ 1.7
+
+
+ org.freemarker
+ freemarker
+ 2.3.30
+
+
+
+
+
+
+
+ com.auth0
+ java-jwt
+ 3.10.3
+
+
+
+ cn.hutool
+ hutool-all
+ 5.7.20
+
+
+ com.github.whvcse
+ easy-captcha
+ 1.6.2
+
+
+
+ org.mindrot
+ jbcrypt
+ 0.4
+
+
+
+ com.exam
+ ExamSphere
+ 0.0.1-SNAPSHOT
+
+
+ com.baomidou
+ mybatis-plus
+ 3.5.4.1
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ 2.6.13
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ com.exam.examsphere.ExamSphereApplication
+ true
+
+
+
+ repackage
+
+ repackage
+
+
+
+
+
+
+
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/ExamSphereApplication.java b/ExamSphere/src/main/java/com/exam/examsphere/ExamSphereApplication.java
new file mode 100644
index 0000000..b5c1bb5
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/ExamSphereApplication.java
@@ -0,0 +1,13 @@
+package com.exam.examsphere;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ExamSphereApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ExamSphereApplication.class, args);
+ }
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/common/Result.java b/ExamSphere/src/main/java/com/exam/examsphere/common/Result.java
new file mode 100644
index 0000000..562e353
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/common/Result.java
@@ -0,0 +1,29 @@
+package com.exam.examsphere.common;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Result {
+ private Integer code;
+ private String msg;
+ private Object data;
+ public static Result success() {
+ return new Result(200,"操作成功",null);
+ }
+ public static Result success(Object data) {
+ return new Result(200,"操作成功",data);
+ }
+ public static Result error(String msg) {
+ return new Result(500,msg,null);
+ }
+ public static Result error(Integer code, String msg) {
+ return new Result(code,msg,null);
+ }
+ public static Result error() {
+ return new Result(500,"系统错误,请联系管理员",null);
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/config/CaptureConfig.java b/ExamSphere/src/main/java/com/exam/examsphere/config/CaptureConfig.java
new file mode 100644
index 0000000..a82fc62
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/config/CaptureConfig.java
@@ -0,0 +1,12 @@
+package com.exam.examsphere.config;
+
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class CaptureConfig {
+ public static Map CAPTURE_MAP = new HashMap();
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/config/CorsConfig.java b/ExamSphere/src/main/java/com/exam/examsphere/config/CorsConfig.java
new file mode 100644
index 0000000..b970fcb
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/config/CorsConfig.java
@@ -0,0 +1,25 @@
+package com.exam.examsphere.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+@Configuration
+public class CorsConfig {
+ // 当前跨域请求最大有效时长。默认1天
+ private static final long MAX_AGE = 24 * 60 * 60;
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration corsConfiguration = new CorsConfiguration();
+ corsConfiguration.addAllowedOrigin("http://localhost:5173/"); // 1 设置访问源地址
+ corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
+ corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
+ corsConfiguration.setMaxAge(MAX_AGE);
+ source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
+ return new CorsFilter(source);
+ }
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/config/InterceptorConfig.java b/ExamSphere/src/main/java/com/exam/examsphere/config/InterceptorConfig.java
new file mode 100644
index 0000000..a16a345
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/config/InterceptorConfig.java
@@ -0,0 +1,23 @@
+// package com.exam.examsphere.config;
+//
+// import com.exam.examsphere.config.interceptor.JwtInterceptor;
+// import org.springframework.context.annotation.Bean;
+// import org.springframework.context.annotation.Configuration;
+// import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+// import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+// @Configuration
+//
+//
+// public class InterceptorConfig implements WebMvcConfigurer {
+// @Override
+// public void addInterceptors(InterceptorRegistry registry) {
+// registry.addInterceptor(jwtInterceptor())
+// .addPathPatterns("/**")//拦截所有请求,通过判断token是否合法决定是否需要登录
+// .excludePathPatterns("/user/login","/user/register","/doc.html","/swagger-resources/**","/captcha");
+// }
+//
+// @Bean
+// public JwtInterceptor jwtInterceptor() {
+// return new JwtInterceptor();
+// }
+// }
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/config/MybatisPlusConfig.java b/ExamSphere/src/main/java/com/exam/examsphere/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..a37041f
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/config/MybatisPlusConfig.java
@@ -0,0 +1,28 @@
+package com.exam.examsphere.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 阻止恶意的全表更新删除
+ */
+@Configuration
+public class MybatisPlusConfig {
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
+ return interceptor;
+ }
+
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor2() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+ return interceptor;
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/config/SwaggerConfig.java b/ExamSphere/src/main/java/com/exam/examsphere/config/SwaggerConfig.java
new file mode 100644
index 0000000..d164553
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/config/SwaggerConfig.java
@@ -0,0 +1,33 @@
+package com.exam.examsphere.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+ @Bean
+ public Docket docket() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("com.exam.examsphere.controller"))
+ .paths(PathSelectors.any())
+ .build().apiInfo(apiInfo());
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("ExamSphere在线考试系统")
+ .version("1.0")
+ .build();
+ }
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/config/interceptor/JwtInterceptor.java b/ExamSphere/src/main/java/com/exam/examsphere/config/interceptor/JwtInterceptor.java
new file mode 100644
index 0000000..e97f7d0
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/config/interceptor/JwtInterceptor.java
@@ -0,0 +1,61 @@
+package com.exam.examsphere.config.interceptor;
+
+import cn.hutool.core.util.StrUtil;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTVerificationException;
+
+import com.exam.examsphere.entity.User;
+import com.exam.examsphere.exception.ServiceException;
+import com.exam.examsphere.service.IUserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+@Slf4j
+@Component
+public class JwtInterceptor implements HandlerInterceptor {
+
+ @Autowired
+ private IUserService userService;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ String token = request.getHeader("token");
+ if(!(handler instanceof HandlerMethod)){
+ return true;
+ }
+ // 执行认证
+ if (StrUtil.isBlank(token)) {
+ throw new ServiceException("无token,请重新登录");
+ }
+ // 获取 token 中的 userId
+ String userId;
+ try {
+ userId = JWT.decode(token).getAudience().get(0);
+
+ } catch (Exception e) {
+ throw new ServiceException("token验证失败,请重新登录");
+ }
+ // 根据token中的userid查询数据库
+ User user =userService.getById(userId);
+ if (user == null) {
+ throw new ServiceException("用户不存在,请重新登录");
+ }
+ try {
+ // 用户密码加签验证 token
+ JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
+ jwtVerifier.verify(token); // 验证token
+ } catch (JWTVerificationException e) {
+ throw new ServiceException("token验证失败,请重新登录");
+ }
+ return true;
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/AnswerController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/AnswerController.java
new file mode 100644
index 0000000..c8263a0
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/AnswerController.java
@@ -0,0 +1,136 @@
+package com.exam.examsphere.controller;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.common.Result;
+import com.exam.examsphere.dto.AnswerDTO;
+import com.exam.examsphere.entity.Exam;
+import com.exam.examsphere.entity.Question;
+import com.exam.examsphere.mapper.ExamMapper;
+import com.exam.examsphere.mapper.QuestionMapper;
+import com.exam.examsphere.service.IExamService;
+import com.exam.examsphere.service.IQuestionService;
+import com.exam.examsphere.utils.TokenUtils;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import com.exam.examsphere.service.IAnswerService;
+import com.exam.examsphere.entity.Answer;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * @author chx
+ *
+ */
+@RestController
+@RequestMapping("/answer")
+public class AnswerController {
+
+ @Resource
+ private IAnswerService answerService;
+
+ @Resource
+ private ExamMapper examMapper;
+
+ @Resource
+ private QuestionMapper questionMapper;
+
+ // 新增或者更新
+ @PostMapping
+ public Result save(@RequestBody Answer answer) {
+ return Result.success(answerService.saveOrUpdate(answer));
+ }
+ //删除
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ return Result.success(answerService.removeById(id));
+ }
+ //多项删除
+ @PostMapping("/del/batch")
+ public Result deleteBatch(@RequestBody List ids) {
+ return Result.success(answerService.removeByIds(ids));
+ }
+ //查询所有数据
+ @GetMapping
+ public Result findAll() {
+ return Result.success(answerService.markListWithName());
+ }
+
+ @GetMapping("/findByUserId")
+ public Result findByUserId() {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ Long id = TokenUtils.getCurrentUser().getId();
+ queryWrapper.eq("user_id", id);
+ queryWrapper.orderByDesc("submit_time");
+ return Result.success(answerService.list(queryWrapper));
+ }
+ //根据id查询
+ @GetMapping("/{id}")
+ public Result findOne(@PathVariable Integer id) {
+ return Result.success(answerService.getById(id));
+ }
+ //分页查询
+ @GetMapping("/page")
+ public Result findPage(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByDesc("id");
+ return Result.success(answerService.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+ // 获取考试详情,包括答题详情
+ @GetMapping("/details/{examId}")
+ public Result getExamDetails(@PathVariable Long examId) {
+ // 获取考试的基本信息
+ Exam exam = examMapper.selectById(examId);
+ Long userId = TokenUtils.getCurrentUser().getId();
+ // 获取该考试的答题详情
+ List answerDetails = answerService.getAnswerDetailsByExamId(examId, userId);
+ for (AnswerDTO answerDTO : answerDetails) {
+ // 根据题目ID获取每道题目的信息
+ Question question = questionMapper.selectById(answerDTO.getId());
+ if (question != null) {
+ // 设置每道题目的正确答案
+ answerDTO.setCorrectAnswer(question.getAnswer());
+ if(question.getAnswer().equals(String.join("", answerDTO.getUserAnswers()).trim())){
+ answerDTO.setUserScore(question.getScore());
+ }
+ } else {
+ answerDTO.setCorrectAnswer(null);
+ answerDTO.setUserScore(0);
+ }
+ }
+ return Result.success(answerDetails);
+ }
+
+ @GetMapping("/{examId}/student/{studentId}")
+ public Result getExamDetails(@PathVariable Long examId, @PathVariable Long studentId) {
+ // 获取考试的基本信息
+ Exam exam = examMapper.selectById(examId);
+ // 获取该考试的答题详情
+ List answerDetails = answerService.getAnswerDetailsByExamId(examId,studentId);
+ for (AnswerDTO answerDTO : answerDetails) {
+ // 根据题目ID获取每道题目的信息
+ Question question = questionMapper.selectById(answerDTO.getId());
+ if (question != null) {
+ // 设置每道题目的正确答案
+ answerDTO.setCorrectAnswer(question.getAnswer());
+ if(question.getAnswer().equals(String.join("", answerDTO.getUserAnswers()).trim())){
+ answerDTO.setUserScore(question.getScore());
+ }
+ } else {
+ answerDTO.setCorrectAnswer(null);
+ answerDTO.setUserScore(0);
+ }
+ }
+ return Result.success(answerDetails);
+ }
+
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/CaptchaController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/CaptchaController.java
new file mode 100644
index 0000000..b06e64c
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/CaptchaController.java
@@ -0,0 +1,32 @@
+package com.exam.examsphere.controller;
+
+import com.exam.examsphere.config.CaptureConfig;
+import com.wf.captcha.ArithmeticCaptcha;
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@RestController
+@RequestMapping
+public class CaptchaController {
+ @RequestMapping("/captcha")
+ public void captcha(@RequestParam String key,HttpServletRequest request, HttpServletResponse response) throws IOException {
+ // SpecCaptcha captcha = new SpecCaptcha(100, 30,4);
+ // captcha.setCharType(SpecCaptcha.TYPE_ONLY_NUMBER);
+ // CaptureConfig.CAPTURE_MAP.put(key,captcha.text().toLowerCase());
+ // CaptchaUtil.out(captcha,request,response);
+
+ ArithmeticCaptcha captcha = new ArithmeticCaptcha();
+ captcha.setLen(4);
+ captcha.getArithmeticString();
+ captcha.text();
+ CaptureConfig.CAPTURE_MAP.put(key, captcha.text().toLowerCase());
+ CaptchaUtil.out(captcha, request, response);
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/CommentController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/CommentController.java
new file mode 100644
index 0000000..f022744
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/CommentController.java
@@ -0,0 +1,63 @@
+package com.exam.examsphere.controller;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.common.Result;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import com.exam.examsphere.service.ICommentService;
+import com.exam.examsphere.entity.Comment;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * @author chx
+ *
+ */
+@RestController
+@RequestMapping("/comment")
+ public class CommentController {
+
+ @Resource
+ private ICommentService commentService;
+
+ // 新增或者更新
+ @PostMapping
+ public Result save(@RequestBody Comment comment) {
+ return Result.success(commentService.saveOrUpdate(comment));
+ }
+ //删除
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ return Result.success(commentService.removeById(id));
+ }
+ //多项删除
+ @PostMapping("/del/batch")
+ public Result deleteBatch(@RequestBody List ids) {
+ return Result.success(commentService.removeByIds(ids));
+ }
+ //查询所有数据
+ @GetMapping
+ public Result findAll() {
+ return Result.success(commentService.getComments());
+ }
+ //根据id查询
+ @GetMapping("/{id}")
+ public Result findOne(@PathVariable Integer id) {
+ return Result.success(commentService.getById(id));
+ }
+ //分页查询
+ @GetMapping("/page")
+ public Result findPage(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByDesc("id");
+ return Result.success(commentService.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/ExamController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/ExamController.java
new file mode 100644
index 0000000..29b7a3e
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/ExamController.java
@@ -0,0 +1,196 @@
+package com.exam.examsphere.controller;
+
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.common.Result;
+import com.exam.examsphere.dto.*;
+import com.exam.examsphere.entity.Answer;
+import com.exam.examsphere.entity.Question;
+import com.exam.examsphere.mapper.ExamMapper;
+import com.exam.examsphere.mapper.QuestionMapper;
+import com.exam.examsphere.service.IAnswerService;
+import com.exam.examsphere.service.IQuestionService;
+import com.exam.examsphere.utils.TokenUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.CacheControl;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import com.exam.examsphere.service.IExamService;
+import com.exam.examsphere.entity.Exam;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * @author chx
+ *
+ */
+@RestController
+@RequestMapping("/exam")
+public class ExamController {
+
+ @Resource
+ private IExamService examService;
+
+ @Resource
+ private ExamMapper examMapper;
+
+ @Resource
+ private IQuestionService questionService;
+
+ @Resource
+ private QuestionMapper questionMapper;
+
+
+ // 新增或者更新
+ @PostMapping
+ public Result save(@RequestBody Exam exam) {
+ return Result.success(examService.saveOrUpdate(exam));
+ }
+ //删除
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ return Result.success(examService.removeById(id));
+ }
+ //多项删除
+ @PostMapping("/del/batch")
+ public Result deleteBatch(@RequestBody List ids) {
+ return Result.success(examService.removeByIds(ids));
+ }
+ //查询所有数据
+ @GetMapping
+ public Result findAll() {
+ return Result.success(examService.findAllWithTeacherName());
+ }
+ //根据id查询
+ @GetMapping("/{id}")
+ public Result findOne(@PathVariable Integer id) {
+ return Result.success(examService.getByIdWithTeacherName(id));
+ }
+ //分页查询
+ @GetMapping("/page")
+ public Result findPage(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByDesc("id");
+ return Result.success(examService.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+ // 根据 question_ids 获取多道题目
+ @GetMapping("/{examId}/question")
+ public Result getQuestionsByExam(@PathVariable Long examId, @RequestParam(defaultValue = "1") int page) {
+ // 假设每次只加载一道题目
+ int pageSize = 1;
+ // 根据 examId 获取 question_ids
+ Exam exam = examMapper.selectById(examId);
+ if (exam == null) {
+ return Result.error();
+ }
+
+ // 将 question_ids 转换为 List
+ List questionIds = Arrays.stream(exam.getQuestionIds().split(","))
+ .map(Long::valueOf)
+ .collect(Collectors.toList());
+
+ int totalQuestions = questionIds.size();
+
+ // 分页获取题目 ID
+ int fromIndex = Math.min((page - 1) * pageSize, questionIds.size());
+ int toIndex = Math.min(fromIndex + pageSize, questionIds.size());
+ List pagedQuestionIds = questionIds.subList(fromIndex, toIndex);
+
+ // 查询题目表
+ List questions = questionService.getQuestionsByIds(pagedQuestionIds);
+
+ Map response = new HashMap<>();
+ response.put("data", questions);
+ response.put("total", totalQuestions);
+
+ return Result.success(response);
+ }
+
+ // 提交答案
+ @PostMapping("/submit")
+ public Result submitExam(@RequestBody SubmitExamDTO submitExamDTO) {
+ try {
+ examService.submitExam(submitExamDTO);
+ return Result.success("试卷提交成功");
+ } catch (Exception e) {
+ return Result.error("试卷提交失败:" + e.getMessage());
+ }
+ }
+
+ //提交评分
+ @PostMapping("/submit-scores")
+ public Result submitScores(@RequestBody SubmitScoreDTO submitScoreDTO) {
+ try {
+ examService.submitScores(submitScoreDTO);
+ return Result.success("试卷提交成功");
+ } catch (Exception e) {
+ return Result.error("试卷提交失败:" + e.getMessage());
+ }
+ }
+
+ @PostMapping("/manual")
+ public Result createManualExam(@RequestBody Exam exam) {
+ boolean success = examService.createManualExam(exam);
+ return success ? Result.success("手动组卷成功") : Result.error("手动组卷失败");
+ }
+
+ @PostMapping("/random")
+ public Result randomExam(@RequestBody RandomExamDTO randomExamDTO) {
+ String title = randomExamDTO.getTitle();
+ Map typeCounts = randomExamDTO.getTypeCounts();
+ LocalDateTime startTime=randomExamDTO.getStartTime();
+ LocalDateTime endTime=randomExamDTO.getEndTime();
+ String img=randomExamDTO.getImg();
+
+ if (StrUtil.isBlank(title)) {
+ return Result.error("试卷标题不能为空");
+ }
+
+ List selectedQuestions = new ArrayList<>();
+ for (Map.Entry entry : typeCounts.entrySet()) {
+ String type = entry.getKey();
+ Integer count = entry.getValue();
+ if (count > 0) {
+ List questions = questionMapper.findRandomQuestionsByType(type, count);
+ selectedQuestions.addAll(questions);
+ }
+ }
+
+ if (selectedQuestions.isEmpty()) {
+ return Result.error("未找到符合条件的题目");
+ }
+
+ int totalScore = selectedQuestions.stream().mapToInt(Question::getScore).sum();
+ String questionIds = selectedQuestions.stream()
+ .map(q -> String.valueOf(q.getId()))
+ .collect(Collectors.joining(","));
+
+ Exam exam = new Exam();
+ exam.setTitle(title);
+ exam.setTotal(totalScore);
+ exam.setQuestionIds(questionIds);
+ exam.setUserId(Math.toIntExact(TokenUtils.getCurrentUser().getId()));
+ exam.setStartTime(startTime);
+ exam.setEndTime(endTime);
+ exam.setImg(img);
+ examMapper.insert(exam);
+ Map response = new HashMap<>();
+ response.put("examId", exam.getId());
+ return Result.success(response);
+ }
+
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/FileController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/FileController.java
new file mode 100644
index 0000000..0776b9d
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/FileController.java
@@ -0,0 +1,70 @@
+package com.exam.examsphere.controller;
+
+import com.exam.examsphere.common.Result;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/file")
+public class FileController {
+
+ private static final String UPLOAD_DIR = System.getProperty("user.dir")+"/static/img";
+
+ @PostMapping("/upload")
+ public Result uploadFile(@RequestParam("file") MultipartFile file) {
+ if (file.isEmpty()) {
+ return Result.error("文件不能为空");
+ }
+ try {
+ // 确保目录存在
+ File uploadDir = new File(UPLOAD_DIR);
+ if (!uploadDir.exists()) {
+ uploadDir.mkdirs();
+ }
+
+ // 生成唯一文件名
+ String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
+ File dest = new File(UPLOAD_DIR, fileName);
+
+ // 保存文件
+ file.transferTo(dest);
+
+ // 返回文件访问路径
+ String fileUrl = "http://localhost:8080/file/download?name=" + fileName;
+ return Result.success(fileUrl);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return Result.error("上传失败");
+ }
+ }
+
+
+ @GetMapping("/download")
+ public ResponseEntity downloadFile(@RequestParam String name) {
+ try {
+ // 文件完整路径
+ Path filePath = Paths.get(UPLOAD_DIR, name);
+ Resource resource = new UrlResource(filePath.toUri());
+
+ if (resource.exists() && resource.isReadable()) {
+ return ResponseEntity.ok()
+ .header("Content-Disposition", "inline; filename=\"" + name + "\"")
+ .body(resource);
+ } else {
+ throw new RuntimeException("文件不存在");
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("下载失败", e);
+ }
+ }
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/QuestionController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/QuestionController.java
new file mode 100644
index 0000000..7aef00c
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/QuestionController.java
@@ -0,0 +1,85 @@
+package com.exam.examsphere.controller;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.common.Result;
+import com.exam.examsphere.dto.QuestionDTO;
+import com.exam.examsphere.mapper.QuestionMapper;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import com.exam.examsphere.service.IQuestionService;
+import com.exam.examsphere.entity.Question;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * @author chx
+ *
+ */
+@RestController
+@RequestMapping("/question")
+ public class QuestionController {
+
+ @Resource
+ private IQuestionService questionService;
+
+ // 新增或者更新
+ @PostMapping
+ public Result save(@RequestBody Question question) {
+ return Result.success(questionService.saveOrUpdate(question));
+ }
+ //删除
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ return Result.success(questionService.removeById(id));
+ }
+ //多项删除
+ @PostMapping("/del/batch")
+ public Result deleteBatch(@RequestBody List ids) {
+ return Result.success(questionService.removeByIds(ids));
+ }
+ //查询所有数据
+ @GetMapping
+ public Result findAll() {
+ return Result.success(questionService.list());
+ }
+
+ @GetMapping("/getQuestion")
+ public Result getQuestion(@RequestParam("ids") Integer[] ids) {
+ List list = new ArrayList<>();
+ for (Integer id : ids) {
+ Question byId = questionService.getById(id);
+ list.add(byId);
+ }
+ return new Result<>().success(list);
+ }
+
+ @GetMapping("/getQuestionsByIds")
+ public Result getQuestionsByIds(@RequestParam("ids") Integer[] ids) {
+ List list = new ArrayList<>();
+ for (Integer id : ids) {
+ Question byId = questionService.getById(id);
+ }
+ return Result.success(ids);
+ }
+
+ //根据id查询
+ @GetMapping("/{id}")
+ public Result findOne(@PathVariable Integer id) {
+ return Result.success(questionService.getById(id));
+ }
+ //分页查询
+ @GetMapping("/page")
+ public Result findPage(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize,
+ @RequestParam(required = false) String keyword) {
+ return Result.success(questionService.findQuestionsWithTeacher(new Page<>(pageNum, pageSize),keyword));
+ }
+
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/controller/UserController.java b/ExamSphere/src/main/java/com/exam/examsphere/controller/UserController.java
new file mode 100644
index 0000000..98bb942
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/controller/UserController.java
@@ -0,0 +1,159 @@
+package com.exam.examsphere.controller;
+
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.common.Result;
+import com.exam.examsphere.config.CaptureConfig;
+import com.exam.examsphere.dto.UserDTO;
+import com.exam.examsphere.utils.TokenUtils;
+import com.wf.captcha.utils.CaptchaUtil;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import com.exam.examsphere.service.IUserService;
+import com.exam.examsphere.entity.User;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * @author chx
+ *
+ */
+@RestController
+@RequestMapping("/user")
+public class UserController {
+
+ @Resource
+ private IUserService userService;
+
+ @PostMapping("/login")
+ public Result login(@RequestBody UserDTO userDTO, @RequestParam String key, HttpServletRequest request) {
+ if(!userDTO.getVerificationCode().equalsIgnoreCase(CaptureConfig.CAPTURE_MAP.get(key))){
+ CaptchaUtil.clear(request);
+ return Result.error("验证码错误");
+ }
+ String username = userDTO.getUsername();
+ String password = userDTO.getPassword();
+ if(StrUtil.isBlank(username) || StrUtil.isBlank(password)){
+ return Result.error("用户名或密码不能为空");
+ }
+ CaptureConfig.CAPTURE_MAP.remove(key);
+ return Result.success(userService.login(userDTO));
+ }
+
+ @PostMapping("/register")
+ public Result register(@RequestBody UserDTO userDTO) {
+ String username = userDTO.getUsername();
+ String password = userDTO.getPassword();
+ if(StrUtil.isBlank(username) || StrUtil.isBlank(password)){
+ return Result.error("用户名或密码不能为空");
+ }
+ return Result.success(userService.register(userDTO));
+ }
+
+ // 新增或者更新
+ @PostMapping
+ public Result save(@RequestBody User user) {
+ User existingUser = null;
+ if (StrUtil.isNotBlank(user.getUsername())) {
+ existingUser = userService.getOne(new QueryWrapper().eq("username", user.getUsername()));
+ }
+ if (existingUser != null) {
+ if (StrUtil.isBlank(user.getPassword())) {
+ user.setPassword(existingUser.getPassword());
+ }
+ user.setId(existingUser.getId());
+ }
+ return Result.success(userService.saveOrUpdate(user));
+ }
+ //删除
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ return Result.success(userService.removeById(id));
+ }
+ //多项删除
+ @PostMapping("/del/batch")
+ public Result deleteBatch(@RequestBody List ids) {
+ return Result.success(userService.removeByIds(ids));
+ }
+ //查询所有数据
+ @GetMapping
+ public Result findAll() {
+ return Result.success(userService.list());
+ }
+ //获取当前用户信息
+ @GetMapping("/info")
+ public Result findOne() {
+ Long id= TokenUtils.getCurrentUser().getId();
+ return Result.success(userService.getById(id));
+ }
+
+ @GetMapping("/{id}")
+ public Result findById(@PathVariable Integer id) {
+ return Result.success(userService.getById(id));
+ }
+
+ //分页查询
+ @GetMapping("/page")
+ public Result findPage(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize,
+ @RequestParam(required = false) String keyword) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByAsc("id");
+ if (keyword != null && !keyword.isEmpty()) {
+ queryWrapper.like("id", keyword)
+ .or().like("username", keyword)
+ .or().like("mobile", keyword)
+ .or().like("email", keyword)
+ .or().like("gender", keyword)
+ .or().like("address", keyword)
+ .or().like("role", keyword);
+ }
+ return Result.success(userService.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+ @GetMapping("/student")
+ public Result findStudents(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize,
+ @RequestParam(required = false) String keyword) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByAsc("id");
+ queryWrapper.like("role", "student");
+ if (keyword != null && !keyword.isEmpty()) {
+ queryWrapper.like("id", keyword)
+ .or().like("username", keyword)
+ .or().like("mobile", keyword)
+ .or().like("email", keyword)
+ .or().like("gender", keyword)
+ .or().like("address", keyword)
+ .or().like("role", keyword);
+ }
+ return Result.success(userService.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+ @GetMapping("/teacher")
+ public Result findTeachers(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize,
+ @RequestParam(required = false) String keyword) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByAsc("id");
+ queryWrapper.like("role", "teacher");
+ if (keyword != null && !keyword.isEmpty()) {
+ queryWrapper.like("id", keyword)
+ .or().like("username", keyword)
+ .or().like("mobile", keyword)
+ .or().like("email", keyword)
+ .or().like("gender", keyword)
+ .or().like("address", keyword)
+ .or().like("role", keyword);
+ }
+ return Result.success(userService.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/AnswerDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/AnswerDTO.java
new file mode 100644
index 0000000..76f4439
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/AnswerDTO.java
@@ -0,0 +1,37 @@
+package com.exam.examsphere.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.Data;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true) // 忽略未定义字段
+public class AnswerDTO {
+ private Long id; // 题目ID
+ private String name; // 题目名称
+ private String type; // 题目类型
+ private List options; // 选项
+ private String answer; // 用户答案
+ private Integer score; // 分数
+ private String user; // 用户信息
+ private List userAnswers; // 用户多选题答案
+ private Integer userScore; // 用户得分
+ private String correctAnswer;
+}
+
+
+
+
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/CommentDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/CommentDTO.java
new file mode 100644
index 0000000..72eb949
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/CommentDTO.java
@@ -0,0 +1,17 @@
+package com.exam.examsphere.dto;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class CommentDTO {
+ private Long id;
+ private String username;
+ private String content;
+ private String time;
+ private Long parentId;
+ private String avatar;
+ private List replies = new ArrayList<>();
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/ExamDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/ExamDTO.java
new file mode 100644
index 0000000..63dc55c
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/ExamDTO.java
@@ -0,0 +1,17 @@
+package com.exam.examsphere.dto;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class ExamDTO {
+ private Long id;
+ private String title;
+ private String img;
+ private LocalDateTime startTime;
+ private LocalDateTime endTime;
+ private Integer total;
+ private Long userId;
+ private String teacherName;
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/MarkListDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/MarkListDTO.java
new file mode 100644
index 0000000..d509951
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/MarkListDTO.java
@@ -0,0 +1,35 @@
+package com.exam.examsphere.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+@Data
+public class MarkListDTO {
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private Long examId;
+
+ private Long userId;
+
+ private Integer teacherId;
+
+ private String answers;
+
+ private Integer score;
+
+ private String name;
+
+ private String questionIds;
+
+ private String isScore;
+
+ private LocalDateTime submitTime;
+
+ private String studentName;
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/QuestionDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/QuestionDTO.java
new file mode 100644
index 0000000..97a9225
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/QuestionDTO.java
@@ -0,0 +1,25 @@
+package com.exam.examsphere.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class QuestionDTO {
+
+ private Integer id;
+
+ private String name;
+
+ private String type;
+
+ private String options;
+
+ private String answer;
+
+ private Integer score;
+
+ private String teacherName;
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/RandomExamDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/RandomExamDTO.java
new file mode 100644
index 0000000..e0d338e
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/RandomExamDTO.java
@@ -0,0 +1,16 @@
+package com.exam.examsphere.dto;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Map;
+
+@Data
+public class RandomExamDTO {
+ private String title;
+ private Map typeCounts; // 题型对应的题目数量
+ private LocalDateTime startTime;
+ private LocalDateTime endTime;
+ private String img;
+}
\ No newline at end of file
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/SubmitExamDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/SubmitExamDTO.java
new file mode 100644
index 0000000..86555ab
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/SubmitExamDTO.java
@@ -0,0 +1,13 @@
+package com.exam.examsphere.dto;
+
+import com.exam.examsphere.dto.AnswerDTO;
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class SubmitExamDTO {
+ private Long examId;
+ private String answers;
+
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/SubmitScoreDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/SubmitScoreDTO.java
new file mode 100644
index 0000000..27f61d6
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/SubmitScoreDTO.java
@@ -0,0 +1,10 @@
+package com.exam.examsphere.dto;
+
+import lombok.Data;
+
+@Data
+public class SubmitScoreDTO {
+ private Long examId;
+ private Long userId;
+ private String answers;
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/dto/UserDTO.java b/ExamSphere/src/main/java/com/exam/examsphere/dto/UserDTO.java
new file mode 100644
index 0000000..1aa5d10
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/dto/UserDTO.java
@@ -0,0 +1,13 @@
+package com.exam.examsphere.dto;
+
+import lombok.Data;
+
+@Data
+public class UserDTO {
+ private String username;
+ private String password;
+ private String role;
+ private String token;
+ private String verificationCode;
+ private String avatar;
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/entity/Answer.java b/ExamSphere/src/main/java/com/exam/examsphere/entity/Answer.java
new file mode 100644
index 0000000..d0638b4
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/entity/Answer.java
@@ -0,0 +1,48 @@
+package com.exam.examsphere.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author chx
+ */
+@Getter
+@Setter
+ @ApiModel(value = "Answer对象", description = "")
+public class Answer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ private Long examId;
+
+ private Long userId;
+
+ private Integer teacherId;
+
+ private String answers;
+
+ private Integer score;
+
+ private String name;
+
+ private String questionIds;
+
+ private String isScore;
+
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime submitTime;
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/entity/Comment.java b/ExamSphere/src/main/java/com/exam/examsphere/entity/Comment.java
new file mode 100644
index 0000000..8bef654
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/entity/Comment.java
@@ -0,0 +1,39 @@
+package com.exam.examsphere.entity;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author chx
+ */
+@Getter
+@Setter
+ @ApiModel(value = "Comment对象", description = "")
+public class Comment implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ private String username;
+
+ private String content;
+
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime time;
+
+ private Long parentId;
+
+
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/entity/Exam.java b/ExamSphere/src/main/java/com/exam/examsphere/entity/Exam.java
new file mode 100644
index 0000000..034fc95
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/entity/Exam.java
@@ -0,0 +1,48 @@
+package com.exam.examsphere.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author chx
+ */
+@Getter
+@Setter
+ @ApiModel(value = "Exam对象", description = "考试表")
+public class Exam implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("主键ID")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty("考试标题")
+ private String title;
+
+ @ApiModelProperty("封面图")
+ private String img;
+
+ @ApiModelProperty("考试开始时间")
+ private LocalDateTime startTime;
+
+ @ApiModelProperty("考试结束时间")
+ private LocalDateTime endTime;
+
+ @ApiModelProperty("试题列表")
+ private String questionIds;
+
+ @ApiModelProperty("考试总分")
+ private Integer total;
+
+ @ApiModelProperty("用户ID")
+ private Integer userId;
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/entity/Question.java b/ExamSphere/src/main/java/com/exam/examsphere/entity/Question.java
new file mode 100644
index 0000000..4a3ccf8
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/entity/Question.java
@@ -0,0 +1,45 @@
+package com.exam.examsphere.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author chx
+ */
+@Getter
+@Setter
+ @ApiModel(value = "Question对象", description = "试题表")
+public class Question implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("主键ID")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty("题目文本")
+ private String name;
+
+ @ApiModelProperty("题型")
+ private String type;
+
+ @ApiModelProperty("选择题选项")
+ private String options;
+
+ @ApiModelProperty("正确答案")
+ private String answer;
+
+ @ApiModelProperty("分值")
+ private Integer score;
+
+ @ApiModelProperty("用户ID")
+ private Integer userId;
+
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/entity/User.java b/ExamSphere/src/main/java/com/exam/examsphere/entity/User.java
new file mode 100644
index 0000000..07c771f
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/entity/User.java
@@ -0,0 +1,41 @@
+package com.exam.examsphere.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * @author chx
+ */
+@Getter
+@Setter
+@ApiModel(value = "User对象", description = "")
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ private String username;
+ private String password;
+
+ @ApiModelProperty("用户角色:student, teacher, admin")
+ private String role;
+
+ private String gender;
+ private String email;
+ private String mobile;
+ private String address;
+ private String avatar;
+
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/exception/MyExceptionHandler.java b/ExamSphere/src/main/java/com/exam/examsphere/exception/MyExceptionHandler.java
new file mode 100644
index 0000000..c470390
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/exception/MyExceptionHandler.java
@@ -0,0 +1,15 @@
+package com.exam.examsphere.exception;
+
+import com.exam.examsphere.common.Result;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@ControllerAdvice
+public class MyExceptionHandler {
+ @ExceptionHandler(ServiceException.class)
+ @ResponseBody
+ public Result handle(ServiceException se){
+ return Result.error(se.getMessage());
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/exception/ServiceException.java b/ExamSphere/src/main/java/com/exam/examsphere/exception/ServiceException.java
new file mode 100644
index 0000000..25bcb88
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/exception/ServiceException.java
@@ -0,0 +1,11 @@
+package com.exam.examsphere.exception;
+
+import lombok.Getter;
+
+@Getter
+public class ServiceException extends RuntimeException {
+ public ServiceException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/mapper/AnswerMapper.java b/ExamSphere/src/main/java/com/exam/examsphere/mapper/AnswerMapper.java
new file mode 100644
index 0000000..4d2b9b5
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/mapper/AnswerMapper.java
@@ -0,0 +1,27 @@
+package com.exam.examsphere.mapper;
+
+import com.exam.examsphere.dto.MarkListDTO;
+import com.exam.examsphere.entity.Answer;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Mapper
+public interface AnswerMapper extends BaseMapper {
+ @Update("UPDATE answer " +
+ "SET answers = #{answers}, is_score = #{isScore}, score =#{score} " +
+ "WHERE exam_id = #{examId} AND user_id = #{userId}")
+
+ void update(Answer answer);
+
+ @Select("SELECT a.exam_id,a.user_id,a.name,a.score,a.is_score,a.submit_Time,u.username as studentName from answer a left join test.user u on a.user_id = u.id")
+ List selectWithName();
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/mapper/CommentMapper.java b/ExamSphere/src/main/java/com/exam/examsphere/mapper/CommentMapper.java
new file mode 100644
index 0000000..32073a2
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/mapper/CommentMapper.java
@@ -0,0 +1,21 @@
+package com.exam.examsphere.mapper;
+
+import com.exam.examsphere.dto.CommentDTO;
+import com.exam.examsphere.entity.Comment;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Mapper
+public interface CommentMapper extends BaseMapper {
+ @Select("SELECT c.id, c.username, c.content,c.time,c.parent_id, u.avatar " +
+ "FROM comment c " +
+ "LEFT JOIN user u ON c.username = u.username ")
+ List getCommentsWithAvatar();
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/mapper/ExamMapper.java b/ExamSphere/src/main/java/com/exam/examsphere/mapper/ExamMapper.java
new file mode 100644
index 0000000..9dbf07f
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/mapper/ExamMapper.java
@@ -0,0 +1,32 @@
+package com.exam.examsphere.mapper;
+
+import com.exam.examsphere.dto.ExamDTO;
+import com.exam.examsphere.entity.Answer;
+import com.exam.examsphere.entity.Exam;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Mapper
+public interface ExamMapper extends BaseMapper {
+ void insertAnswer(Answer answer);
+
+ @Select("SELECT e.id, e.title, e.img, e.start_time, e.end_time, e.user_id, u.username AS teacherName " +
+ "FROM exam e " +
+ "LEFT JOIN user u ON e.user_id = u.id")
+ List findAllWithTeacherName();
+
+ @Select("SELECT e.id, e.title, e.img, e.start_time, e.end_time,e.total,e.user_id, u.username AS teacherName " +
+ "FROM exam e " +
+ "LEFT JOIN user u ON e.user_id = u.id " +
+ "WHERE e.id = #{id}")
+ ExamDTO findByIdWithTeacherName(@Param("id") Integer id);
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/mapper/QuestionMapper.java b/ExamSphere/src/main/java/com/exam/examsphere/mapper/QuestionMapper.java
new file mode 100644
index 0000000..1ab6a33
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/mapper/QuestionMapper.java
@@ -0,0 +1,32 @@
+package com.exam.examsphere.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.dto.AnswerDTO;
+import com.exam.examsphere.dto.ExamDTO;
+import com.exam.examsphere.dto.QuestionDTO;
+import com.exam.examsphere.entity.Question;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Mapper
+public interface QuestionMapper extends BaseMapper {
+ @Select("SELECT * FROM question WHERE type = #{type} ORDER BY RAND() LIMIT #{count}")
+ List findRandomQuestionsByType(@Param("type") String type, @Param("count") int count);
+
+ @Select(" SELECT q.id, q.name, q.type, q.options, q.answer, q.score, u.username AS teacherName " +
+ "FROM question q LEFT JOIN user u ON q.user_id = u.id " +
+ "WHERE q.name LIKE CONCAT('%', #{keyword}, '%') " +
+ "OR u.username LIKE CONCAT('%', #{keyword}, '%') " +
+ "ORDER BY q.id ASC")
+ IPage findQuestionsWithTeacher(Page> page, @Param("keyword") String keyword);
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/mapper/UserMapper.java b/ExamSphere/src/main/java/com/exam/examsphere/mapper/UserMapper.java
new file mode 100644
index 0000000..7324acd
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/mapper/UserMapper.java
@@ -0,0 +1,14 @@
+package com.exam.examsphere.mapper;
+
+import com.exam.examsphere.entity.User;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ *
+ * @author chx
+ */
+@Mapper
+public interface UserMapper extends BaseMapper {
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/IAnswerService.java b/ExamSphere/src/main/java/com/exam/examsphere/service/IAnswerService.java
new file mode 100644
index 0000000..a4a0e47
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/IAnswerService.java
@@ -0,0 +1,22 @@
+package com.exam.examsphere.service;
+
+import com.exam.examsphere.dto.AnswerDTO;
+import com.exam.examsphere.dto.MarkListDTO;
+import com.exam.examsphere.dto.SubmitExamDTO;
+import com.exam.examsphere.entity.Answer;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+public interface IAnswerService extends IService {
+ List getAnswerDetailsByExamId(Long examId, Long userId);
+
+
+ Answer getByIds(Long examId, Long userId);
+
+ List markListWithName();
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/ICommentService.java b/ExamSphere/src/main/java/com/exam/examsphere/service/ICommentService.java
new file mode 100644
index 0000000..65778bd
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/ICommentService.java
@@ -0,0 +1,16 @@
+package com.exam.examsphere.service;
+
+import com.exam.examsphere.dto.CommentDTO;
+import com.exam.examsphere.entity.Comment;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+public interface ICommentService extends IService {
+
+ List getComments();
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/IExamService.java b/ExamSphere/src/main/java/com/exam/examsphere/service/IExamService.java
new file mode 100644
index 0000000..961e800
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/IExamService.java
@@ -0,0 +1,27 @@
+package com.exam.examsphere.service;
+
+import com.exam.examsphere.dto.AnswerDTO;
+import com.exam.examsphere.dto.ExamDTO;
+import com.exam.examsphere.dto.SubmitExamDTO;
+import com.exam.examsphere.dto.SubmitScoreDTO;
+import com.exam.examsphere.entity.Exam;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+public interface IExamService extends IService {
+
+ void submitExam(SubmitExamDTO submitExamDTO);
+
+ List findAllWithTeacherName();
+
+ ExamDTO getByIdWithTeacherName(Integer id);
+
+ void submitScores(SubmitScoreDTO submitScoreDTO);
+
+ boolean createManualExam(Exam exam);
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/IQuestionService.java b/ExamSphere/src/main/java/com/exam/examsphere/service/IQuestionService.java
new file mode 100644
index 0000000..a83ce81
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/IQuestionService.java
@@ -0,0 +1,23 @@
+package com.exam.examsphere.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.dto.QuestionDTO;
+import com.exam.examsphere.entity.Question;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+public interface IQuestionService extends IService {
+
+ List getQuestionsByIds(List ids);
+
+ Long getTotalQuestionsByExamId(Long examId);
+
+ IPage findQuestionsWithTeacher(Page> page, @Param("keyword") String keyword);
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/IUserService.java b/ExamSphere/src/main/java/com/exam/examsphere/service/IUserService.java
new file mode 100644
index 0000000..7c3136d
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/IUserService.java
@@ -0,0 +1,16 @@
+package com.exam.examsphere.service;
+
+import com.exam.examsphere.dto.UserDTO;
+import com.exam.examsphere.entity.User;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * @author chx
+ */
+public interface IUserService extends IService {
+
+ UserDTO login(UserDTO userDTO);
+
+ User register(UserDTO userDTO);
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/impl/AnswerServiceImpl.java b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/AnswerServiceImpl.java
new file mode 100644
index 0000000..95e057f
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/AnswerServiceImpl.java
@@ -0,0 +1,64 @@
+package com.exam.examsphere.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.exam.examsphere.dto.AnswerDTO;
+import com.exam.examsphere.dto.MarkListDTO;
+import com.exam.examsphere.dto.SubmitExamDTO;
+import com.exam.examsphere.entity.Answer;
+import com.exam.examsphere.exception.ServiceException;
+import com.exam.examsphere.mapper.AnswerMapper;
+import com.exam.examsphere.mapper.ExamMapper;
+import com.exam.examsphere.service.IAnswerService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Service
+public class AnswerServiceImpl extends ServiceImpl implements IAnswerService {
+ @Autowired
+ private AnswerMapper answerMapper;
+
+ @Autowired
+ private ExamMapper examMapper;
+
+ @Autowired
+ private ObjectMapper objectMapper; // 使用 Jackson 解析 JSON
+
+ public List getAnswerDetailsByExamId(Long examId, Long userId) {
+ // 查询用户的答题记录
+ Answer answer = answerMapper.selectOne(new QueryWrapper()
+ .eq("exam_id", examId)
+ .eq("user_id", userId));
+ if (answer == null) {
+ return null;
+ }
+
+ try {
+ // 解析 answers 字段(JSON 字符串)
+ return objectMapper.readValue(answer.getAnswers(), objectMapper.getTypeFactory().constructCollectionType(List.class, AnswerDTO.class));
+ } catch (Exception e) {
+ throw new RuntimeException("解析答题详情失败", e);
+ }
+ }
+
+ @Override
+ public Answer getByIds(Long examId, Long userId) {
+ Answer answer = answerMapper.selectOne(new QueryWrapper().eq("exam_id", examId).eq("user_id", userId));
+ return answer;
+ }
+
+ @Override
+ public List markListWithName() {
+ return answerMapper.selectWithName();
+ }
+
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/impl/CommentServiceImpl.java b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/CommentServiceImpl.java
new file mode 100644
index 0000000..bc03b55
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/CommentServiceImpl.java
@@ -0,0 +1,28 @@
+package com.exam.examsphere.service.impl;
+
+import com.exam.examsphere.dto.CommentDTO;
+import com.exam.examsphere.entity.Comment;
+import com.exam.examsphere.mapper.CommentMapper;
+import com.exam.examsphere.service.ICommentService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Service
+public class CommentServiceImpl extends ServiceImpl implements ICommentService {
+
+ @Autowired
+ private CommentMapper commentMapper;
+
+ @Override
+ public List getComments() {
+ return commentMapper.getCommentsWithAvatar();
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/impl/ExamServiceImpl.java b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/ExamServiceImpl.java
new file mode 100644
index 0000000..e770685
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/ExamServiceImpl.java
@@ -0,0 +1,186 @@
+package com.exam.examsphere.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.exam.examsphere.dto.AnswerDTO;
+import com.exam.examsphere.dto.ExamDTO;
+import com.exam.examsphere.dto.SubmitExamDTO;
+import com.exam.examsphere.dto.SubmitScoreDTO;
+import com.exam.examsphere.entity.Answer;
+import com.exam.examsphere.entity.Exam;
+import com.exam.examsphere.entity.Question;
+import com.exam.examsphere.mapper.AnswerMapper;
+import com.exam.examsphere.mapper.ExamMapper;
+import com.exam.examsphere.mapper.QuestionMapper;
+import com.exam.examsphere.service.IExamService;
+import com.exam.examsphere.utils.JsonUtil;
+import com.exam.examsphere.utils.TokenUtils;
+import lombok.extern.slf4j.Slf4j;
+import lombok.extern.slf4j.XSlf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class ExamServiceImpl extends ServiceImpl implements IExamService {
+
+ @Autowired
+ private QuestionMapper questionMapper;
+
+ @Autowired
+ private AnswerMapper answerMapper;
+
+ @Autowired
+ private ExamMapper examMapper;
+
+ @Transactional
+ public void submitExam(SubmitExamDTO submitExamDTO) {
+ Long userId = TokenUtils.getCurrentUser().getId();
+ int userScore = 0;
+ boolean containsSubjective = false;
+ log.info("开始处理试卷提交,用户ID:{}",userId);
+ // 将提交的答案 JSON 转换为对象
+ List answers = JsonUtil.convertJsonToAnswerList(submitExamDTO.getAnswers());
+ log.info("接收到的答案列表:{}",answers);
+ for (AnswerDTO answerDTO : answers) {
+
+ Question question = questionMapper.selectById(answerDTO.getId());
+ if (question == null) {
+ log.info("题目不存在,ID:{}",answerDTO.getId());
+ continue;
+ }
+
+ log.info("正在处理题目:{},类型:{}",question.getName(),question.getType());
+ // 处理用户答案和标准答案
+ String userAnswer = cleanUserAnswer(answerDTO.getUserAnswers(), question.getType(), Collections.singletonList(question.getOptions()));
+ String correctAnswer = question.getAnswer();
+ log.info("用户答案:{}",userAnswer);
+ log.info("正确答案:{}",correctAnswer);
+
+
+ if (!"主观题".equals(question.getType())) {
+ if ("多选题".equals(question.getType())) {
+ if (isCorrectMultiChoiceAnswer(userAnswer, correctAnswer)) {
+ userScore += question.getScore();
+ log.info("多选题得分:{}",question.getScore());
+ }
+ } else if ("单选题".equals(question.getType())) {
+ if (userAnswer.equals(correctAnswer)) {
+ userScore += question.getScore();
+ log.info("单选题得分:{}",question.getScore());
+ }
+ } else{
+ if (userAnswer.equals(correctAnswer)) {
+ userScore += question.getScore();
+ log.info("填空题得分:{}",question.getScore());
+ }
+ }
+ } else {
+ containsSubjective = true;
+ log.info("题目为主观题,跳过自动评分。");
+ }
+ }
+ log.info("用户总得分:{}",userScore);
+ long examId = submitExamDTO.getExamId();
+ Answer answer = new Answer();
+ answer.setExamId(examId);
+ answer.setUserId(userId);
+ answer.setScore(userScore);
+ answer.setAnswers(submitExamDTO.getAnswers()); // 原始答案 JSON
+ answer.setIsScore(containsSubjective ? "未评分" : "已评分");
+ answer.setQuestionIds(examMapper.selectById(examId).getQuestionIds());
+ answer.setTeacherId(examMapper.selectById(examId).getUserId());
+ answer.setName(examMapper.selectById(examId).getTitle());
+
+ answerMapper.insert(answer);
+ log.info("答案保存成功,用户ID:{}",userId);
+ }
+
+ @Override
+ public List findAllWithTeacherName() {
+ return examMapper.findAllWithTeacherName();
+ }
+
+ @Override
+ public ExamDTO getByIdWithTeacherName(Integer id) {
+ return examMapper.findByIdWithTeacherName(id);
+ }
+
+ @Transactional
+ @Override
+ public void submitScores(SubmitScoreDTO submitScoreDTO) {
+ Long userId = submitScoreDTO.getUserId();
+ // 将提交的答案 JSON 转换为对象
+ List answers = JsonUtil.convertJsonToAnswerList(submitScoreDTO.getAnswers());
+ log.info("接收到的答案列表:{}",answers);
+ int userScore = 0;
+ for (AnswerDTO answerDTO : answers) {
+ userScore += answerDTO.getUserScore();
+ }
+ Answer answer = new Answer();
+ answer.setExamId(submitScoreDTO.getExamId());
+ answer.setUserId(userId);
+ answer.setScore(userScore);
+ answer.setAnswers(submitScoreDTO.getAnswers());
+ answer.setIsScore("已评分");
+ answerMapper.update(answer);
+
+ }
+
+ @Override
+ public boolean createManualExam(Exam exam) {
+ return false;
+ }
+
+ private String cleanUserAnswer(List userAnswers, String questionType, List options) {
+ if ("主观题".equals(questionType) || "填空题".equals(questionType)) {
+ // 主观题或填空题保留完整答案
+ return String.join("", userAnswers).trim();
+ } else {
+ // 单选题或多选题提取选项字母
+ return userAnswers.stream()
+ .map(answer -> extractOptionLetters(answer, options)) // 提取有效选项字母
+ .collect(Collectors.joining());
+ }
+ }
+ private String cleanAnswer(String answer) {
+ return answer.replaceAll("\\s+", "").replaceAll("[^A-Z]", "");
+ }
+
+
+ private boolean isCorrectMultiChoiceAnswer(String userAnswer, String correctAnswer) {
+ char[] userArray = userAnswer.toCharArray();
+ char[] correctArray = correctAnswer.toCharArray();
+ Arrays.sort(userArray);
+ Arrays.sort(correctArray);
+ return Arrays.equals(userArray, correctArray);
+ }
+
+ private String extractOptionLetters(String userAnswer, List options) {
+ // 映射选项内容到代表字母
+ for (String option : options) {
+ // 如果用户答案中包含选项内容,提取选项字母
+ String letter = option.substring(0, 1); // 假设选项格式 "A. Apple"
+ if (userAnswer.contains(option)) {
+ return letter;
+ }
+ }
+ // 如果用户答案仅包含字母,直接返回
+ return userAnswer.replaceAll("\\s+", "").replaceAll("[^A-Z]", "");
+ }
+
+ @Override
+ public boolean saveOrUpdate(Exam entity) {
+ entity.setUserId(Math.toIntExact(TokenUtils.getCurrentUser().getId()));
+ return super.saveOrUpdate(entity);
+ }
+}
+
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/impl/QuestionServiceImpl.java b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/QuestionServiceImpl.java
new file mode 100644
index 0000000..1d9f233
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/QuestionServiceImpl.java
@@ -0,0 +1,50 @@
+package com.exam.examsphere.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.dto.QuestionDTO;
+import com.exam.examsphere.entity.Question;
+import com.exam.examsphere.mapper.QuestionMapper;
+import com.exam.examsphere.service.IQuestionService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.exam.examsphere.utils.TokenUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author chx
+ */
+@Service
+public class QuestionServiceImpl extends ServiceImpl implements IQuestionService {
+ @Autowired
+ private QuestionMapper questionMapper;
+
+ @Override
+ public List getQuestionsByIds(List ids) {
+ return questionMapper.selectBatchIds(ids);
+ }
+
+ public Long getTotalQuestionsByExamId(Long examId) {
+ return questionMapper.selectCount(new QueryWrapper().eq("id", examId));
+ }
+
+ @Override
+ public IPage findQuestionsWithTeacher(Page> page, String keyword) {
+ return questionMapper.findQuestionsWithTeacher(page, keyword);
+ }
+
+
+ @Override
+ public boolean saveOrUpdate(Question entity) {
+ if(entity.getId() == null){
+ entity.setUserId(Math.toIntExact(TokenUtils.getCurrentUser().getId()));
+ }
+ return super.saveOrUpdate(entity);
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/service/impl/UserServiceImpl.java b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..ab43715
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/service/impl/UserServiceImpl.java
@@ -0,0 +1,63 @@
+package com.exam.examsphere.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.exam.examsphere.dto.UserDTO;
+import com.exam.examsphere.entity.User;
+import com.exam.examsphere.exception.ServiceException;
+import com.exam.examsphere.mapper.UserMapper;
+import com.exam.examsphere.service.IUserService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.exam.examsphere.utils.TokenUtils;
+import jdk.nashorn.internal.parser.Token;
+import org.mindrot.jbcrypt.BCrypt;
+import org.omg.CORBA.UserException;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author chx
+ */
+@Service
+public class UserServiceImpl extends ServiceImpl implements IUserService {
+
+ @Override
+ public UserDTO login(UserDTO userDTO) {
+ User uniqueUser=getUserByUsername(userDTO.getUsername());
+ if (uniqueUser != null) {
+ // 验证密码
+ if (BCrypt.checkpw(userDTO.getPassword(), uniqueUser.getPassword())) {
+ BeanUtil.copyProperties(uniqueUser, userDTO, true);
+
+ // 生成 Token
+ String token = TokenUtils.genToken(uniqueUser.getId().toString(), uniqueUser.getPassword());
+ userDTO.setToken(token);
+ return userDTO;
+ }
+ }else{
+ throw new ServiceException("用户名或密码错误");
+ }
+ return null;
+ }
+
+ @Override
+ public User register(UserDTO userDTO) {
+ User uniqueUser=getUserByUsername(userDTO.getUsername());
+ if (uniqueUser == null) {
+ BeanUtil.copyProperties(userDTO, uniqueUser = new User(),true);
+ //密码加密
+ String hashedPassword = BCrypt.hashpw(userDTO.getPassword(), BCrypt.gensalt());
+ uniqueUser.setPassword(hashedPassword);
+ save(uniqueUser);
+ }else{
+ throw new ServiceException("用户已存在");
+ }
+ return uniqueUser;
+ }
+ private User getUserByUsername(String username) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("username", username);
+ return getOne(queryWrapper);
+ }
+}
\ No newline at end of file
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/utils/JsonUtil.java b/ExamSphere/src/main/java/com/exam/examsphere/utils/JsonUtil.java
new file mode 100644
index 0000000..a94e35f
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/utils/JsonUtil.java
@@ -0,0 +1,25 @@
+package com.exam.examsphere.utils;
+
+import com.exam.examsphere.dto.AnswerDTO;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.List;
+
+public class JsonUtil {
+
+ /**
+ * 将 JSON 字符串转换为 List
+ *
+ * @param jsonString JSON 字符串
+ * @return 转换后的 List
+ */
+ public static List convertJsonToAnswerList(String jsonString) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ // 使用 TypeReference 将 JSON 转换为 List
+ return objectMapper.readValue(jsonString, new TypeReference>() {});
+ } catch (Exception e) {
+ throw new RuntimeException("JSON 转换失败: " + e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/utils/MyMetaObjectHandler.java b/ExamSphere/src/main/java/com/exam/examsphere/utils/MyMetaObjectHandler.java
new file mode 100644
index 0000000..6d229e9
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/utils/MyMetaObjectHandler.java
@@ -0,0 +1,22 @@
+package com.exam.examsphere.utils;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+ @Override
+ public void insertFill(MetaObject metaObject) {
+ this.strictInsertFill(metaObject, "submitTime", LocalDateTime.class, LocalDateTime.now());
+ this.strictInsertFill(metaObject, "time", LocalDateTime.class, LocalDateTime.now());
+ }
+
+ @Override
+ public void updateFill(MetaObject metaObject) {
+
+ }
+}
diff --git a/ExamSphere/src/main/java/com/exam/examsphere/utils/TokenUtils.java b/ExamSphere/src/main/java/com/exam/examsphere/utils/TokenUtils.java
new file mode 100644
index 0000000..c515127
--- /dev/null
+++ b/ExamSphere/src/main/java/com/exam/examsphere/utils/TokenUtils.java
@@ -0,0 +1,62 @@
+package com.exam.examsphere.utils;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.exam.examsphere.entity.User;
+import com.exam.examsphere.mapper.UserMapper;
+import com.exam.examsphere.service.IUserService;
+import com.exam.examsphere.service.impl.UserServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;
+@Component
+public class TokenUtils {
+ @Autowired
+ private UserMapper userMapper;
+
+ private static IUserService staticUserService;
+ @Resource
+ private IUserService userService;
+
+ @PostConstruct
+ public void setUserService(){
+ staticUserService = userService;
+ }
+
+ /**
+ * token生成
+ * @return
+ */
+ public static String genToken(String userId, String sign) {
+ return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面,作为载荷
+ .withExpiresAt(DateUtil.offsetHour(new Date(), 1)) // token 1小时后过期
+ .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
+ }
+
+ public static User getCurrentUser() {
+ try {
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ String token = request.getHeader("token");
+ if (StrUtil.isNotBlank(token)) {
+ String userId = JWT.decode(token).getAudience().get(0);
+ return staticUserService.getById(Integer.parseInt(userId));
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return null;
+ }
+
+
+
+}
diff --git a/ExamSphere/src/main/resources/META-INF/MANIFEST.MF b/ExamSphere/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a30722f
--- /dev/null
+++ b/ExamSphere/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,32 @@
+Manifest-Version: 1.0
+Main-Class: com.exam.examsphere.ExamSphereApplication
+Class-Path: spring-jdbc-5.3.23.jar springfox-core-2.9.2.jar java-jwt-3.1
+ 0.3.jar swagger-models-1.5.20.jar tomcat-embed-core-9.0.68.jar spring-b
+ oot-starter-tomcat-2.6.13.jar mybatis-plus-annotation-3.5.4.1.jar log4j
+ -api-2.17.2.jar velocity-1.7.jar jul-to-slf4j-1.7.36.jar commons-lang-2
+ .4.jar spring-beans-5.3.23.jar spring-boot-autoconfigure-2.6.13.jar jav
+ assist-3.25.0-GA.jar logback-classic-1.2.11.jar springfox-schema-2.9.2.
+ jar jackson-databind-2.13.4.2.jar springfox-swagger-common-2.9.2.jar hu
+ tool-all-5.7.20.jar springfox-spring-web-2.9.2.jar spring-boot-starter-
+ logging-2.6.13.jar springfox-spi-2.9.2.jar spring-web-5.3.23.jar common
+ s-codec-1.15.jar spring-tx-5.3.23.jar classmate-1.5.1.jar jackson-modul
+ e-parameter-names-2.13.4.jar spring-boot-starter-2.6.13.jar spring-jcl-
+ 5.3.23.jar spring-plugin-metadata-1.2.0.RELEASE.jar commons-collections
+ -3.2.1.jar mysql-connector-j-8.0.31.jar spring-webmvc-5.3.23.jar byte-b
+ uddy-1.11.22.jar mybatis-plus-extension-3.5.4.1.jar swagger-bootstrap-u
+ i-1.9.6.jar mybatis-3.5.13.jar mybatis-plus-generator-3.5.1.jar spring-
+ boot-devtools-2.6.13.jar springfox-swagger2-2.9.2.jar mybatis-plus-boot
+ -starter-3.5.4.1.jar spring-boot-starter-jdbc-2.6.13.jar snakeyaml-1.29
+ .jar tomcat-embed-websocket-9.0.68.jar log4j-to-slf4j-2.17.2.jar mapstr
+ uct-1.2.0.Final.jar jackson-core-2.13.4.jar HikariCP-4.0.3.jar spring-b
+ oot-starter-web-2.6.13.jar jackson-annotations-2.13.4.jar mybatis-plus-
+ 3.5.4.1.jar jackson-datatype-jsr310-2.13.4.jar spring-context-5.3.23.ja
+ r guava-20.0.jar jsqlparser-4.6.jar spring-core-5.3.23.jar mybatis-plus
+ -spring-boot-autoconfigure-3.5.4.1.jar spring-aop-5.3.23.jar logback-co
+ re-1.2.11.jar lombok-1.18.24.jar jakarta.annotation-api-1.3.5.jar sprin
+ gfox-swagger-ui-2.9.2.jar spring-plugin-core-1.2.0.RELEASE.jar swagger-
+ annotations-1.5.20.jar spring-expression-5.3.23.jar spring-boot-starter
+ -json-2.6.13.jar jackson-datatype-jdk8-2.13.4.jar mybatis-spring-2.1.1.
+ jar slf4j-api-1.7.36.jar tomcat-embed-el-9.0.68.jar mybatis-plus-core-3
+ .5.4.1.jar spring-boot-2.6.13.jar
+
diff --git a/ExamSphere/src/main/resources/application-dev.yaml b/ExamSphere/src/main/resources/application-dev.yaml
new file mode 100644
index 0000000..dd7b190
--- /dev/null
+++ b/ExamSphere/src/main/resources/application-dev.yaml
@@ -0,0 +1,22 @@
+# 开发环境
+#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+##??????url
+#spring.datasource.url=jdbc:mysql://localhost:3306/tlias
+##?????????
+#spring.datasource.username=root
+##????????
+#spring.datasource.password=123456
+#
+#spring.devtools.restart.enable=true
+#spring.devtools.restart.additional-paths=src/main/java
+
+spring:
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/test
+ username: root
+ password: 123456
+ devtools:
+ restart:
+ enabled: true
+ additional-paths: src/main/java
diff --git a/ExamSphere/src/main/resources/application-prod.yaml b/ExamSphere/src/main/resources/application-prod.yaml
new file mode 100644
index 0000000..7aa7ead
--- /dev/null
+++ b/ExamSphere/src/main/resources/application-prod.yaml
@@ -0,0 +1,12 @@
+#生产环境
+server.port=8080
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+#??????url
+spring.datasource.url=jdbc:mysql://localhost:3306/test
+#?????????
+spring.datasource.username=root
+#????????
+spring.datasource.password=123456
+
+spring.devtools.restart.enable=true
+spring.devtools.restart.additional-paths=src/main/java
diff --git a/ExamSphere/src/main/resources/application.yaml b/ExamSphere/src/main/resources/application.yaml
new file mode 100644
index 0000000..72ca5da
--- /dev/null
+++ b/ExamSphere/src/main/resources/application.yaml
@@ -0,0 +1,13 @@
+spring:
+ profiles:
+ active: dev
+ mvc:
+ pathmatch:
+ matching-strategy: ant_path_matcher
+mybatis-plus:
+ configuration:
+ mapper-locations: classpath*:/mapper/**mapper.xml
+#配置sql日志
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+server:
+ port: 8080
diff --git a/ExamSphere/src/main/resources/mapper/AnswerMapper.xml b/ExamSphere/src/main/resources/mapper/AnswerMapper.xml
new file mode 100644
index 0000000..8bba3d4
--- /dev/null
+++ b/ExamSphere/src/main/resources/mapper/AnswerMapper.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/ExamSphere/src/main/resources/mapper/CommentMapper.xml b/ExamSphere/src/main/resources/mapper/CommentMapper.xml
new file mode 100644
index 0000000..1ef3bda
--- /dev/null
+++ b/ExamSphere/src/main/resources/mapper/CommentMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/ExamSphere/src/main/resources/mapper/ExamMapper.xml b/ExamSphere/src/main/resources/mapper/ExamMapper.xml
new file mode 100644
index 0000000..affb2bc
--- /dev/null
+++ b/ExamSphere/src/main/resources/mapper/ExamMapper.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ INSERT INTO answer (exam_id, user_id, teacher_id, answers, score, name, question_ids, is_score)
+ VALUES (#{examId}, #{userId}, #{teacherId}, #{answers}, #{score}, #{name}, #{questionIds}, #{isScore});
+
+
diff --git a/ExamSphere/src/main/resources/mapper/MessageMapper.xml b/ExamSphere/src/main/resources/mapper/MessageMapper.xml
new file mode 100644
index 0000000..fbd2466
--- /dev/null
+++ b/ExamSphere/src/main/resources/mapper/MessageMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/ExamSphere/src/main/resources/mapper/QuestionMapper.xml b/ExamSphere/src/main/resources/mapper/QuestionMapper.xml
new file mode 100644
index 0000000..70f695d
--- /dev/null
+++ b/ExamSphere/src/main/resources/mapper/QuestionMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/ExamSphere/src/main/resources/mapper/UserMapper.xml b/ExamSphere/src/main/resources/mapper/UserMapper.xml
new file mode 100644
index 0000000..01f7429
--- /dev/null
+++ b/ExamSphere/src/main/resources/mapper/UserMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/ExamSphere/src/main/resources/static/index.html b/ExamSphere/src/main/resources/static/index.html
new file mode 100644
index 0000000..89bb8ba
--- /dev/null
+++ b/ExamSphere/src/main/resources/static/index.html
@@ -0,0 +1,6 @@
+
+
+hello word!!!
+this is a html page
+
+
\ No newline at end of file
diff --git a/ExamSphere/src/main/resources/templates/controller.java.vm b/ExamSphere/src/main/resources/templates/controller.java.vm
new file mode 100644
index 0000000..aaab6c3
--- /dev/null
+++ b/ExamSphere/src/main/resources/templates/controller.java.vm
@@ -0,0 +1,83 @@
+package ${package.Controller};
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.exam.examsphere.common.Result;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import ${package.Service}.${table.serviceName};
+import ${package.Entity}.${entity};
+
+#if(${restControllerStyle})
+import org.springframework.web.bind.annotation.RestController;
+#else
+import org.springframework.stereotype.Controller;
+#end
+#if(${superControllerClassPackage})
+import ${superControllerClassPackage};
+#end
+
+/**
+ *
+ * @author ${author}
+ *
+ */
+#if(${restControllerStyle})
+@RestController
+#else
+@Controller
+#end
+@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
+#if(${kotlin})
+ class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end
+
+#else
+ #if(${superControllerClass})
+ public class ${table.controllerName} extends ${superControllerClass} {
+ #else
+ public class ${table.controllerName} {
+ #end
+
+ @Resource
+ private ${table.serviceName} ${table.entityPath}Service;
+
+ // 新增或者更新
+ @PostMapping
+ public Result save(@RequestBody ${entity} ${table.entityPath}) {
+ return Result.success(${table.entityPath}Service.saveOrUpdate(${table.entityPath}));
+ }
+ //删除
+ @DeleteMapping("/{id}")
+ public Result delete(@PathVariable Integer id) {
+ return Result.success(${table.entityPath}Service.removeById(id));
+ }
+ //多项删除
+ @PostMapping("/del/batch")
+ public Result deleteBatch(@RequestBody List ids) {
+ return Result.success(${table.entityPath}Service.removeByIds(ids));
+ }
+ //查询所有数据
+ @GetMapping
+ public Result findAll() {
+ return Result.success(${table.entityPath}Service.list());
+ }
+ //根据id查询
+ @GetMapping("/{id}")
+ public Result findOne(@PathVariable Integer id) {
+ return Result.success(${table.entityPath}Service.getById(id));
+ }
+ //分页查询
+ @GetMapping("/page")
+ public Result findPage(@RequestParam Integer pageNum,
+ @RequestParam Integer pageSize) {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.orderByDesc("id");
+ return Result.success(${table.entityPath}Service.page(new Page<>(pageNum, pageSize),queryWrapper));
+ }
+
+}
+
+#end
\ No newline at end of file
diff --git a/ExamSphere/src/test/java/com/exam/examsphere/ExamSphereApplicationTests.java b/ExamSphere/src/test/java/com/exam/examsphere/ExamSphereApplicationTests.java
new file mode 100644
index 0000000..0ac8f17
--- /dev/null
+++ b/ExamSphere/src/test/java/com/exam/examsphere/ExamSphereApplicationTests.java
@@ -0,0 +1,24 @@
+package com.exam.examsphere;
+
+import com.exam.examsphere.entity.User;
+import com.exam.examsphere.mapper.UserMapper;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import java.util.List;
+
+@SpringBootTest
+class ExamSphereApplicationTests {
+ @Autowired
+ private UserMapper userMapper;
+ @Test
+ void contextLoads() {
+ }
+ @Test
+ public void testSelect() {
+ System.out.println(("----- selectAll method test ------"));
+ List userList = userMapper.selectList(null);
+ userList.forEach(System.out::println);
+ }
+
+}
diff --git a/ExamSphere/static/img/0072d532-b6b7-4336-9ead-5d6e001698e0_背景1.jpg b/ExamSphere/static/img/0072d532-b6b7-4336-9ead-5d6e001698e0_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/0072d532-b6b7-4336-9ead-5d6e001698e0_背景1.jpg differ
diff --git a/ExamSphere/static/img/1585e530-74f9-4381-9a2c-3a2f7ad58e39_背景1.jpg b/ExamSphere/static/img/1585e530-74f9-4381-9a2c-3a2f7ad58e39_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/1585e530-74f9-4381-9a2c-3a2f7ad58e39_背景1.jpg differ
diff --git a/ExamSphere/static/img/24d23157-044d-46b2-b6f2-759ce9e6d287_背景1.jpg b/ExamSphere/static/img/24d23157-044d-46b2-b6f2-759ce9e6d287_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/24d23157-044d-46b2-b6f2-759ce9e6d287_背景1.jpg differ
diff --git a/ExamSphere/static/img/2d5fbdc8-ea81-4df7-9baa-b3bcdfca7271_背景1.jpg b/ExamSphere/static/img/2d5fbdc8-ea81-4df7-9baa-b3bcdfca7271_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/2d5fbdc8-ea81-4df7-9baa-b3bcdfca7271_背景1.jpg differ
diff --git a/ExamSphere/static/img/3860f280-c888-4c91-b8a1-7f1f9e297edd_user.png b/ExamSphere/static/img/3860f280-c888-4c91-b8a1-7f1f9e297edd_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/3860f280-c888-4c91-b8a1-7f1f9e297edd_user.png differ
diff --git a/ExamSphere/static/img/425c9d84-6086-48d6-ad9a-17b22a2baec8_user.png b/ExamSphere/static/img/425c9d84-6086-48d6-ad9a-17b22a2baec8_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/425c9d84-6086-48d6-ad9a-17b22a2baec8_user.png differ
diff --git a/ExamSphere/static/img/47ff0ceb-481d-4882-b41f-9931130f80d5_user.png b/ExamSphere/static/img/47ff0ceb-481d-4882-b41f-9931130f80d5_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/47ff0ceb-481d-4882-b41f-9931130f80d5_user.png differ
diff --git a/ExamSphere/static/img/4c2015c3-f9b8-481d-bd2d-58c907e4beb0_背景1.jpg b/ExamSphere/static/img/4c2015c3-f9b8-481d-bd2d-58c907e4beb0_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/4c2015c3-f9b8-481d-bd2d-58c907e4beb0_背景1.jpg differ
diff --git a/ExamSphere/static/img/4deeabf3-0c26-42d5-b0e2-feaee1263966_user.png b/ExamSphere/static/img/4deeabf3-0c26-42d5-b0e2-feaee1263966_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/4deeabf3-0c26-42d5-b0e2-feaee1263966_user.png differ
diff --git a/ExamSphere/static/img/53c0ac5a-9b01-4e24-a612-159850379180_背景1.jpg b/ExamSphere/static/img/53c0ac5a-9b01-4e24-a612-159850379180_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/53c0ac5a-9b01-4e24-a612-159850379180_背景1.jpg differ
diff --git a/ExamSphere/static/img/60e8c900-004d-4d6a-b169-f577c0b2a2e0_背景3.jpg b/ExamSphere/static/img/60e8c900-004d-4d6a-b169-f577c0b2a2e0_背景3.jpg
new file mode 100644
index 0000000..aa0a1bd
Binary files /dev/null and b/ExamSphere/static/img/60e8c900-004d-4d6a-b169-f577c0b2a2e0_背景3.jpg differ
diff --git a/ExamSphere/static/img/77578a92-c5e7-42f9-a026-24748ae8ee6c_背景1.jpg b/ExamSphere/static/img/77578a92-c5e7-42f9-a026-24748ae8ee6c_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/77578a92-c5e7-42f9-a026-24748ae8ee6c_背景1.jpg differ
diff --git a/ExamSphere/static/img/7bb7d82c-eb78-46d5-847d-ed38d1a0e751_user.png b/ExamSphere/static/img/7bb7d82c-eb78-46d5-847d-ed38d1a0e751_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/7bb7d82c-eb78-46d5-847d-ed38d1a0e751_user.png differ
diff --git a/ExamSphere/static/img/86eea89b-fbf8-403f-a085-b5383ebb080d_背景1.jpg b/ExamSphere/static/img/86eea89b-fbf8-403f-a085-b5383ebb080d_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/86eea89b-fbf8-403f-a085-b5383ebb080d_背景1.jpg differ
diff --git a/ExamSphere/static/img/88fea9e9-339d-4522-a921-ddc2c9f0bbfa_user.png b/ExamSphere/static/img/88fea9e9-339d-4522-a921-ddc2c9f0bbfa_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/88fea9e9-339d-4522-a921-ddc2c9f0bbfa_user.png differ
diff --git a/ExamSphere/static/img/a992593a-66cc-4852-8731-5bbfc7918a47_user.png b/ExamSphere/static/img/a992593a-66cc-4852-8731-5bbfc7918a47_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/a992593a-66cc-4852-8731-5bbfc7918a47_user.png differ
diff --git a/ExamSphere/static/img/b213da19-7b0d-4a3d-ba73-d1362fc665ff_user.png b/ExamSphere/static/img/b213da19-7b0d-4a3d-ba73-d1362fc665ff_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/b213da19-7b0d-4a3d-ba73-d1362fc665ff_user.png differ
diff --git a/ExamSphere/static/img/b4299e83-ac91-4bd1-a3f5-7e2748213971_屏幕截图 2024-12-17 235252.png b/ExamSphere/static/img/b4299e83-ac91-4bd1-a3f5-7e2748213971_屏幕截图 2024-12-17 235252.png
new file mode 100644
index 0000000..f3c1b01
Binary files /dev/null and b/ExamSphere/static/img/b4299e83-ac91-4bd1-a3f5-7e2748213971_屏幕截图 2024-12-17 235252.png differ
diff --git a/ExamSphere/static/img/b8a114e7-a33c-4ad8-8157-2ad0c2bc5ce2_屏幕截图 2024-12-17 235252.png b/ExamSphere/static/img/b8a114e7-a33c-4ad8-8157-2ad0c2bc5ce2_屏幕截图 2024-12-17 235252.png
new file mode 100644
index 0000000..f3c1b01
Binary files /dev/null and b/ExamSphere/static/img/b8a114e7-a33c-4ad8-8157-2ad0c2bc5ce2_屏幕截图 2024-12-17 235252.png differ
diff --git a/ExamSphere/static/img/bdfa77a8-2666-43f6-a2ab-801ad8249c22_user.png b/ExamSphere/static/img/bdfa77a8-2666-43f6-a2ab-801ad8249c22_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/bdfa77a8-2666-43f6-a2ab-801ad8249c22_user.png differ
diff --git a/ExamSphere/static/img/bf0d4510-f8db-4afb-bf9e-4fa76da41b4e_user.png b/ExamSphere/static/img/bf0d4510-f8db-4afb-bf9e-4fa76da41b4e_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/bf0d4510-f8db-4afb-bf9e-4fa76da41b4e_user.png differ
diff --git a/ExamSphere/static/img/c5ab3687-2f15-428e-a8e9-4e07bb1ef56d_user.png b/ExamSphere/static/img/c5ab3687-2f15-428e-a8e9-4e07bb1ef56d_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/c5ab3687-2f15-428e-a8e9-4e07bb1ef56d_user.png differ
diff --git a/ExamSphere/static/img/d5848a62-73a1-4fe0-a143-3ce85855a203_屏幕截图 2024-12-17 235252.png b/ExamSphere/static/img/d5848a62-73a1-4fe0-a143-3ce85855a203_屏幕截图 2024-12-17 235252.png
new file mode 100644
index 0000000..e06d97d
Binary files /dev/null and b/ExamSphere/static/img/d5848a62-73a1-4fe0-a143-3ce85855a203_屏幕截图 2024-12-17 235252.png differ
diff --git a/ExamSphere/static/img/f1343317-1991-4c2c-88f2-2164bb1edf1b_user.png b/ExamSphere/static/img/f1343317-1991-4c2c-88f2-2164bb1edf1b_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/f1343317-1991-4c2c-88f2-2164bb1edf1b_user.png differ
diff --git a/ExamSphere/static/img/f2e5e85d-53e4-41a6-a1e4-98658d0225d1_user.png b/ExamSphere/static/img/f2e5e85d-53e4-41a6-a1e4-98658d0225d1_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img/f2e5e85d-53e4-41a6-a1e4-98658d0225d1_user.png differ
diff --git a/ExamSphere/static/img/f5737e3c-cf94-4db9-9e59-9e9e5a7c66b5_背景1.jpg b/ExamSphere/static/img/f5737e3c-cf94-4db9-9e59-9e9e5a7c66b5_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img/f5737e3c-cf94-4db9-9e59-9e9e5a7c66b5_背景1.jpg differ
diff --git a/ExamSphere/static/img0d1fbc84-aac1-4a77-a410-cceccf55c616_轮播图1.png b/ExamSphere/static/img0d1fbc84-aac1-4a77-a410-cceccf55c616_轮播图1.png
new file mode 100644
index 0000000..80860f5
Binary files /dev/null and b/ExamSphere/static/img0d1fbc84-aac1-4a77-a410-cceccf55c616_轮播图1.png differ
diff --git a/ExamSphere/static/img34256a36-9715-48e7-93bb-87e2d66d0536_user.png b/ExamSphere/static/img34256a36-9715-48e7-93bb-87e2d66d0536_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img34256a36-9715-48e7-93bb-87e2d66d0536_user.png differ
diff --git a/ExamSphere/static/img442c9d26-ba93-448b-8dfc-3abad9ce96de_user.png b/ExamSphere/static/img442c9d26-ba93-448b-8dfc-3abad9ce96de_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img442c9d26-ba93-448b-8dfc-3abad9ce96de_user.png differ
diff --git a/ExamSphere/static/img4b9660c3-9d4e-45ab-bdd1-cee3c437e745_user.png b/ExamSphere/static/img4b9660c3-9d4e-45ab-bdd1-cee3c437e745_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img4b9660c3-9d4e-45ab-bdd1-cee3c437e745_user.png differ
diff --git a/ExamSphere/static/img4bccf5b0-0c82-4d8d-b30d-f0ede4c1d970_user.png b/ExamSphere/static/img4bccf5b0-0c82-4d8d-b30d-f0ede4c1d970_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img4bccf5b0-0c82-4d8d-b30d-f0ede4c1d970_user.png differ
diff --git a/ExamSphere/static/img4ca66e51-7b27-4f44-a500-8259a812231e_背景1.jpg b/ExamSphere/static/img4ca66e51-7b27-4f44-a500-8259a812231e_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img4ca66e51-7b27-4f44-a500-8259a812231e_背景1.jpg differ
diff --git a/ExamSphere/static/img4f431ab1-b78f-487f-b559-322363e38c88_背景1.jpg b/ExamSphere/static/img4f431ab1-b78f-487f-b559-322363e38c88_背景1.jpg
new file mode 100644
index 0000000..59bbe75
Binary files /dev/null and b/ExamSphere/static/img4f431ab1-b78f-487f-b559-322363e38c88_背景1.jpg differ
diff --git a/ExamSphere/static/img6d9e7300-3843-435f-8f32-1023ffda10b9_user.png b/ExamSphere/static/img6d9e7300-3843-435f-8f32-1023ffda10b9_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img6d9e7300-3843-435f-8f32-1023ffda10b9_user.png differ
diff --git a/ExamSphere/static/img77db5bc8-7805-4a16-8e7c-ba0eafebfb3b_user.png b/ExamSphere/static/img77db5bc8-7805-4a16-8e7c-ba0eafebfb3b_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/img77db5bc8-7805-4a16-8e7c-ba0eafebfb3b_user.png differ
diff --git a/ExamSphere/static/imgd0d5c90d-d4aa-4e23-ab58-b894fc2ee1c8_user.png b/ExamSphere/static/imgd0d5c90d-d4aa-4e23-ab58-b894fc2ee1c8_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/imgd0d5c90d-d4aa-4e23-ab58-b894fc2ee1c8_user.png differ
diff --git a/ExamSphere/static/imge9f7fc0f-206a-40c3-b3ff-fa4c4d46977f_user.png b/ExamSphere/static/imge9f7fc0f-206a-40c3-b3ff-fa4c4d46977f_user.png
new file mode 100644
index 0000000..6964706
Binary files /dev/null and b/ExamSphere/static/imge9f7fc0f-206a-40c3-b3ff-fa4c4d46977f_user.png differ
diff --git a/ExamSphere_demo/.gitignore b/ExamSphere_demo/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/ExamSphere_demo/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/ExamSphere_demo/.vscode/extensions.json b/ExamSphere_demo/.vscode/extensions.json
new file mode 100644
index 0000000..a7cea0b
--- /dev/null
+++ b/ExamSphere_demo/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["Vue.volar"]
+}
diff --git a/ExamSphere_demo/README.md b/ExamSphere_demo/README.md
new file mode 100644
index 0000000..1511959
--- /dev/null
+++ b/ExamSphere_demo/README.md
@@ -0,0 +1,5 @@
+# Vue 3 + Vite
+
+This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `
+