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 ` + + diff --git a/ExamSphere_demo/package-lock.json b/ExamSphere_demo/package-lock.json new file mode 100644 index 0000000..e62a8e5 --- /dev/null +++ b/ExamSphere_demo/package-lock.json @@ -0,0 +1,885 @@ +{ + "name": "lesson2", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "lesson2", + "version": "0.0.0", + "dependencies": { + "@element-plus/icons-vue": "^2.3.1", + "axios": "^1.7.7", + "bcryptjs": "^2.4.3", + "echarts": "^5.5.1", + "element-china-area-data": "^6.1.0", + "element-plus": "^2.8.6", + "pinia": "^2.3.0", + "vue": "^3.4.37", + "vue-router": "4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.1.2", + "vite": "^5.4.1" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz", + "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "license": "MIT" + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.21.2", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz", + "integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz", + "integrity": "sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz", + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz", + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz", + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "vue": "3.5.13" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "license": "MIT" + }, + "node_modules/@vueuse/core": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz", + "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/metadata": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz", + "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz", + "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "license": "MIT", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmmirror.com/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "license": "MIT" + }, + "node_modules/china-division": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz", + "integrity": "sha512-4uUPAT+1WfqDh5jytq7omdCmHNk3j+k76zEG/2IqaGcYB90c2SwcixttcypdsZ3T/9tN1TTpBDoeZn+Yw/qBEA==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/echarts": { + "version": "5.5.1", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz", + "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.0" + } + }, + "node_modules/element-china-area-data": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/element-china-area-data/-/element-china-area-data-6.1.0.tgz", + "integrity": "sha512-IkpcjwQv2A/2AxFiSoaISZ+oMw1rZCPUSOg5sOCwT5jKc96TaawmKZeY81xfxXsO0QbKxU5LLc6AirhG52hUmg==", + "license": "MIT", + "dependencies": { + "china-division": "^2.7.0" + } + }, + "node_modules/element-plus": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.8.6.tgz", + "integrity": "sha512-fk5jB8V3efM02/4roZ5SWOLArgaYXbxEydZLlXSr+KPAwjNyHBlk2+HO5em8YKo5+RLBoHnn6BaThj6IE4nXoQ==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.1", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.3", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "license": "MIT", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", + "license": "BSD-3-Clause" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/pinia": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.3.0.tgz", + "integrity": "sha512-ohZj3jla0LL0OH5PlLTDMzqKiVw2XARmC1XYLdLWIPBMdhDW/123ZWr4zVAhtJm+aoSkFa13pYXskAvAscIkhQ==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.21.2", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.21.2.tgz", + "integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.21.2", + "@rollup/rollup-android-arm64": "4.21.2", + "@rollup/rollup-darwin-arm64": "4.21.2", + "@rollup/rollup-darwin-x64": "4.21.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.2", + "@rollup/rollup-linux-arm-musleabihf": "4.21.2", + "@rollup/rollup-linux-arm64-gnu": "4.21.2", + "@rollup/rollup-linux-arm64-musl": "4.21.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.2", + "@rollup/rollup-linux-riscv64-gnu": "4.21.2", + "@rollup/rollup-linux-s390x-gnu": "4.21.2", + "@rollup/rollup-linux-x64-gnu": "4.21.2", + "@rollup/rollup-linux-x64-musl": "4.21.2", + "@rollup/rollup-win32-arm64-msvc": "4.21.2", + "@rollup/rollup-win32-ia32-msvc": "4.21.2", + "@rollup/rollup-win32-x64-msvc": "4.21.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, + "node_modules/vite": { + "version": "5.4.3", + "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.3.tgz", + "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz", + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", + "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/zrender": { + "version": "5.6.0", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz", + "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + } + } +} diff --git a/ExamSphere_demo/package.json b/ExamSphere_demo/package.json new file mode 100644 index 0000000..af4af9f --- /dev/null +++ b/ExamSphere_demo/package.json @@ -0,0 +1,26 @@ +{ + "name": "lesson2", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.3.1", + "axios": "^1.7.7", + "bcryptjs": "^2.4.3", + "echarts": "^5.5.1", + "element-china-area-data": "^6.1.0", + "element-plus": "^2.8.6", + "pinia": "^2.3.0", + "vue": "^3.4.37", + "vue-router": "4" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.1.2", + "vite": "^5.4.1" + } +} diff --git a/ExamSphere_demo/public/1.jpg b/ExamSphere_demo/public/1.jpg new file mode 100644 index 0000000..daa4afe Binary files /dev/null and b/ExamSphere_demo/public/1.jpg differ diff --git a/ExamSphere_demo/public/11.jpg b/ExamSphere_demo/public/11.jpg new file mode 100644 index 0000000..689276d Binary files /dev/null and b/ExamSphere_demo/public/11.jpg differ diff --git a/ExamSphere_demo/public/12.png b/ExamSphere_demo/public/12.png new file mode 100644 index 0000000..b923427 Binary files /dev/null and b/ExamSphere_demo/public/12.png differ diff --git a/ExamSphere_demo/public/2.jpg b/ExamSphere_demo/public/2.jpg new file mode 100644 index 0000000..3238996 Binary files /dev/null and b/ExamSphere_demo/public/2.jpg differ diff --git a/ExamSphere_demo/public/21.png b/ExamSphere_demo/public/21.png new file mode 100644 index 0000000..0a738fa Binary files /dev/null and b/ExamSphere_demo/public/21.png differ diff --git a/ExamSphere_demo/public/22.png b/ExamSphere_demo/public/22.png new file mode 100644 index 0000000..8be9008 Binary files /dev/null and b/ExamSphere_demo/public/22.png differ diff --git a/ExamSphere_demo/public/3.png b/ExamSphere_demo/public/3.png new file mode 100644 index 0000000..7c33bac Binary files /dev/null and b/ExamSphere_demo/public/3.png differ diff --git a/ExamSphere_demo/public/31.jpg b/ExamSphere_demo/public/31.jpg new file mode 100644 index 0000000..3bea401 Binary files /dev/null and b/ExamSphere_demo/public/31.jpg differ diff --git a/ExamSphere_demo/public/32.png b/ExamSphere_demo/public/32.png new file mode 100644 index 0000000..2273dfb Binary files /dev/null and b/ExamSphere_demo/public/32.png differ diff --git a/ExamSphere_demo/public/41.png b/ExamSphere_demo/public/41.png new file mode 100644 index 0000000..2cfd58b Binary files /dev/null and b/ExamSphere_demo/public/41.png differ diff --git a/ExamSphere_demo/public/42.jpg b/ExamSphere_demo/public/42.jpg new file mode 100644 index 0000000..a2beecb Binary files /dev/null and b/ExamSphere_demo/public/42.jpg differ diff --git a/ExamSphere_demo/public/adminHead.jpg b/ExamSphere_demo/public/adminHead.jpg new file mode 100644 index 0000000..cfd28f6 Binary files /dev/null and b/ExamSphere_demo/public/adminHead.jpg differ diff --git a/ExamSphere_demo/public/f1.png b/ExamSphere_demo/public/f1.png new file mode 100644 index 0000000..7c33bac Binary files /dev/null and b/ExamSphere_demo/public/f1.png differ diff --git a/ExamSphere_demo/public/user.png b/ExamSphere_demo/public/user.png new file mode 100644 index 0000000..07b82cc Binary files /dev/null and b/ExamSphere_demo/public/user.png differ diff --git a/ExamSphere_demo/public/vite.svg b/ExamSphere_demo/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/ExamSphere_demo/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ExamSphere_demo/src/App.vue b/ExamSphere_demo/src/App.vue new file mode 100644 index 0000000..eeb083b --- /dev/null +++ b/ExamSphere_demo/src/App.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/ExamSphere_demo/src/assets/images/轮播图1.png b/ExamSphere_demo/src/assets/images/轮播图1.png new file mode 100644 index 0000000..80860f5 Binary files /dev/null and b/ExamSphere_demo/src/assets/images/轮播图1.png differ diff --git a/ExamSphere_demo/src/assets/images/轮播图2.png b/ExamSphere_demo/src/assets/images/轮播图2.png new file mode 100644 index 0000000..6bdb27f Binary files /dev/null and b/ExamSphere_demo/src/assets/images/轮播图2.png differ diff --git a/ExamSphere_demo/src/assets/images/轮播图3.jpg b/ExamSphere_demo/src/assets/images/轮播图3.jpg new file mode 100644 index 0000000..94e5376 Binary files /dev/null and b/ExamSphere_demo/src/assets/images/轮播图3.jpg differ diff --git a/ExamSphere_demo/src/assets/images/轮播图4.jpg b/ExamSphere_demo/src/assets/images/轮播图4.jpg new file mode 100644 index 0000000..8965b65 Binary files /dev/null and b/ExamSphere_demo/src/assets/images/轮播图4.jpg differ diff --git a/ExamSphere_demo/src/assets/styles.css b/ExamSphere_demo/src/assets/styles.css new file mode 100644 index 0000000..e69de29 diff --git a/ExamSphere_demo/src/assets/vue.svg b/ExamSphere_demo/src/assets/vue.svg new file mode 100644 index 0000000..770e9d3 --- /dev/null +++ b/ExamSphere_demo/src/assets/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ExamSphere_demo/src/assets/背景1.jpg b/ExamSphere_demo/src/assets/背景1.jpg new file mode 100644 index 0000000..59bbe75 Binary files /dev/null and b/ExamSphere_demo/src/assets/背景1.jpg differ diff --git a/ExamSphere_demo/src/assets/背景2.jpg b/ExamSphere_demo/src/assets/背景2.jpg new file mode 100644 index 0000000..0760a72 Binary files /dev/null and b/ExamSphere_demo/src/assets/背景2.jpg differ diff --git a/ExamSphere_demo/src/assets/背景3.jpg b/ExamSphere_demo/src/assets/背景3.jpg new file mode 100644 index 0000000..aa0a1bd Binary files /dev/null and b/ExamSphere_demo/src/assets/背景3.jpg differ diff --git a/ExamSphere_demo/src/components/1.vue b/ExamSphere_demo/src/components/1.vue new file mode 100644 index 0000000..df559d6 --- /dev/null +++ b/ExamSphere_demo/src/components/1.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/ExamSphere_demo/src/components/2.vue b/ExamSphere_demo/src/components/2.vue new file mode 100644 index 0000000..cbebb79 --- /dev/null +++ b/ExamSphere_demo/src/components/2.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/components/3.vue b/ExamSphere_demo/src/components/3.vue new file mode 100644 index 0000000..0fd9dd3 --- /dev/null +++ b/ExamSphere_demo/src/components/3.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/components/4.vue b/ExamSphere_demo/src/components/4.vue new file mode 100644 index 0000000..67f4b60 --- /dev/null +++ b/ExamSphere_demo/src/components/4.vue @@ -0,0 +1,73 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/components/MarkExam.vue b/ExamSphere_demo/src/components/MarkExam.vue new file mode 100644 index 0000000..a8a1446 --- /dev/null +++ b/ExamSphere_demo/src/components/MarkExam.vue @@ -0,0 +1,230 @@ + + + + + diff --git a/ExamSphere_demo/src/components/MarkList.vue b/ExamSphere_demo/src/components/MarkList.vue new file mode 100644 index 0000000..12b9683 --- /dev/null +++ b/ExamSphere_demo/src/components/MarkList.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/ExamSphere_demo/src/main.js b/ExamSphere_demo/src/main.js new file mode 100644 index 0000000..662c127 --- /dev/null +++ b/ExamSphere_demo/src/main.js @@ -0,0 +1,21 @@ +import { createApp } from 'vue' +import './style.css' + +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' +// import App from './view/student/myExam.vue' +import App from './App.vue' +import router from './router' +import './assets/styles.css'; +import * as ElIconModules from "@element-plus/icons-vue" +import { createPinia } from 'pinia'; +const app = createApp(App) +const pinia = createPinia(); + +for(let iconName in ElIconModules){ + app.component(iconName,ElIconModules[iconName]) +} +app.use(ElementPlus) +app.use(router) +app.use(pinia) +app.mount('#app') diff --git a/ExamSphere_demo/src/request.js b/ExamSphere_demo/src/request.js new file mode 100644 index 0000000..9238306 --- /dev/null +++ b/ExamSphere_demo/src/request.js @@ -0,0 +1,46 @@ +import axios from 'axios' +import { ElMessage } from 'element-plus'; + +const request = axios.create({ + timeout: 3000 +}) + +// request 拦截器 +// 自请求发送前对请求做一些处理 +// 统一加token,对请求参数统一加密 +request.interceptors.request.use(config => { + let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null + if (user) { + config.headers['token'] = user.token; // 设置请求头 + } + // 判断请求是否是文件上传 + if (config.headers['Content-Type'] === 'multipart/form-data') { + delete config.headers['Content-Type']; // 删除 content-type,让浏览器自动处理 + } else { + config.headers['Content-Type'] = 'application/json;charset=utf-8'; // 默认设置为 JSON + } + + return config +}, error => { + return Promise.reject(error) +}); + +// response 拦截器 +// 可以在接口响应后统一处理结果 +request.interceptors.response.use( + response => { + let res = response; + // 如果返回的 code 是 500,显示错误信息 + if (res.data.code === '500') { + ElMessage.error(res.data.msg); + } + + return res; + }, + error => { + console.log('err' + error); + return Promise.reject(error); + } +); + +export default request; diff --git a/ExamSphere_demo/src/router.js b/ExamSphere_demo/src/router.js new file mode 100644 index 0000000..ba0981c --- /dev/null +++ b/ExamSphere_demo/src/router.js @@ -0,0 +1,189 @@ +import { + createRouter, + createWebHashHistory +} from "vue-router" + +const router = createRouter({ + history: createWebHashHistory(), + routes: [{ + path: '/', + redirect: '/login' //默认页面 + }, + { + path: '/index', + name: 'Index', + component: () => import('./view/student/index.vue') + }, + { + path: '/login', + name: 'Login', + component: () => import('./view/Login.vue') + }, + { + path: '/register', + name: 'Register', + component: () => import('./view/Register.vue') + }, + { + path: '/student', + name: 'Student', + component: () => import('./view/student/index.vue'), + redirect: '/student/home', + children: [{ + path: 'home', + name: 'Home', + component: () => import('./view/student/home.vue'), + }, + { + path: 'personalCenter', + name: 'PersonalCenter', + component: () => import('./view/student/personalCenter.vue'), + }, + { + path: 'discussion', + name: 'Discussion', + component: () => import('./view/student/discussion.vue'), + }, + { + path: 'myExam', + name: 'MyEXam', + component: () => import('./view/student/myExam.vue'), + }, + { + path: 'myScore', + name: 'MyScore', + component: () => import('./view/student/myScore.vue'), + }, + { + path: 'exam-detail', + name: 'ExamDetail', + component: () => import('./view/student/examDetail.vue'), + }, + { + path: '/exam-answers/:examId', + name: 'ExamAnswers', + component: () => import('./view/student/examAnswers.vue'), + props: true, + } + ] + }, + { + path: "/teacher", + name: 'Teacher', + component: () => import('./view/teacher/index.vue'), + redirect: '/teacher/firstpage', + children: [{ + path: 'student-info', + name: 'StudentInfo', + component: () => import('./view/teacher/studentInfo.vue') + }, + { + path: 'teacher-info', + name: 'TeacherInfo', + component: () => import('./view/teacher/teacherInfo.vue') + }, + { + path: 'information', + component: () => import('./view/teacher/information.vue') + }, + { + path: 'myinfo', + component: () => import('./view/teacher/myinfo.vue') + }, + { + path: 'firstpage', + component: () => import('./view/teacher/firstpage.vue') + }, + { + path: 'notice', + component: () => import('./view/teacher/notice.vue') + }, + { + path: 'random', + component: () => import('./view/teacher/randomCreate.vue') + }, + { + path: 'hand', + component: () => import('./view/teacher/handCreate.vue') + }, + { + path: 'cor', + component: () => import('./view/teacher/Correct.vue') + }, + { + path:'questions', + component: ()=>import('./view/teacher/questions.vue') + }, + { + path: '/mark-exam', + name: 'MarkExam', + component: () => import('./components/MarkExam.vue'), + props: true + } + ] + }, + { + path: "/admin", + name: 'admin', + component: () => import('./view/admin/index.vue'), + redirect: { + name: 'FirstPage' + }, // Default redirect to firstpage route by name + children: [{ + path: 'student-info', + component: () => import('./view/admin/studentInfo.vue') + }, + { + path: 'teacher-info', + component: () => import('./view/admin/teacherInfo.vue'), + }, + { + path: 'information', + name: 'Information', + component: () => import('./view/admin/information.vue'), + }, + { + path: 'myinfo', + name: 'MyInfo', + component: () => import('./view/admin/myinfo.vue'), + }, + { + path: 'firstpage', + name: 'FirstPage', + component: () => import('./view/admin/firstpage.vue'), + redirect: { + name: 'FirstPage1' + }, + children: [{ + path: '1', + name: 'FirstPage1', + component: () => import('./components/1.vue'), + }, + { + path: '2', + name: 'FirstPage2', + component: () => import('./components/2.vue'), + }, + { + path: '3', + name: 'FirstPage3', + component: () => import('./components/3.vue'), + }, + { + path: '4', + name: 'FirstPage4', + component: () => import('./components/4.vue'), + } + ] + }, + { + path: 'notice', + name: 'Notice', + component: () => import('./view/admin/notice.vue'), + } + ] + } + ] +}) + +export default router diff --git a/ExamSphere_demo/src/stores/user.ts b/ExamSphere_demo/src/stores/user.ts new file mode 100644 index 0000000..f867b30 --- /dev/null +++ b/ExamSphere_demo/src/stores/user.ts @@ -0,0 +1,16 @@ +import { defineStore } from 'pinia'; +import { reactive } from 'vue'; + +export const useUserStore = defineStore('user', () => { + const user = reactive({ + username: '', + avatar: '', + }); + + const setUser = (newUser) => { + user.username = newUser.username || user.username; + user.avatar = newUser.avatar || user.avatar; + }; + + return { user, setUser }; +}); diff --git a/ExamSphere_demo/src/style.css b/ExamSphere_demo/src/style.css new file mode 100644 index 0000000..bb131d6 --- /dev/null +++ b/ExamSphere_demo/src/style.css @@ -0,0 +1,79 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/ExamSphere_demo/src/view/Login.vue b/ExamSphere_demo/src/view/Login.vue new file mode 100644 index 0000000..81d3881 --- /dev/null +++ b/ExamSphere_demo/src/view/Login.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/ExamSphere_demo/src/view/Register.vue b/ExamSphere_demo/src/view/Register.vue new file mode 100644 index 0000000..d9b5e74 --- /dev/null +++ b/ExamSphere_demo/src/view/Register.vue @@ -0,0 +1,159 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/admin/firstpage.vue b/ExamSphere_demo/src/view/admin/firstpage.vue new file mode 100644 index 0000000..735f8ef --- /dev/null +++ b/ExamSphere_demo/src/view/admin/firstpage.vue @@ -0,0 +1,196 @@ + + + + + + + diff --git a/ExamSphere_demo/src/view/admin/index.vue b/ExamSphere_demo/src/view/admin/index.vue new file mode 100644 index 0000000..1a532b1 --- /dev/null +++ b/ExamSphere_demo/src/view/admin/index.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/ExamSphere_demo/src/view/admin/information.vue b/ExamSphere_demo/src/view/admin/information.vue new file mode 100644 index 0000000..115eceb --- /dev/null +++ b/ExamSphere_demo/src/view/admin/information.vue @@ -0,0 +1,110 @@ + + + + + + diff --git a/ExamSphere_demo/src/view/admin/myinfo.vue b/ExamSphere_demo/src/view/admin/myinfo.vue new file mode 100644 index 0000000..74dd799 --- /dev/null +++ b/ExamSphere_demo/src/view/admin/myinfo.vue @@ -0,0 +1,213 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/admin/notice.vue b/ExamSphere_demo/src/view/admin/notice.vue new file mode 100644 index 0000000..98ecddd --- /dev/null +++ b/ExamSphere_demo/src/view/admin/notice.vue @@ -0,0 +1,248 @@ + + + + + diff --git a/ExamSphere_demo/src/view/admin/studentInfo.vue b/ExamSphere_demo/src/view/admin/studentInfo.vue new file mode 100644 index 0000000..05a32db --- /dev/null +++ b/ExamSphere_demo/src/view/admin/studentInfo.vue @@ -0,0 +1,382 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/admin/teacherInfo.vue b/ExamSphere_demo/src/view/admin/teacherInfo.vue new file mode 100644 index 0000000..63c85db --- /dev/null +++ b/ExamSphere_demo/src/view/admin/teacherInfo.vue @@ -0,0 +1,382 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/student/discussion.vue b/ExamSphere_demo/src/view/student/discussion.vue new file mode 100644 index 0000000..0806529 --- /dev/null +++ b/ExamSphere_demo/src/view/student/discussion.vue @@ -0,0 +1,289 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/student/examAnswers.vue b/ExamSphere_demo/src/view/student/examAnswers.vue new file mode 100644 index 0000000..40ab6c5 --- /dev/null +++ b/ExamSphere_demo/src/view/student/examAnswers.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/ExamSphere_demo/src/view/student/examDetail.vue b/ExamSphere_demo/src/view/student/examDetail.vue new file mode 100644 index 0000000..52cbea0 --- /dev/null +++ b/ExamSphere_demo/src/view/student/examDetail.vue @@ -0,0 +1,409 @@ + + + + + + + + + + diff --git a/ExamSphere_demo/src/view/student/home.vue b/ExamSphere_demo/src/view/student/home.vue new file mode 100644 index 0000000..b5f7bed --- /dev/null +++ b/ExamSphere_demo/src/view/student/home.vue @@ -0,0 +1,152 @@ + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/student/index.vue b/ExamSphere_demo/src/view/student/index.vue new file mode 100644 index 0000000..3888d6d --- /dev/null +++ b/ExamSphere_demo/src/view/student/index.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/ExamSphere_demo/src/view/student/myExam.vue b/ExamSphere_demo/src/view/student/myExam.vue new file mode 100644 index 0000000..ade0c7e --- /dev/null +++ b/ExamSphere_demo/src/view/student/myExam.vue @@ -0,0 +1,135 @@ + + + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/student/myScore.vue b/ExamSphere_demo/src/view/student/myScore.vue new file mode 100644 index 0000000..7420e6f --- /dev/null +++ b/ExamSphere_demo/src/view/student/myScore.vue @@ -0,0 +1,161 @@ + + + + + diff --git a/ExamSphere_demo/src/view/student/personalCenter.vue b/ExamSphere_demo/src/view/student/personalCenter.vue new file mode 100644 index 0000000..74dd799 --- /dev/null +++ b/ExamSphere_demo/src/view/student/personalCenter.vue @@ -0,0 +1,213 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/teacher/Correct.vue b/ExamSphere_demo/src/view/teacher/Correct.vue new file mode 100644 index 0000000..5e473cd --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/Correct.vue @@ -0,0 +1,8 @@ + + + + diff --git a/ExamSphere_demo/src/view/teacher/firstpage.vue b/ExamSphere_demo/src/view/teacher/firstpage.vue new file mode 100644 index 0000000..43b2b9c --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/firstpage.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/ExamSphere_demo/src/view/teacher/handCreate.vue b/ExamSphere_demo/src/view/teacher/handCreate.vue new file mode 100644 index 0000000..3fefe04 --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/handCreate.vue @@ -0,0 +1,212 @@ + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/teacher/index.vue b/ExamSphere_demo/src/view/teacher/index.vue new file mode 100644 index 0000000..d11b3d4 --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/index.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/ExamSphere_demo/src/view/teacher/information.vue b/ExamSphere_demo/src/view/teacher/information.vue new file mode 100644 index 0000000..e78f93f --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/information.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/teacher/myinfo.vue b/ExamSphere_demo/src/view/teacher/myinfo.vue new file mode 100644 index 0000000..74dd799 --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/myinfo.vue @@ -0,0 +1,213 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/teacher/notice.vue b/ExamSphere_demo/src/view/teacher/notice.vue new file mode 100644 index 0000000..586aecf --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/notice.vue @@ -0,0 +1,161 @@ + + + + + + diff --git a/ExamSphere_demo/src/view/teacher/questions.vue b/ExamSphere_demo/src/view/teacher/questions.vue new file mode 100644 index 0000000..a44d881 --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/questions.vue @@ -0,0 +1,296 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/teacher/randomCreate.vue b/ExamSphere_demo/src/view/teacher/randomCreate.vue new file mode 100644 index 0000000..24eee3d --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/randomCreate.vue @@ -0,0 +1,172 @@ + + + + + diff --git a/ExamSphere_demo/src/view/teacher/studentInfo.vue b/ExamSphere_demo/src/view/teacher/studentInfo.vue new file mode 100644 index 0000000..ccc4a37 --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/studentInfo.vue @@ -0,0 +1,382 @@ + + + + + \ No newline at end of file diff --git a/ExamSphere_demo/src/view/teacher/teacherInfo.vue b/ExamSphere_demo/src/view/teacher/teacherInfo.vue new file mode 100644 index 0000000..3203276 --- /dev/null +++ b/ExamSphere_demo/src/view/teacher/teacherInfo.vue @@ -0,0 +1,157 @@ + + + + + + diff --git a/ExamSphere_demo/vite.config.js b/ExamSphere_demo/vite.config.js new file mode 100644 index 0000000..05c1740 --- /dev/null +++ b/ExamSphere_demo/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/ExamSphere_demo/yarn.lock b/ExamSphere_demo/yarn.lock new file mode 100644 index 0000000..b5e6097 --- /dev/null +++ b/ExamSphere_demo/yarn.lock @@ -0,0 +1,509 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + +"@babel/parser@^7.25.3": + version "7.26.3" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.3.tgz" + integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA== + dependencies: + "@babel/types" "^7.26.3" + +"@babel/types@^7.26.3": + version "7.26.3" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz" + integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + +"@ctrl/tinycolor@^3.4.1": + version "3.6.1" + resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz" + integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA== + +"@element-plus/icons-vue@^2.3.1": + version "2.3.1" + resolved "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz" + integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@floating-ui/core@^1.6.0": + version "1.6.8" + resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz" + integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA== + dependencies: + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/dom@^1.0.1": + version "1.6.12" + resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz" + integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/utils@^0.2.8": + version "0.2.8" + resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz" + integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== + +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7": + version "2.11.7" + resolved "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz" + integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ== + +"@rollup/rollup-win32-x64-msvc@4.21.2": + version "4.21.2" + resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz" + integrity sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA== + +"@types/estree@1.0.5": + version "1.0.5" + resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/lodash-es@*", "@types/lodash-es@^4.17.6": + version "4.17.12" + resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz" + integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*", "@types/lodash@^4.14.182": + version "4.17.13" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz" + integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg== + +"@types/web-bluetooth@^0.0.16": + version "0.0.16" + resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz" + integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ== + +"@vitejs/plugin-vue@^5.1.2": + version "5.1.3" + resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz" + integrity sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw== + +"@vue/compiler-core@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz" + integrity sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q== + dependencies: + "@babel/parser" "^7.25.3" + "@vue/shared" "3.5.13" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.0" + +"@vue/compiler-dom@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz" + integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA== + dependencies: + "@vue/compiler-core" "3.5.13" + "@vue/shared" "3.5.13" + +"@vue/compiler-sfc@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz" + integrity sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ== + dependencies: + "@babel/parser" "^7.25.3" + "@vue/compiler-core" "3.5.13" + "@vue/compiler-dom" "3.5.13" + "@vue/compiler-ssr" "3.5.13" + "@vue/shared" "3.5.13" + estree-walker "^2.0.2" + magic-string "^0.30.11" + postcss "^8.4.48" + source-map-js "^1.2.0" + +"@vue/compiler-ssr@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz" + integrity sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA== + dependencies: + "@vue/compiler-dom" "3.5.13" + "@vue/shared" "3.5.13" + +"@vue/devtools-api@^6.6.3", "@vue/devtools-api@^6.6.4": + version "6.6.4" + resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz" + integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g== + +"@vue/reactivity@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz" + integrity sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg== + dependencies: + "@vue/shared" "3.5.13" + +"@vue/runtime-core@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz" + integrity sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw== + dependencies: + "@vue/reactivity" "3.5.13" + "@vue/shared" "3.5.13" + +"@vue/runtime-dom@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz" + integrity sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog== + dependencies: + "@vue/reactivity" "3.5.13" + "@vue/runtime-core" "3.5.13" + "@vue/shared" "3.5.13" + csstype "^3.1.3" + +"@vue/server-renderer@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz" + integrity sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA== + dependencies: + "@vue/compiler-ssr" "3.5.13" + "@vue/shared" "3.5.13" + +"@vue/shared@3.5.13": + version "3.5.13" + resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz" + integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ== + +"@vueuse/core@^9.1.0": + version "9.13.0" + resolved "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz" + integrity sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw== + dependencies: + "@types/web-bluetooth" "^0.0.16" + "@vueuse/metadata" "9.13.0" + "@vueuse/shared" "9.13.0" + vue-demi "*" + +"@vueuse/metadata@9.13.0": + version "9.13.0" + resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz" + integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ== + +"@vueuse/shared@9.13.0": + version "9.13.0" + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz" + integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw== + dependencies: + vue-demi "*" + +async-validator@^4.2.5: + version "4.2.5" + resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz" + integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.npmmirror.com/axios/-/axios-1.7.7.tgz" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.npmmirror.com/bcryptjs/-/bcryptjs-2.4.3.tgz" + integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ== + +china-division@^2.7.0: + version "2.7.0" + resolved "https://registry.npmmirror.com/china-division/-/china-division-2.7.0.tgz" + integrity sha512-4uUPAT+1WfqDh5jytq7omdCmHNk3j+k76zEG/2IqaGcYB90c2SwcixttcypdsZ3T/9tN1TTpBDoeZn+Yw/qBEA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +csstype@^3.1.3: + version "3.1.3" + resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +dayjs@^1.11.3: + version "1.11.13" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +echarts@^5.5.1: + version "5.5.1" + resolved "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz" + integrity sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA== + dependencies: + tslib "2.3.0" + zrender "5.6.0" + +element-china-area-data@^6.1.0: + version "6.1.0" + resolved "https://registry.npmmirror.com/element-china-area-data/-/element-china-area-data-6.1.0.tgz" + integrity sha512-IkpcjwQv2A/2AxFiSoaISZ+oMw1rZCPUSOg5sOCwT5jKc96TaawmKZeY81xfxXsO0QbKxU5LLc6AirhG52hUmg== + dependencies: + china-division "^2.7.0" + +element-plus@^2.8.6: + version "2.8.6" + resolved "https://registry.npmjs.org/element-plus/-/element-plus-2.8.6.tgz" + integrity sha512-fk5jB8V3efM02/4roZ5SWOLArgaYXbxEydZLlXSr+KPAwjNyHBlk2+HO5em8YKo5+RLBoHnn6BaThj6IE4nXoQ== + dependencies: + "@ctrl/tinycolor" "^3.4.1" + "@element-plus/icons-vue" "^2.3.1" + "@floating-ui/dom" "^1.0.1" + "@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7" + "@types/lodash" "^4.14.182" + "@types/lodash-es" "^4.17.6" + "@vueuse/core" "^9.1.0" + async-validator "^4.2.5" + dayjs "^1.11.3" + escape-html "^1.0.3" + lodash "^4.17.21" + lodash-es "^4.17.21" + lodash-unified "^1.0.2" + memoize-one "^6.0.0" + normalize-wheel-es "^1.2.0" + +entities@^4.5.0: + version "4.5.0" + resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + +escape-html@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +lodash-es@*, lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + +lodash-unified@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz" + integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ== + +lodash@*, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +magic-string@^0.30.11: + version "0.30.17" + resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +memoize-one@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz" + integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +normalize-wheel-es@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz" + integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +pinia@^2.3.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/pinia/-/pinia-2.3.0.tgz" + integrity sha512-ohZj3jla0LL0OH5PlLTDMzqKiVw2XARmC1XYLdLWIPBMdhDW/123ZWr4zVAhtJm+aoSkFa13pYXskAvAscIkhQ== + dependencies: + "@vue/devtools-api" "^6.6.3" + vue-demi "^0.14.10" + +postcss@^8.4.43, postcss@^8.4.48: + version "8.4.49" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz" + integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +rollup@^4.20.0: + version "4.21.2" + resolved "https://registry.npmmirror.com/rollup/-/rollup-4.21.2.tgz" + integrity sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.21.2" + "@rollup/rollup-android-arm64" "4.21.2" + "@rollup/rollup-darwin-arm64" "4.21.2" + "@rollup/rollup-darwin-x64" "4.21.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.21.2" + "@rollup/rollup-linux-arm-musleabihf" "4.21.2" + "@rollup/rollup-linux-arm64-gnu" "4.21.2" + "@rollup/rollup-linux-arm64-musl" "4.21.2" + "@rollup/rollup-linux-powerpc64le-gnu" "4.21.2" + "@rollup/rollup-linux-riscv64-gnu" "4.21.2" + "@rollup/rollup-linux-s390x-gnu" "4.21.2" + "@rollup/rollup-linux-x64-gnu" "4.21.2" + "@rollup/rollup-linux-x64-musl" "4.21.2" + "@rollup/rollup-win32-arm64-msvc" "4.21.2" + "@rollup/rollup-win32-ia32-msvc" "4.21.2" + "@rollup/rollup-win32-x64-msvc" "4.21.2" + fsevents "~2.3.2" + +source-map-js@^1.2.0, source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +tslib@2.3.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + +vite@^5.0.0, vite@^5.4.1: + version "5.4.3" + resolved "https://registry.npmmirror.com/vite/-/vite-5.4.3.tgz" + integrity sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +vue-demi@*, vue-demi@^0.14.10: + version "0.14.10" + resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz" + integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg== + +vue-router@4: + version "4.4.5" + resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz" + integrity sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q== + dependencies: + "@vue/devtools-api" "^6.6.4" + +"vue@^2.7.0 || ^3.5.11", "vue@^3.0.0-0 || ^2.6.0", vue@^3.2.0, vue@^3.2.25, vue@^3.4.37, vue@3.5.13: + version "3.5.13" + resolved "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz" + integrity sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ== + dependencies: + "@vue/compiler-dom" "3.5.13" + "@vue/compiler-sfc" "3.5.13" + "@vue/runtime-dom" "3.5.13" + "@vue/server-renderer" "3.5.13" + "@vue/shared" "3.5.13" + +zrender@5.6.0: + version "5.6.0" + resolved "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz" + integrity sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg== + dependencies: + tslib "2.3.0" diff --git a/test.sql b/test.sql new file mode 100644 index 0000000..a4fc173 --- /dev/null +++ b/test.sql @@ -0,0 +1,190 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- 主机: 127.0.0.1:3306 +-- 生成日期: 2024-12-25 03:42:26 +-- 服务器版本: 8.0.31 +-- PHP 版本: 7.4.33 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- 数据库: `test` +-- + +-- -------------------------------------------------------- + +-- +-- 表的结构 `answer` +-- + +DROP TABLE IF EXISTS `answer`; +CREATE TABLE IF NOT EXISTS `answer` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `exam_id` bigint DEFAULT NULL, + `user_id` bigint DEFAULT NULL, + `teacher_id` bigint DEFAULT NULL, + `answers` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, + `score` varchar(255) DEFAULT NULL, + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, + `question_ids` varchar(255) DEFAULT NULL, + `is_score` varchar(255) DEFAULT NULL, + `submit_Time` datetime DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=205 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- +-- 转存表中的数据 `answer` +-- + +INSERT INTO `answer` (`id`, `exam_id`, `user_id`, `teacher_id`, `answers`, `score`, `name`, `question_ids`, `is_score`, `submit_Time`) VALUES +(195, 4, 4, 3, '[{\"id\":1,\"name\":\"什么是数据库?\",\"type\":\"单选题\",\"options\":[\"A. 数据存储\",\"B. 数据库\",\"C. 数据表\",\"D. 数据项\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]}]', '10', '考试2', '1', '已评分', '2024-12-16 16:44:33'), +(197, 5, 4, 3, '[{\"id\":1,\"name\":\"什么是数据库?\",\"type\":\"单选题\",\"options\":[\"A. 数据存储\",\"B. 数据库\",\"C. 数据表\",\"D. 数据项\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]},{\"id\":2,\"name\":\"以下哪种语言是面向对象的?\",\"type\":\"单选题\",\"options\":[\"A. Java\",\"B. C\",\"C. Assembly\",\"D. Python\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]},{\"id\":4,\"name\":\"HTML是什么的缩写?\",\"type\":\"单选题\",\"options\":[\"A. HyperText Markup Language\",\"B. HyperText Modeling Language\",\"C. HyperText Management Language\",\"D. HyperText Method Language\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]},{\"id\":5,\"name\":\"以下哪些是Python的数据类型?\",\"type\":\"多选题\",\"options\":[\"A. Cascading Style Sheets\",\"B. Centralized Style Sheets\",\"C. Creative Style Sheets\",\"D. Computer Style Sheets\"],\"answer\":\"ABCD\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":\"0\",\"userAnswers\":[\"A\",\"B\",\"C\",\"D\"]},{\"id\":6,\"name\":\"什么是CSS?\",\"type\":\"单选题\",\"options\":[\"A. Cascading Style Sheets\",\"B. Centralized Style Sheets\",\"C. Creative Style Sheets\",\"D. Computer Style Sheets\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]}]', '50', '考试3', '1,2,4,5,6', '已评分', '2024-12-16 22:12:23'), +(198, 4, 1, 3, '[{\"id\":1,\"name\":\"什么是数据库?\",\"type\":\"单选题\",\"options\":[\"A. 数据存储\",\"B. 数据库\",\"C. 数据表\",\"D. 数据项\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]}]', '10', '考试2', '1', '已评分', '2024-12-17 15:11:42'), +(202, 5, 1, 3, '[{\"id\":1,\"name\":\"什么是数据库?\",\"type\":\"单选题\",\"options\":[\"A. 数据存储\",\"B. 数据库\",\"C. 数据表\",\"D. 数据项\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]},{\"id\":2,\"name\":\"以下哪种语言是面向对象的?\",\"type\":\"单选题\",\"options\":[\"A. Java\",\"B. C\",\"C. Assembly\",\"D. Python\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]},{\"id\":4,\"name\":\"HTML是什么的缩写?\",\"type\":\"单选题\",\"options\":[\"A. HyperText Markup Language\",\"B. HyperText Modeling Language\",\"C. HyperText Management Language\",\"D. HyperText Method Language\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]},{\"id\":5,\"name\":\"以下哪些是Python的数据类型?\",\"type\":\"多选题\",\"options\":[\"A. Cascading Style Sheets\",\"B. Centralized Style Sheets\",\"C. Creative Style Sheets\",\"D. Computer Style Sheets\"],\"answer\":\"ABCD\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\",\"B\",\"C\",\"D\"]},{\"id\":6,\"name\":\"什么是CSS?\",\"type\":\"单选题\",\"options\":[\"A. Cascading Style Sheets\",\"B. Centralized Style Sheets\",\"C. Creative Style Sheets\",\"D. Computer Style Sheets\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]}]', '50', '考试3', '1,2,4,5,6', '未评分', '2024-12-17 15:31:22'), +(203, 3, 4, 2, '[{\"id\":1,\"name\":\"什么是数据库?\",\"type\":\"单选题\",\"options\":[\"A. 数据存储\",\"B. 数据库\",\"C. 数据表\",\"D. 数据项\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]},{\"id\":2,\"name\":\"以下哪种语言是面向对象的?\",\"type\":\"单选题\",\"options\":[\"A. Java\",\"B. C\",\"C. Assembly\",\"D. Python\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]},{\"id\":4,\"name\":\"HTML是什么的缩写?\",\"type\":\"单选题\",\"options\":[\"A. HyperText Markup Language\",\"B. HyperText Modeling Language\",\"C. HyperText Management Language\",\"D. HyperText Method Language\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\"]},{\"id\":5,\"name\":\"以下哪些是Python的数据类型?\",\"type\":\"多选题\",\"options\":[\"A. Cascading Style Sheets\",\"B. Centralized Style Sheets\",\"C. Creative Style Sheets\",\"D. Computer Style Sheets\"],\"answer\":\"ABCD\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"A\",\"B\",\"C\",\"D\"]},{\"id\":25,\"name\":\"简述一下计算机的组成原理?\",\"type\":\"主观题\",\"options\":[],\"answer\":\"123\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":\"9\",\"userAnswers\":[\"123\"]},{\"id\":24,\"name\":\"1+1=?\",\"type\":\"单选题\",\"options\":[\"A:1\",\"B:2\",\"C:3\",\"D:4\"],\"answer\":\"B\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"B\"]},{\"id\":21,\"name\":\"1+1=?\",\"type\":\"填空题\",\"options\":[],\"answer\":\"2\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"2\"]},{\"id\":19,\"name\":\"1\",\"type\":\"单选题\",\"options\":[\"A:1\",\"B:1\",\"C:1\",\"D:1\"],\"answer\":\"D\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":10,\"userAnswers\":[\"D\"]}]', '79', '123', '1,2,4,5,25,24,21,19', '已评分', '2024-12-19 13:50:44'), +(204, 13, 4, 2, '[{\"id\":1,\"name\":\"什么是数据库?\",\"type\":\"单选题\",\"options\":[\"A. 数据存储\",\"B. 数据库\",\"C. 数据表\",\"D. 数据项\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]},{\"id\":2,\"name\":\"以下哪种语言是面向对象的?\",\"type\":\"单选题\",\"options\":[\"A. Java\",\"B. C\",\"C. Assembly\",\"D. Python\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]},{\"id\":4,\"name\":\"HTML是什么的缩写?\",\"type\":\"单选题\",\"options\":[\"A. HyperText Markup Language\",\"B. HyperText Modeling Language\",\"C. HyperText Management Language\",\"D. HyperText Method Language\"],\"answer\":\"A\",\"score\":10,\"userId\":null,\"user\":null,\"userScore\":0,\"userAnswers\":[\"A\"]}]', '30', '试卷10', '1,2,4', '已评分', '2024-12-24 23:40:56'); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `comment` +-- + +DROP TABLE IF EXISTS `comment`; +CREATE TABLE IF NOT EXISTS `comment` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `username` varchar(255) NOT NULL, + `content` varchar(255) DEFAULT NULL, + `time` datetime(6) DEFAULT NULL, + `parent_id` bigint DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- +-- 转存表中的数据 `comment` +-- + +INSERT INTO `comment` (`id`, `username`, `content`, `time`, `parent_id`) VALUES +(6, 'chx', '123', '2024-12-23 14:24:17.637000', NULL), +(7, 'chx', '456', '2024-12-23 15:59:38.945000', NULL), +(8, 'chx2', '@chx 46', '2024-12-23 16:00:06.741000', 6); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `exam` +-- + +DROP TABLE IF EXISTS `exam`; +CREATE TABLE IF NOT EXISTS `exam` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '考试标题', + `img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '封面图', + `start_time` datetime DEFAULT NULL COMMENT '考试开始时间', + `end_time` datetime DEFAULT NULL COMMENT '考试结束时间', + `question_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '试题列表', + `total` int DEFAULT NULL COMMENT '考试总分', + `user_id` int DEFAULT NULL COMMENT '用户ID', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='考试表' ROW_FORMAT=DYNAMIC; + +-- +-- 转存表中的数据 `exam` +-- + +INSERT INTO `exam` (`id`, `title`, `img`, `start_time`, `end_time`, `question_ids`, `total`, `user_id`) VALUES +(2, '测试', 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg', '2024-05-29 00:00:00', '2024-12-16 16:42:00', '1,2,4,5,6', 50, 2), +(3, '123', 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg', '2024-06-08 08:00:00', '2024-12-20 19:51:00', '1,2,4,5,25,24,21,19', 110, 2), +(4, '考试2', 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg', '2024-11-05 03:55:00', '2024-12-31 12:00:00', '1', 10, 3), +(5, '考试3', 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg', '2024-11-05 03:55:00', '2024-12-31 19:12:00', '1,2,4,5,6', 50, 3); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `question` +-- + +DROP TABLE IF EXISTS `question`; +CREATE TABLE IF NOT EXISTS `question` ( + `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '题目文本', + `type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '题型', + `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择题选项', + `answer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '正确答案', + `score` int DEFAULT NULL COMMENT '分值', + `user_id` int DEFAULT NULL COMMENT '用户ID', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='试题表' ROW_FORMAT=DYNAMIC; + +-- +-- 转存表中的数据 `question` +-- + +INSERT INTO `question` (`id`, `name`, `type`, `options`, `answer`, `score`, `user_id`) VALUES +(1, '什么是数据库?', '单选题', '[\"A. 数据存储\", \"B. 数据库\", \"C. 数据表\", \"D. 数据项\"]', 'A', 10, 3), +(2, '以下哪种语言是面向对象的?', '单选题', '[\"A. Java\", \"B. C\", \"C. Assembly\", \"D. Python\"]', 'A', 10, 3), +(4, 'HTML是什么的缩写?', '单选题', '[\"A. HyperText Markup Language\", \"B. HyperText Modeling Language\", \"C. HyperText Management Language\", \"D. HyperText Method Language\"]', 'A', 10, 3), +(5, '以下哪些是Python的数据类型?', '多选题', '[\"A. Cascading Style Sheets\", \"B. Centralized Style Sheets\", \"C. Creative Style Sheets\", \"D. Computer Style Sheets\"]', 'ABCD', 10, 3), +(6, '什么是CSS?', '单选题', '[\"A. Cascading Style Sheets\", \"B. Centralized Style Sheets\", \"C. Creative Style Sheets\", \"D. Computer Style Sheets\"]', 'A', 10, 3), +(9, 'React是哪家公司开发的?', '多选题', '[\"A. Facebook\", \"B. Google\", \"C. Microsoft\", \"D. Apple\"]', 'ABCD', 10, 3), +(10, '机器学习的主要分类有哪些?', '多选题', '[\"A. Cascading Style Sheets\", \"B. Centralized Style Sheets\", \"C. Creative Style Sheets\", \"D. Computer Style Sheets\"]', 'ABCD', 10, 3), +(13, '1+2=?', '单选题', '[\"A. 1\", \"B. 2\", \"C. 3\", \"D. 4\"]', 'C', 10, 3), +(14, '1+1+1+1=?', '单选题', '[\"A. 1\", \"B. 2\", \"C. 3\", \"D. 4\"]', 'D', 10, 3), +(15, '1+0=?', '单选题', '[\"A. 1\", \"B. 22222\", \"C. 3\", \"D. 4\"]\n', '2', 10, 3), +(16, '10+10=?', '单选题', '[\"A. 1\", \"B. 22222\", \"C. 3\", \"D. 20\"]\n', 'D', 10, 3), +(17, '1+2+3=?', '单选题', '[\"A. 1\", \"B. 6\", \"C. 3\", \"D. 20\"]', 'D', 10, 3), +(18, '1+10=?', '单选题', '[\"A:11\",\"B:22\",\"C:22\",\"D:113\"]', 'D', 10, 3), +(19, '1', '单选题', '[\"A:1\",\"B:1\",\"C:1\",\"D:1\"]', 'D', 10, 3), +(20, '1+1=2对吗', '判断题', '', '对', 10, 3), +(21, '1+1=?', '填空题', '{\"0\":\"A:\",\"1\":\"B:\",\"2\":\"C:\",\"3\":\"D:\"}', '2', 10, 3), +(22, '1+1=2?', '判断题', '', '对', 10, 3), +(23, '1+1+1=3?', '判断题', '', '对', 10, 3), +(24, '1+1=?', '单选题', '[\"A:1\",\"B:2\",\"C:3\",\"D:4\"]', 'B', 10, 3), +(25, '简述一下计算机的组成原理?', '主观题', NULL, '计算机的组成原理', 10, 3); + +-- -------------------------------------------------------- + +-- +-- 表的结构 `user` +-- + +DROP TABLE IF EXISTS `user`; +CREATE TABLE IF NOT EXISTS `user` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `username` varchar(50) NOT NULL, + `password` varchar(100) NOT NULL, + `role` varchar(20) NOT NULL COMMENT '用户角色:student, teacher, admin', + `email` varchar(255) DEFAULT NULL, + `mobile` varchar(255) DEFAULT NULL, + `avatar` varchar(255) DEFAULT NULL, + `gender` varchar(255) DEFAULT NULL, + `address` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `username` (`username`) +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- +-- 转存表中的数据 `user` +-- + +INSERT INTO `user` (`id`, `username`, `password`, `role`, `email`, `mobile`, `avatar`, `gender`, `address`) VALUES +(1, 'student', '$2a$10$fclE/Dgq1Ej5fEG9cNwIZu.Me0aFCbGy3naccAZOa/Fa/1tBAsZGq', 'student', NULL, NULL, 'http://localhost:8080/file/download?name=bf0d4510-f8db-4afb-bf9e-4fa76da41b4e_user.png', '男', ''), +(2, 'teacher', '$2a$10$fclE/Dgq1Ej5fEG9cNwIZu.Me0aFCbGy3naccAZOa/Fa/1tBAsZGq', 'teacher', NULL, NULL, NULL, NULL, NULL), +(3, 'admin', '$2a$10$fclE/Dgq1Ej5fEG9cNwIZu.Me0aFCbGy3naccAZOa/Fa/1tBAsZGq', 'admin', NULL, NULL, NULL, NULL, NULL), +(4, 'chx', '$2a$10$fclE/Dgq1Ej5fEG9cNwIZu.Me0aFCbGy3naccAZOa/Fa/1tBAsZGq', 'student', '12313156', '1233456', 'http://localhost:8080/file/download?name=c5ab3687-2f15-428e-a8e9-4e07bb1ef56d_user.png', '男', '北京市 市辖区 东城区'), +(18, 'chx2', '$2a$10$TtgftGGLDzMgy7TOPbnBJuXZpybkFApZMaZPA8yPg3iqeMJR8CZNm', 'student', NULL, NULL, 'http://localhost:8080/file/download?name=24d23157-044d-46b2-b6f2-759ce9e6d287_背景1.jpg', NULL, ''); +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;