commit eac3915a112d5f8af450ee3310fd580a4289e57f
Author: 曙光 <5248283+lsg15829561090@user.noreply.gitee.com>
Date: Thu Feb 27 21:35:01 2025 +0800
feat-0330: INIT PROJECT
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/System(7).iml b/.idea/System(7).iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/System(7).iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..e69a7a0
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..c92fd3c
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ mysql.8
+ true
+ true
+ com.mysql.cj.jdbc.Driver
+ jdbc:mysql://127.0.0.1:3309/jingsaisystem?useSSL=false&serverTimezone=UTC
+
+
+
+
+
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..665e12f
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..ca2eeaf
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..636e4fc
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/System/.gitignore b/System/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/System/.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/System/pom.xml b/System/pom.xml
new file mode 100644
index 0000000..bea4f41
--- /dev/null
+++ b/System/pom.xml
@@ -0,0 +1,219 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.17
+
+
+ com.example
+ System
+ 0.0.1-SNAPSHOT
+ System
+ System
+
+ 11
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.67
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.5
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+
+
+ com.squareup.okhttp3
+ okhttp
+ 4.10.0
+
+
+
+ com.squareup.okio
+ okio
+ 2.10.0
+
+
+ org.springframework.boot
+ spring-boot
+ 2.7.8
+
+
+ org.projectlombok
+ lombok
+
+
+
+ com.alibaba
+ druid
+ 1.1.20
+
+
+
+ cn.hutool
+ hutool-all
+ 5.7.22
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter-test
+ 3.0.3
+ test
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.3.1
+
+
+ org.postgresql
+ postgresql
+ runtime
+
+
+ org.apache.poi
+ poi
+ 5.2.4
+
+
+ org.apache.poi
+ poi-ooxml
+ 5.2.4
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+ jakarta.validation
+ jakarta.validation-api
+ 2.0.2
+
+
+ org.springframework.security
+ spring-security-core
+ 5.4.2
+
+
+ dom4j
+ dom4j
+ 1.1
+
+
+ org.aspectj
+ aspectjweaver
+ 1.9.6
+
+
+ mysql
+ mysql-connector-java
+ 8.0.28
+ runtime
+
+
+ org.hibernate
+ hibernate-core
+ 5.6.15.Final
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.aliyun.oss
+ aliyun-sdk-oss
+ 3.15.0
+
+
+
+
+ joda-time
+ joda-time
+ 2.10.1
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 11
+ 11
+
+
+
+
+
+
diff --git a/System/sjk.sql b/System/sjk.sql
new file mode 100644
index 0000000..049fe6c
--- /dev/null
+++ b/System/sjk.sql
@@ -0,0 +1,152 @@
+
+--学院
+CREATE TABLE IF NOT EXISTS college_table (
+ college_id SERIAL PRIMARY KEY,
+ college_name VARCHAR(255) DEFAULT NULL
+);
+--专业
+CREATE TABLE IF NOT EXISTS major_table (
+ major_table_id SERIAL PRIMARY KEY,
+ major_table_name VARCHAR(255) DEFAULT NULL,
+ college_id INT DEFAULT NULL
+);
+--用户表
+CREATE TABLE IF NOT EXISTS user_table (
+ user_id SERIAL PRIMARY KEY,
+ user_name VARCHAR(50) NOT NULL,
+ s_t_id VARCHAR(20) NOT NULL,
+ user_password VARCHAR(255) NOT NULL,
+ user_privileges INT NOT NULL DEFAULT 1,
+ email VARCHAR(50) NOT NULL,
+ college_id INT NOT NULL,
+ major_table_id INT DEFAULT NULL,
+ phone VARCHAR(20) DEFAULT NULL,
+ teacher_title VARCHAR(50) DEFAULT NULL,
+ birthdate DATE DEFAULT NULL,
+ gender VARCHAR(10) DEFAULT NULL CHECK (gender IN ('男', '女')),
+ user_status INT DEFAULT 0
+);
+--竞赛表
+CREATE TABLE IF NOT EXISTS competition_table (
+ competition_id SERIAL PRIMARY KEY,
+ competition_name VARCHAR(50) NOT NULL,
+ user_id INT NOT NULL,
+ registration_start_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
+ registration_end_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
+ announcement_link VARCHAR(255) DEFAULT '',
+ competition_status INT DEFAULT 0
+);
+--资料表
+CREATE TABLE IF NOT EXISTS information_table (
+ profile_id SERIAL PRIMARY KEY,
+ user_id INT NOT NULL,
+ competition_id INT NOT NULL,
+ personal_info TEXT,
+ related_data TEXT,
+ CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES user_table (user_id),
+ CONSTRAINT fk_competition_id FOREIGN KEY (competition_id) REFERENCES competition_table (competition_id),
+);
+--报名表
+CREATE TABLE IF NOT EXISTS registration_table (
+ registration_id SERIAL PRIMARY KEY,
+ student_id INT NOT NULL,
+ competition_id INT NOT NULL,
+ team_leader_id INT DEFAULT NULL,
+ competition_type VARCHAR(50) NOT NULL DEFAULT '校级' CHECK (competition_type IN ('国家级', '省级', '市/区级', '校级', '院级', '其他')),
+ award_level VARCHAR(50) DEFAULT NULL CHECK (award_level IN ('未获奖', '一等奖', '二等奖', '三等奖')),
+ registration_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
+ registration_status VARCHAR(50) NOT NULL DEFAULT '等待学校审核' CHECK (registration_status IN ('等待学校审核', '等待主办方审核', '成功报名', '已取消')),
+ certificate_path VARCHAR(255) DEFAULT '',
+ additional_info VARCHAR(255) DEFAULT ''
+);
+--文章表
+CREATE TABLE IF NOT EXISTS article_table (
+ article_id SERIAL PRIMARY KEY,
+ user_id INT NOT NULL,
+ article_title TEXT NOT NULL,
+ brief_content TEXT,
+ article_content TEXT NOT NULL,
+ article_type VARCHAR(50) NOT NULL CHECK (article_type IN ('公告', '活动', '讨论')),
+ publish_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
+ competition_id INT
+);
+--评论表
+CREATE TABLE IF NOT EXISTS comment_table (
+ comment_id SERIAL PRIMARY KEY,
+ user_id INT NOT NULL,
+ article_id INT NOT NULL,
+ comment_content TEXT NOT NULL,
+ publish_time TIMESTAMP WITHOUT TIME ZONE NOT NULL
+);
+--设置外键约束
+ALTER TABLE major_table ADD CONSTRAINT fk_college_id FOREIGN KEY (college_id) REFERENCES college_table (college_id);
+ALTER TABLE user_table ADD CONSTRAINT fk_college_id FOREIGN KEY (college_id) REFERENCES college_table (college_id);
+ALTER TABLE user_table ADD CONSTRAINT fk_major_table_id FOREIGN KEY (major_table_id) REFERENCES major_table (major_table_id);
+ALTER TABLE competition_table ADD CONSTRAINT competition_fk_user_id FOREIGN KEY (user_id) REFERENCES user_table (user_id);
+ALTER TABLE registration_table ADD CONSTRAINT fk_competition_id FOREIGN KEY (competition_id) REFERENCES competition_table (competition_id);
+ALTER TABLE registration_table ADD CONSTRAINT registration_fk_student_id FOREIGN KEY (student_id) REFERENCES user_table (user_id);
+ALTER TABLE registration_table ADD CONSTRAINT registration_fk_team_leader_id FOREIGN KEY (team_leader_id) REFERENCES user_table (user_id);
+ALTER TABLE article_table ADD CONSTRAINT article_fk_user_id FOREIGN KEY (user_id) REFERENCES user_table (user_id);
+ALTER TABLE comment_table ADD CONSTRAINT comment_fk_user_id FOREIGN KEY (user_id) REFERENCES user_table (user_id);
+ALTER TABLE comment_table ADD CONSTRAINT fk_article_id FOREIGN KEY (article_id) REFERENCES article_table (article_id);
+ALTER TABLE article_table
+ ADD CONSTRAINT fk_article_competition_id
+ FOREIGN KEY (competition_id)
+ REFERENCES competition_table (competition_id)
+ ON DELETE SET NULL;
+
+
+--插入数据
+INSERT INTO college_table (college_name) VALUES
+ (NULL),
+ ('会计学院'),
+ ('经济贸易学院'),
+ ('电信工程学院'),
+ ('服装与技术贸易学院'),
+ ('医药工程学院'),
+ ('人文与艺术学院'),
+ ('计算级学院'),
+ ('国际教育学院'),
+ ('镐京书院'),
+ ('外语教育部'),
+ ('思政部'),
+ ('体育部');
+INSERT INTO major_table (major_table_name, college_id) VALUES
+ (NULL, 1),
+ ('税收学', 2),
+ ('会计学', 2),
+ ('审计学', 2),
+ ('金融工程', 2),
+ ('财务管理', 2),
+ ('国际经济与贸易', 3),
+ ('市场营销', 3),
+ ('工商管理', 3),
+ ('人力资源管理', 3),
+ ('行政管理', 3),
+ ('电子商务', 3),
+ ('电气工程及其自动化', 4),
+ ('电子信息工程', 4),
+ ('服装设计', 5),
+ ('管理运营', 5),
+ ('服装科技', 5),
+ ('健康服务与管理', 7),
+ ('药物制剂', 7),
+ ('计算机科学与技术', 8),
+ ('网络工程', 8),
+ ('物联网工程', 8),
+ ('智能科学与技术', 8);
+INSERT INTO user_table (user_name, s_t_id, user_password, user_privileges, email, college_id, major_table_id, phone, teacher_title, birthdate, gender, user_status) VALUES
+ ('史旺', 'Admin', '1234', 0, '1919093209@qq.com', 7, 1, '', '', NULL, NULL, NULL),
+ ('史旺', '213010248', '0248', 1, '1919093209@qq.com', 7, 20, '17342351231', '', '2002-04-04', '男', NULL),
+ ('刘舒光', '213010127', '0127', 2, 'qqsyun@gmail.com', 7, 20, '18509144920', '教授', NULL, NULL, 0);
+INSERT INTO competition_table (competition_name, user_id, registration_start_time, registration_end_time, announcement_link, competition_status) VALUES
+ ('中国大学生计算机设计大赛', 3, '2023-04-01 00:00:00', '2023-05-01 00:00:00', 'https://jsjds.blcu.edu.cn/', 0);
+INSERT INTO registration_table (student_id, competition_id, team_leader_id, competition_type, award_level, registration_time, registration_status, certificate_path, additional_info) VALUES
+ (2, 1, 2, '校级', '未获奖', '2023-04-02 00:00:00', '成功报名', NULL, '');
+INSERT INTO article_table (user_id, article_title, brief_content, article_content, article_type, publish_time) VALUES
+ (3, '全国大学生计算级设计大赛报名通道开启!', '第17届全国大学生计算级设计大赛报名通道开启,请大家踊跃报名!', '中国大学生计算机设计大赛是非营利的、公益性的、科技型的群众活动。大赛的生命线与遵从的原则是“三公”,即公开、公平、公正。公平、公正是灵魂和基础,公开是公平、公正的保障。', '公告', '2023-03-01 08:00:00'),
+ (2, '关于开展科研讨论会的通知', '', '科研讨论会', '活动', '2023-03-05 09:00:00');
+INSERT INTO comment_table (user_id, article_id, comment_content, publish_time) VALUES
+ (2, 1, '非常期待!', '2023-03-01 09:00:00');
+
+
diff --git a/System/spring-blog.log b/System/spring-blog.log
new file mode 100644
index 0000000..1053531
--- /dev/null
+++ b/System/spring-blog.log
@@ -0,0 +1,208 @@
+2024-04-25 13:29:04.765 INFO 36228 --- [main] c.example.system.SystemApplicationTests : Starting SystemApplicationTests using Java 22.0.1 on LAPTOP-65TM63SL with PID 36228 (started by 12705 in C:\Users\12705\Desktop\竞赛管理系统spring boot-2024.4.23 20:55 (2)\竞赛管理系统spring boot-2024.4.23 20:55\竞赛管理系统spring boot-2024.4.23 20:55\System)
+2024-04-25 13:29:04.772 INFO 36228 --- [main] c.example.system.SystemApplicationTests : No active profile set, falling back to 1 default profile: "default"
+2024-04-25 13:29:06.085 INFO 36228 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2024-04-25 13:29:06.247 INFO 36228 --- [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 145 ms. Found 6 JPA repository interfaces.
+2024-04-25 13:29:07.264 INFO 36228 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
+2024-04-25 13:29:08.408 INFO 36228 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
+2024-04-25 13:29:08.498 INFO 36228 --- [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
+2024-04-25 13:29:08.643 INFO 36228 --- [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.15.Final
+2024-04-25 13:29:08.941 INFO 36228 --- [main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
+2024-04-25 13:29:09.267 INFO 36228 --- [main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL92Dialect
+2024-04-25 13:29:10.365 INFO 36228 --- [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
+2024-04-25 13:29:10.383 INFO 36228 --- [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2024-04-25 13:29:12.569 WARN 36228 --- [main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverEndpointExporter' defined in class path resource [com/example/system/ai/WebSocketConfig1.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
+2024-04-25 13:29:12.574 INFO 36228 --- [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2024-04-25 13:29:12.583 INFO 36228 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
+2024-04-25 13:29:12.589 INFO 36228 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
+2024-04-25 13:29:12.611 INFO 36228 --- [main] ConditionEvaluationReportLoggingListener :
+
+Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
+2024-04-25 13:29:12.672 ERROR 36228 --- [main] o.s.boot.SpringApplication : Application run failed
+
+org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverEndpointExporter' defined in class path resource [com/example/system/ai/WebSocketConfig1.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:921) ~[spring-context-5.3.30.jar:5.3.30]
+ at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.30.jar:5.3.30]
+ at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.8.jar:2.7.8]
+ at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.8.jar:2.7.8]
+ at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.8.jar:2.7.8]
+ at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:136) ~[spring-boot-test-2.7.17.jar:2.7.17]
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:212) ~[na:na]
+ at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:194) ~[na:na]
+ at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1709) ~[na:na]
+ at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:556) ~[na:na]
+ at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:546) ~[na:na]
+ at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) ~[na:na]
+ at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) ~[na:na]
+ at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na]
+ at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:782) ~[na:na]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:362) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at java.base/java.util.ArrayList.forEach(ArrayList.java:1597) ~[na:na]
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at java.base/java.util.ArrayList.forEach(ArrayList.java:1597) ~[na:na]
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:150) ~[surefire-junit-platform-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124) ~[surefire-junit-platform-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384) ~[surefire-booter-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345) ~[surefire-booter-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126) ~[surefire-booter-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418) ~[surefire-booter-2.22.2.jar:2.22.2]
+Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
+ at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-5.3.30.jar:5.3.30]
+ at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterPropertiesSet(ServerEndpointExporter.java:107) ~[spring-websocket-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.30.jar:5.3.30]
+ ... 82 common frames omitted
+
+2024-04-25 13:29:12.677 ERROR 36228 --- [main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5a1de7fb] to prepare test instance [com.example.system.SystemApplicationTests@1d4c6e32]
+
+java.lang.IllegalStateException: Failed to load ApplicationContext
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:212) ~[na:na]
+ at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:194) ~[na:na]
+ at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1709) ~[na:na]
+ at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:556) ~[na:na]
+ at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:546) ~[na:na]
+ at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) ~[na:na]
+ at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) ~[na:na]
+ at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na]
+ at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:782) ~[na:na]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:362) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66) ~[junit-jupiter-engine-5.8.2.jar:5.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at java.base/java.util.ArrayList.forEach(ArrayList.java:1597) ~[na:na]
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at java.base/java.util.ArrayList.forEach(ArrayList.java:1597) ~[na:na]
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.8.2.jar:1.8.2]
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) ~[junit-platform-launcher-1.3.1.jar:1.3.1]
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:150) ~[surefire-junit-platform-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124) ~[surefire-junit-platform-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384) ~[surefire-booter-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345) ~[surefire-booter-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126) ~[surefire-booter-2.22.2.jar:2.22.2]
+ at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418) ~[surefire-booter-2.22.2.jar:2.22.2]
+Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverEndpointExporter' defined in class path resource [com/example/system/ai/WebSocketConfig1.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:921) ~[spring-context-5.3.30.jar:5.3.30]
+ at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.30.jar:5.3.30]
+ at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.8.jar:2.7.8]
+ at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.8.jar:2.7.8]
+ at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.8.jar:2.7.8]
+ at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:136) ~[spring-boot-test-2.7.17.jar:2.7.17]
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141) ~[spring-test-5.3.30.jar:5.3.30]
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90) ~[spring-test-5.3.30.jar:5.3.30]
+ ... 67 common frames omitted
+Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
+ at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-5.3.30.jar:5.3.30]
+ at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterPropertiesSet(ServerEndpointExporter.java:107) ~[spring-websocket-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.30.jar:5.3.30]
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.30.jar:5.3.30]
+ ... 82 common frames omitted
+
diff --git a/System/src/main/competition-system-master.zip b/System/src/main/competition-system-master.zip
new file mode 100644
index 0000000..d9e11c7
Binary files /dev/null and b/System/src/main/competition-system-master.zip differ
diff --git a/System/src/main/java/com/example/system/SystemApplication.java b/System/src/main/java/com/example/system/SystemApplication.java
new file mode 100644
index 0000000..0ae9c99
--- /dev/null
+++ b/System/src/main/java/com/example/system/SystemApplication.java
@@ -0,0 +1,15 @@
+package com.example.system;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+
+@SpringBootApplication
+public class SystemApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SystemApplication.class, args);
+ }
+
+}
diff --git a/System/src/main/java/com/example/system/advice/ApiResponse.java b/System/src/main/java/com/example/system/advice/ApiResponse.java
new file mode 100644
index 0000000..54a7f02
--- /dev/null
+++ b/System/src/main/java/com/example/system/advice/ApiResponse.java
@@ -0,0 +1,25 @@
+package com.example.system.advice;
+
+public class ApiResponse {
+ private Object data;
+ private int status;
+ private String message;
+
+ public ApiResponse(Object data, int status, String message) {
+ this.data = data;
+ this.status = status;
+ this.message = message;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/System/src/main/java/com/example/system/advice/ExceptionAdvice.java b/System/src/main/java/com/example/system/advice/ExceptionAdvice.java
new file mode 100644
index 0000000..86f9dd1
--- /dev/null
+++ b/System/src/main/java/com/example/system/advice/ExceptionAdvice.java
@@ -0,0 +1,18 @@
+package com.example.system.advice;
+
+import com.example.system.model.Result;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@Slf4j
+@ResponseBody
+@ControllerAdvice
+public class ExceptionAdvice {
+ @ExceptionHandler
+ public Object Exception(Exception e) {
+ log.error("服务端发生异常 e: {}", e);
+ return Result.fail("服务端发生异常");
+ }
+}
diff --git a/System/src/main/java/com/example/system/advice/LoginConfig.java b/System/src/main/java/com/example/system/advice/LoginConfig.java
new file mode 100644
index 0000000..bb78e2a
--- /dev/null
+++ b/System/src/main/java/com/example/system/advice/LoginConfig.java
@@ -0,0 +1,21 @@
+//package com.example.system.advice;
+//
+//import org.springframework.beans.factory.annotation.Autowired;
+//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 LoginConfig implements WebMvcConfigurer {
+// @Autowired
+// private LoginHandler loginHandler;
+//
+// @Override
+// public void addInterceptors(InterceptorRegistry registry) {
+// registry.addInterceptor(loginHandler)
+// .addPathPatterns("/**")
+// .excludePathPatterns("/user/login")
+// .excludePathPatterns("/user/getUserInfo"); // 排除 /user/getUserInfo 路径
+// }
+//
+//}
diff --git a/System/src/main/java/com/example/system/advice/LoginHandler.java b/System/src/main/java/com/example/system/advice/LoginHandler.java
new file mode 100644
index 0000000..5a7ac8e
--- /dev/null
+++ b/System/src/main/java/com/example/system/advice/LoginHandler.java
@@ -0,0 +1,50 @@
+package com.example.system.advice;
+
+import com.example.system.model.Result;
+import com.example.system.utils.JWTUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.jsonwebtoken.Claims;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.PrintWriter;
+
+@CrossOrigin
+@Slf4j
+@Component
+public class LoginHandler implements HandlerInterceptor {
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ log.info("执行拦截器");
+ String toKen =request.getHeader("Authorization");
+ if (toKen == null) {
+ setResponse(response);
+ return false;
+ }
+ Claims claims = JWTUtil.checkToken(toKen);
+ if (claims == null) {
+ setResponse(response);
+ return false;
+ }
+ return true;
+ }
+
+ @SneakyThrows
+ private void setResponse(HttpServletResponse response) {
+ response.setStatus(200);
+ response.setContentType("application/json");
+ ObjectMapper objectMapper = new ObjectMapper();
+ String ret = objectMapper.writeValueAsString(Result.notLogin());
+ response.setCharacterEncoding("UTF-8");
+ PrintWriter writer = response.getWriter();
+ writer.print(ret);
+ writer.flush();
+ }
+}
+
diff --git a/System/src/main/java/com/example/system/advice/ResponseAdvice.java b/System/src/main/java/com/example/system/advice/ResponseAdvice.java
new file mode 100644
index 0000000..dfcc84c
--- /dev/null
+++ b/System/src/main/java/com/example/system/advice/ResponseAdvice.java
@@ -0,0 +1,35 @@
+package com.example.system.advice;
+
+import com.example.system.model.Result;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.SneakyThrows;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+@ControllerAdvice
+public class ResponseAdvice implements ResponseBodyAdvice {
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Override
+ public boolean supports(MethodParameter returnType, Class converterType) {
+ return true;
+ }
+
+ @SneakyThrows
+ @Override
+ public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
+ if (body instanceof Result) {
+ return body;
+ }
+ if (body instanceof String) {
+ return objectMapper.writeValueAsString(Result.success(body));
+ }
+ return Result.success(body);
+ }
+}
diff --git a/System/src/main/java/com/example/system/advice/SmsBaoConfig.java b/System/src/main/java/com/example/system/advice/SmsBaoConfig.java
new file mode 100644
index 0000000..1fe12b2
--- /dev/null
+++ b/System/src/main/java/com/example/system/advice/SmsBaoConfig.java
@@ -0,0 +1,27 @@
+package com.example.system.advice;
+//定义短信宝
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConfigurationProperties(prefix = "smsbao")
+public class SmsBaoConfig {
+ private String username;
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/System/src/main/java/com/example/system/ai/BigModelNew.java b/System/src/main/java/com/example/system/ai/BigModelNew.java
new file mode 100644
index 0000000..dbd5ea9
--- /dev/null
+++ b/System/src/main/java/com/example/system/ai/BigModelNew.java
@@ -0,0 +1,277 @@
+package com.example.system.ai;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import okhttp3.*;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author hanyiming
+ */
+public class BigModelNew extends WebSocketListener {
+ // 地址与鉴权信息 https://spark-api.xf-yun.com/v1.1/chat 1.5地址 domain参数为general
+ // 地址与鉴权信息 https://spark-api.xf-yun.com/v2.1/chat 2.0地址 domain参数为generalv2
+ public static final String hostUrl = "https://spark-api.xf-yun.com/v3.5/chat";
+ // 以下参数替换为自己的身份认证信息
+ public static final String appid = "1369af1f";
+ public static final String apiSecret = "ZTdkYWJjYmIxMzg2MjVhN2IzMGUzYzk0";
+ public static final String apiKey = "3ef4991ce92253521e51f36073cd3d54";
+
+ public static List historyList = new ArrayList<>(); // 对话历史存储集合
+
+ public static String totalAnswer = ""; // 大模型的答案汇总
+
+ // 环境治理的重要性 环保 人口老龄化 我爱我的祖国
+ public static String NewQuestion = "";
+
+ public static final Gson gson = new Gson();
+
+ // 个性化参数
+ private String userId;
+ private Boolean wsCloseFlag;
+
+ private static Boolean totalFlag = true; // 控制提示用户是否输入
+
+ // 构造函数
+ public BigModelNew(String userId, Boolean wsCloseFlag) {
+ this.userId = userId;
+ this.wsCloseFlag = wsCloseFlag;
+ }
+
+ public static boolean canAddHistory() { // 由于历史记录最大上线1.2W左右,需要判断是能能加入历史
+ int history_length = 0;
+ for (RoleContent temp : historyList) {
+ history_length = history_length + temp.content.length();
+ }
+ if (history_length > 12000) {
+ historyList.remove(0);
+ historyList.remove(1);
+ historyList.remove(2);
+ historyList.remove(3);
+ historyList.remove(4);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // 线程来发送音频与参数
+ class MyThread extends Thread {
+ private WebSocket webSocket;
+
+ public MyThread(WebSocket webSocket) {
+ this.webSocket = webSocket;
+ }
+
+ public void run() {
+ try {
+ JSONObject requestJson = new JSONObject();
+
+ JSONObject header = new JSONObject(); // header参数
+ header.put("app_id", appid);
+ header.put("uid", UUID.randomUUID().toString().substring(0, 10));
+
+ JSONObject parameter = new JSONObject(); // parameter参数
+ JSONObject chat = new JSONObject();
+ chat.put("domain", "generalv2");
+ chat.put("temperature", 0.5);
+ chat.put("max_tokens", 4096);
+ parameter.put("chat", chat);
+
+ JSONObject payload = new JSONObject(); // payload参数
+ JSONObject message = new JSONObject();
+ JSONArray text = new JSONArray();
+
+ // 历史问题获取
+ if (historyList.size() > 0) {
+ for (RoleContent tempRoleContent : historyList) {
+ text.add(JSON.toJSON(tempRoleContent));
+ }
+ }
+
+ // 最新问题
+ RoleContent roleContent = new RoleContent();
+ roleContent.role = "user";
+ roleContent.content = NewQuestion;
+ text.add(JSON.toJSON(roleContent));
+ historyList.add(roleContent);
+
+
+ message.put("text", text);
+ payload.put("message", message);
+
+
+ requestJson.put("header", header);
+ requestJson.put("parameter", parameter);
+ requestJson.put("payload", payload);
+ // System.err.println(requestJson); // 可以打印看每次的传参明细
+ webSocket.send(requestJson.toString());
+ // 等待服务端返回完毕后关闭
+ while (true) {
+ // System.err.println(wsCloseFlag + "---");
+ Thread.sleep(200);
+ if (wsCloseFlag) {
+ break;
+ }
+ }
+ webSocket.close(1000, "");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void onOpen(WebSocket webSocket, Response response) {
+ super.onOpen(webSocket, response);
+ System.out.print("大模型:");
+ MyThread myThread = new MyThread(webSocket);
+ myThread.start();
+ }
+
+ @Override
+ public void onMessage(WebSocket webSocket, String text) {
+ // System.out.println(userId + "用来区分那个用户的结果" + text);
+ JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
+ if (myJsonParse.header.code != 0) {
+ System.out.println("发生错误,错误码为:" + myJsonParse.header.code);
+ System.out.println("本次请求的sid为:" + myJsonParse.header.sid);
+ webSocket.close(1000, "");
+ }
+ List textList = myJsonParse.payload.choices.text;
+ for (Text temp : textList) {
+ // 在此处给前端页面发送回答信息,如有存储问答需求,请在此处存储回答信息
+ WebSocketClient.sendInfo(temp.content);
+ System.out.print(temp.content);
+ totalAnswer = totalAnswer + temp.content;
+ }
+ if (myJsonParse.header.status == 2) {
+ // 可以关闭连接,释放资源
+ System.out.println();
+ System.out.println("*************************************************************************************");
+ if (canAddHistory()) {
+ RoleContent roleContent = new RoleContent();
+ roleContent.setRole("assistant");
+ roleContent.setContent(totalAnswer);
+ historyList.add(roleContent);
+ } else {
+ historyList.remove(0);
+ RoleContent roleContent = new RoleContent();
+ roleContent.setRole("assistant");
+ roleContent.setContent(totalAnswer);
+ historyList.add(roleContent);
+ }
+ wsCloseFlag = true;
+ totalFlag = true;
+ }
+ }
+
+ @Override
+ public void onFailure(WebSocket webSocket, Throwable t, Response response) {
+ super.onFailure(webSocket, t, response);
+ try {
+ if (null != response) {
+ int code = response.code();
+ System.out.println("onFailure code:" + code);
+ System.out.println("onFailure body:" + response.body().string());
+ if (101 != code) {
+ System.out.println("connection failed");
+ System.exit(0);
+ }
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+
+ // 鉴权方法
+ public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
+ URL url = new URL(hostUrl);
+ // 时间
+ SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
+ format.setTimeZone(TimeZone.getTimeZone("GMT"));
+ String date = format.format(new Date());
+ // 拼接
+ String preStr = "host: " + url.getHost() + "\n" + "date: " + date + "\n" + "GET " + url.getPath() + " HTTP/1.1";
+ // System.err.println(preStr);
+ // SHA256加密
+ Mac mac = Mac.getInstance("hmacsha256");
+ SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
+ mac.init(spec);
+
+ byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
+ // Base64加密
+ String sha = Base64.getEncoder().encodeToString(hexDigits);
+ // System.err.println(sha);
+ // 拼接
+ String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
+ // 拼接地址
+ HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
+ addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
+ addQueryParameter("date", date).//
+ addQueryParameter("host", url.getHost()).//
+ build();
+
+ // System.err.println(httpUrl.toString());
+ return httpUrl.toString();
+ }
+
+ //返回的json结果拆解
+ class JsonParse {
+ Header header;
+ Payload payload;
+ }
+
+ class Header {
+ int code;
+ int status;
+ String sid;
+ }
+
+ class Payload {
+ Choices choices;
+ }
+
+ class Choices {
+ List text;
+ }
+
+ class Text {
+ String role;
+ String content;
+ }
+
+ class RoleContent {
+ String role;
+ String content;
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+ }
+}
+
+
diff --git a/System/src/main/java/com/example/system/ai/WebAppRootContext.java b/System/src/main/java/com/example/system/ai/WebAppRootContext.java
new file mode 100644
index 0000000..7768bba
--- /dev/null
+++ b/System/src/main/java/com/example/system/ai/WebAppRootContext.java
@@ -0,0 +1,28 @@
+package com.example.system.ai;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.web.servlet.ServletContextInitializer;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.util.WebAppRootListener;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+@Configuration
+@ComponentScan
+@EnableAutoConfiguration
+public class WebAppRootContext implements ServletContextInitializer {
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ servletContext.addListener(WebAppRootListener.class);
+ //这里设置了30兆的缓冲区
+ //Tomcat每次请求过来时在创建session时都会把这个webSocketContainer作为参数传进去所以对所有的session都生效了
+ servletContext.setInitParameter("org.apache.tomcat.websocket.textBufferSize", "30000000");
+ servletContext.setInitParameter("org.apache.tomcat.websocket.binaryBufferSize", "30000000");
+ }
+
+}
+
+
diff --git a/System/src/main/java/com/example/system/ai/WebSocketClient.java b/System/src/main/java/com/example/system/ai/WebSocketClient.java
new file mode 100644
index 0000000..b28d935
--- /dev/null
+++ b/System/src/main/java/com/example/system/ai/WebSocketClient.java
@@ -0,0 +1,178 @@
+package com.example.system.ai;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.druid.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.WebSocket;
+import org.springframework.stereotype.Component;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+
+@ServerEndpoint(value = "/websocketClient/{userId}")
+@Component
+@Slf4j
+public class WebSocketClient {
+
+
+ /**
+ * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的
+ */
+
+ private static int onlineCount = 0;
+
+ /**
+ * concurrent包的线程安全Map,用来存放每个客户端对应的MyWebSocket对象
+ */
+ private static final ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
+
+ public ConcurrentHashMap getWebSocketMap() {
+ return webSocketMap;
+ }
+
+ /**
+ * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+ */
+ private Session session;
+
+ /**
+ * 用户id 唯一标识
+ */
+ private String userId;
+
+ /**
+ * 连接建立成功调用的方法
+ */
+ @OnOpen
+ public void onOpen(Session session, @PathParam("userId") String userId) {
+ this.session = session;
+ this.userId = userId;
+ //加入map
+ webSocketMap.put(userId, this);
+ //在线数加1
+ addOnlineCount();
+ log.info("WebSocket客户端{}连接成功,客户端标识:{},当前在线人数:{}", session.getId(), userId, getOnlineCount());
+ sendMessage("用户" + userId + "连接成功!");
+ }
+
+ /**
+ * 连接关闭调用的方法
+ */
+ @OnClose
+ public void onClose() {
+ //从map中删除
+ webSocketMap.remove(userId);
+ //在线数减1
+ subOnlineCount();
+ log.info("WebSocket客户端{}连接断开,客户端标识:{},当前在线人数:{}", session.getId(), userId, getOnlineCount());
+ }
+
+ /**
+ * 收到客户端消息后调用的方法
+ *
+ * @param message 客户端发送过来的消息
+ */
+ @OnMessage
+ public void onMessage(String message, Session session) throws Exception {
+ // 心跳检测响应
+ if (StringUtils.equalsIgnoreCase("ping", message)) {
+ sendMessage("pong");
+ log.info("WebSocket服务端已回复客户端{}的心跳检测:pong", session.getId());
+ return;
+ }
+ BigModelNew.NewQuestion = message;
+ // 构建鉴权url
+ String authUrl = BigModelNew.getAuthUrl(BigModelNew.hostUrl, BigModelNew.apiKey, BigModelNew.apiSecret);
+ OkHttpClient client = new OkHttpClient.Builder().build();
+ String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
+ Request request = new Request.Builder().url(url).build();
+ for (int i = 0; i < 1; i++) {
+ BigModelNew.totalAnswer="";
+ WebSocket webSocket = client.newWebSocket(request, new BigModelNew(i + "",
+ false));
+ }
+ log.info("收到客户端{}的消息:{}", session.getId(), message);
+ }
+
+ /**
+ * 发生错误时调用
+ */
+ @OnError
+ public void onError(Session session, Throwable error) {
+ log.error("发生错误{}", session.getId(), error);
+ error.printStackTrace();
+ }
+
+ /**
+ * 向客户端发送消息
+ */
+ public void sendMessage(String message) {
+ try {
+ this.session.getBasicRemote().sendText(message);
+ } catch (IOException e) {
+ e.printStackTrace();
+ log.error("客户端{}发送消息{{}}失败", session.getId(), message);
+ }
+ }
+
+ /**
+ * 通过userId向客户端发送消息
+ */
+ public static void sendMessageByUserId(String userId, String message) throws IOException {
+ log.info("给用户{}发送{}信息", userId, message);
+ if (StrUtil.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
+ webSocketMap.get(userId).sendMessage(message);
+ }
+ }
+
+ /**
+ * 关闭WebSocket
+ *
+ * @param userId 用户id
+ */
+ public static void closeWebSocket(String userId) {
+ if (StrUtil.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
+ webSocketMap.get(userId).onClose();
+ }
+ }
+
+ /**
+ * 群发自定义消息
+ */
+ public static void sendInfo(String message) {
+ for (String item : webSocketMap.keySet()) {
+ webSocketMap.get(item).sendMessage(message);
+ }
+ }
+
+ /**
+ * 获取在线人数
+ *
+ * @return 在线人数
+ */
+ public static synchronized int getOnlineCount() {
+ return onlineCount;
+ }
+
+ /**
+ * 添加一位在线人数
+ */
+ public static synchronized void addOnlineCount() {
+ WebSocketClient.onlineCount++;
+ }
+
+ /**
+ * 减少一位在线人数
+ */
+ public static synchronized void subOnlineCount() {
+ WebSocketClient.onlineCount--;
+ }
+
+}
+
+
diff --git a/System/src/main/java/com/example/system/ai/WebSocketConfig1.java b/System/src/main/java/com/example/system/ai/WebSocketConfig1.java
new file mode 100644
index 0000000..e08d39f
--- /dev/null
+++ b/System/src/main/java/com/example/system/ai/WebSocketConfig1.java
@@ -0,0 +1,18 @@
+package com.example.system.ai;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * 开启webSocket支持
+ */
+@Configuration
+public class WebSocketConfig1 {
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter(){
+ return new ServerEndpointExporter();
+ }
+}
+
+
diff --git a/System/src/main/java/com/example/system/chat/FriendController.java b/System/src/main/java/com/example/system/chat/FriendController.java
new file mode 100644
index 0000000..a2b4ba3
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/FriendController.java
@@ -0,0 +1,45 @@
+package com.example.system.chat;
+
+import com.example.system.chat.model.Friend;
+import com.example.system.chat.service.FriendService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/friend")
+public class FriendController {
+ @Autowired
+ private FriendService friendService;
+ /**
+ * 获取好友列表
+ * @return 返回好友列表
+ */
+ @RequestMapping("/getList")
+ public List getList(HttpServletRequest request) {
+ log.info("获取好友列表");
+ String userToken =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(userToken);
+
+ return friendService.getFriendList((Integer) claims.get("userId"));
+ }
+ /**
+ * 添加好友
+ */
+ @RequestMapping("/addFriend")
+ public Object addFriend(Integer friendId, String friendName, HttpServletRequest request) {
+ log.info("添加好友 friendId: {}", friendId);
+ String userToken =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(userToken);
+ Integer userId = (Integer) claims.get("userId");
+ String userName = (String) claims.get("userName");
+ return friendService.addFriend(friendId, friendName, userId, userName);
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/MessageController.java b/System/src/main/java/com/example/system/chat/MessageController.java
new file mode 100644
index 0000000..3f17197
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/MessageController.java
@@ -0,0 +1,27 @@
+package com.example.system.chat;
+
+import com.example.system.chat.service.MessageService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@RestController
+@RequestMapping("/message")
+public class MessageController {
+ @Resource
+ private MessageService messageService;
+ /**
+ * 获取sessionID会话的历史消息,按时间降序从start+1开始获取10条
+ * @param sessionId
+ * @param start
+ * @return
+ */
+ @RequestMapping("/getHistoryMessage")
+ public Object getHistoryMessage(Integer sessionId, Integer start) {
+ log.info("获取sessionID会话的历史消息 sessionId: {} start: {}", sessionId, start);
+ return messageService.getHistoryMessage(sessionId, start);
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/SessionController.java b/System/src/main/java/com/example/system/chat/SessionController.java
new file mode 100644
index 0000000..eff8157
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/SessionController.java
@@ -0,0 +1,51 @@
+package com.example.system.chat;
+
+import com.example.system.chat.model.SessionMassage;
+import com.example.system.chat.service.SessionService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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 java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/session")
+public class SessionController {
+ @Autowired
+ private SessionService sessionService;
+
+ /**
+ * 获取所有的会话
+ */
+ @RequestMapping("/getMessageSession")
+ public List getMessageSession(HttpServletRequest request) {
+ log.info("获取所有的会话");
+ //获取登录用户id
+ String userToken =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(userToken);
+ Integer userId = (Integer) claims.get("userId");
+ return sessionService.getMessageSession(userId);
+ }
+
+ /**
+ * 创建会话
+ */
+ @RequestMapping("/createSession")
+ public Object createSession(@RequestParam List friendId, HttpServletRequest request) {
+ log.info("创建会话 friend: {}", friendId);
+ String userToken =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(userToken);
+
+ Integer userId = (Integer) claims.get("userId");
+ friendId.add(userId);
+ Object session = sessionService.createSession(friendId);
+ log.info("创建会话成功 session: {}", session);
+ return session;
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/config/WebSocketConfig.java b/System/src/main/java/com/example/system/chat/config/WebSocketConfig.java
new file mode 100644
index 0000000..e40de19
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/config/WebSocketConfig.java
@@ -0,0 +1,22 @@
+package com.example.system.chat.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
+
+import javax.annotation.Resource;
+
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig implements WebSocketConfigurer {
+ @Resource
+ private WebSocketController webSocketController;
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ registry.addHandler(webSocketController, "/wsMessage")
+ .addInterceptors(new HttpSessionHandshakeInterceptor());
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/config/WebSocketController.java b/System/src/main/java/com/example/system/chat/config/WebSocketController.java
new file mode 100644
index 0000000..6295d0b
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/config/WebSocketController.java
@@ -0,0 +1,105 @@
+package com.example.system.chat.config;
+
+import com.example.system.chat.mapper.MessageMapper;
+import com.example.system.chat.mapper.SessionMassageMapper;
+import com.example.system.chat.model.ConnectionMap;
+import com.example.system.chat.model.WebSocketRequest;
+import com.example.system.chat.model.WebSocketResp;
+import com.example.system.model.UserTable;
+import com.example.system.utils.JWTUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Component
+@Slf4j
+public class WebSocketController extends TextWebSocketHandler {
+ @Resource
+ private ObjectMapper objectMapper;
+ @Resource
+ private SessionMassageMapper sessionMassageMapper;
+ @Resource
+ private MessageMapper messageMapper;
+
+ @Override
+ public void afterConnectionEstablished(WebSocketSession session) throws Exception {
+ log.info("连接成功");
+ Long userId = getUserIdBySession(session);
+ ConnectionMap.onLine(Math.toIntExact(userId), session);
+ }
+
+ @Override
+ protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+ log.info("收到消息 message: {}", message);
+ //获取用户发送的消息
+ WebSocketRequest webSocketRequest = objectMapper.readValue(message.getPayload(), WebSocketRequest.class);
+ if (!"message".equals(webSocketRequest.getType())) {
+ return;
+ }
+ //获取发送者
+ UserTable user = new UserTable();
+ user.setUserId(getUserIdBySession(session));
+ user.setUserName(getUserNameBySession(session));
+ //构造一个转发的消息
+ WebSocketResp resp = new WebSocketResp();
+ resp.setType(webSocketRequest.getType());
+ resp.setSessionId(webSocketRequest.getSessionId());
+ resp.setUserId(Math.toIntExact(user.getUserId()));
+ resp.setUserName(user.getUserName());
+ resp.setContent(webSocketRequest.getContent());
+ String ret = objectMapper.writeValueAsString(resp);
+ //获取当前发送会话的所有好友id和name
+ List list = sessionMassageMapper.getSessionBySessionId(webSocketRequest.getSessionId(), Math.toIntExact(user.getUserId()));
+ list.add(user);
+ //给所有人转发该条消息
+ for (UserTable tmp : list) {
+ WebSocketSession socketSession = ConnectionMap.getWSSessionById(Math.toIntExact(tmp.getUserId()));
+ if (socketSession != null) {
+ socketSession.sendMessage(new TextMessage(ret));
+ }
+ }
+ //将该条消息存储在数据库中
+ Integer a = messageMapper.sendMessage(Math.toIntExact(user.getUserId()), webSocketRequest.getSessionId(), webSocketRequest.getContent());
+ if (a != 1) {
+ throw new RuntimeException("消息存储异常");
+ }
+ }
+
+ @Override
+ public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
+ log.error("连接异常 exception: {}", exception.toString());
+ int userId = Math.toIntExact(getUserIdBySession(session));
+ ConnectionMap.offLine(userId);
+ }
+
+ @Override
+ public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
+ log.info("连接关闭");
+ int userId = Math.toIntExact(getUserIdBySession(session));
+ ConnectionMap.offLine(userId);
+ }
+
+ public Long getUserIdBySession(WebSocketSession session) {
+ session.getHandshakeHeaders();
+ String userToken = (String) session.getAttributes().get("userToken");
+ Claims claims = JWTUtil.checkToken(userToken);
+ return (Long) claims.get("userId");
+ }
+
+ public String getUserNameBySession(WebSocketSession session) {
+ HttpHeaders handshakeHeaders = session.getHandshakeHeaders();
+ List list = handshakeHeaders.get("sec-websocket-protocol");
+ String userToken =list.get(0);
+ Claims claims = JWTUtil.checkToken(userToken);
+ return (String) claims.get("userName");
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/mapper/FriendMapper.java b/System/src/main/java/com/example/system/chat/mapper/FriendMapper.java
new file mode 100644
index 0000000..d01bcde
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/mapper/FriendMapper.java
@@ -0,0 +1,31 @@
+package com.example.system.chat.mapper;
+
+import com.example.system.chat.model.Friend;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface FriendMapper {
+ /**
+ * 根据用户id获取好友列表
+ */
+ @Select("select friend_id, friend_name from friend where user_id=#{userId};")
+ List getFriendList(Integer userId);
+
+ /**
+ * 判断用户之间的关系
+ */
+ @Select("SELECT COUNT(*) FROM friend WHERE user_id=#{userId} AND friend_id=#{friendId};")
+ int isFriend(Integer userId, Integer friendId);
+
+ /**
+ * 添加好友
+ */
+ @Insert("INSERT INTO friend VALUES " +
+ "(null, #{userId}, #{friendId}, #{friendName}, null)," +
+ "(null, #{friendId}, #{userId}, #{userName}, null);")
+ Integer addFriend(Integer userId, String userName, Integer friendId, String friendName);
+}
diff --git a/System/src/main/java/com/example/system/chat/mapper/MessageMapper.java b/System/src/main/java/com/example/system/chat/mapper/MessageMapper.java
new file mode 100644
index 0000000..fce71ab
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/mapper/MessageMapper.java
@@ -0,0 +1,23 @@
+package com.example.system.chat.mapper;
+
+import com.example.system.chat.model.Message;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface MessageMapper {
+ //根据会话Id获取最新的一条消息
+ @Select("SELECT content FROM message where session_id=#{id} ORDER BY create_time DESC LIMIT 1;")
+ String getNewMessage(Integer id);
+
+ //根据会话id和start来获取10条消息
+ @Select("SELECT * FROM message where session_id=#{sessionId} ORDER BY create_time DESC LIMIT #{start}, 10;")
+ List getHistoryMessage(Integer sessionId, Integer start);
+
+ //发送消息
+ @Insert("INSERT INTO message VALUE (NULL, #{sessionId}, #{userId}, #{content}, NOW());")
+ Integer sendMessage(Integer userId, Integer sessionId, String content);
+}
diff --git a/System/src/main/java/com/example/system/chat/mapper/SessionMassageMapper.java b/System/src/main/java/com/example/system/chat/mapper/SessionMassageMapper.java
new file mode 100644
index 0000000..125814d
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/mapper/SessionMassageMapper.java
@@ -0,0 +1,29 @@
+package com.example.system.chat.mapper;
+
+import com.example.system.chat.model.SessionMassage;
+import com.example.system.model.UserTable;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface SessionMassageMapper {
+ //获取当前用户的所有sessionId并按照降序排列
+ @Select("select id from session_massage where id in " +
+ "(select session_id from user_session where user_id=#{userId}) order by last_time desc")
+ List getSessionIdByUserId(Integer userId);
+
+ //根据sessionId获取对应的好友id和name(排除用户自己)
+ @Select("select user_id, user_name from user_table where user_id in " +
+ "(select user_id from user_session where session_id=#{sessionId} and user_id != #{userSelfId})")
+ List getSessionBySessionId(Integer sessionId, Integer userSelfId);
+
+ //创建新会话并返回会话id
+ Integer insertSession(SessionMassage sessionMassage);
+
+ //创建新绘画与用户的关系
+ @Insert("INSERT INTO user_session VALUES (null, #{userId}, #{sessionId})")
+ Integer insertUserFriend(Integer userId, Integer sessionId);
+}
diff --git a/System/src/main/java/com/example/system/chat/model/ConnectionMap.java b/System/src/main/java/com/example/system/chat/model/ConnectionMap.java
new file mode 100644
index 0000000..49e6932
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/model/ConnectionMap.java
@@ -0,0 +1,26 @@
+package com.example.system.chat.model;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.socket.WebSocketSession;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+@Slf4j
+public class ConnectionMap {
+ private static final ConcurrentMap map = new ConcurrentHashMap<>();
+
+ public static WebSocketSession getWSSessionById(Integer userId) {
+ return map.get(userId);
+ }
+
+ public static void onLine(Integer userId, WebSocketSession session) {
+ map.put(userId, session);
+ log.info("用户上线:{}", userId);
+ }
+
+ public static void offLine(Integer userId) {
+ map.remove(userId);
+ log.info("用户下线:{}", userId);
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/model/Friend.java b/System/src/main/java/com/example/system/chat/model/Friend.java
new file mode 100644
index 0000000..54455ba
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/model/Friend.java
@@ -0,0 +1,10 @@
+package com.example.system.chat.model;
+
+import lombok.Data;
+
+//好友
+@Data
+public class Friend {
+ private Integer friendId;
+ private String friendName;
+}
diff --git a/System/src/main/java/com/example/system/chat/model/Message.java b/System/src/main/java/com/example/system/chat/model/Message.java
new file mode 100644
index 0000000..1888b88
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/model/Message.java
@@ -0,0 +1,15 @@
+package com.example.system.chat.model;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class Message {
+ private Integer id;
+ private Integer sessionId;
+ private Integer userId;
+ private String userName;
+ private String content;
+ private Date createTime;
+}
diff --git a/System/src/main/java/com/example/system/chat/model/SessionMassage.java b/System/src/main/java/com/example/system/chat/model/SessionMassage.java
new file mode 100644
index 0000000..e0594c8
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/model/SessionMassage.java
@@ -0,0 +1,14 @@
+package com.example.system.chat.model;
+
+import com.example.system.model.UserTable;
+import lombok.Data;
+
+import java.util.List;
+
+//会话
+@Data
+public class SessionMassage {
+ private Integer sessionId;
+ private List friend;
+ private String lastMessage;
+}
diff --git a/System/src/main/java/com/example/system/chat/model/WebSocketRequest.java b/System/src/main/java/com/example/system/chat/model/WebSocketRequest.java
new file mode 100644
index 0000000..162a979
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/model/WebSocketRequest.java
@@ -0,0 +1,10 @@
+package com.example.system.chat.model;
+
+import lombok.Data;
+
+@Data
+public class WebSocketRequest {
+ private String type;
+ private Integer sessionId;//会话Id
+ private String content;
+}
diff --git a/System/src/main/java/com/example/system/chat/model/WebSocketResp.java b/System/src/main/java/com/example/system/chat/model/WebSocketResp.java
new file mode 100644
index 0000000..7d362a1
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/model/WebSocketResp.java
@@ -0,0 +1,12 @@
+package com.example.system.chat.model;
+
+import lombok.Data;
+
+@Data
+public class WebSocketResp {
+ private String type;
+ private Integer sessionId;
+ private Integer userId;//发送者id
+ private String userName;//发送者的name
+ private String content;
+}
diff --git a/System/src/main/java/com/example/system/chat/service/FriendService.java b/System/src/main/java/com/example/system/chat/service/FriendService.java
new file mode 100644
index 0000000..5d69613
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/service/FriendService.java
@@ -0,0 +1,27 @@
+package com.example.system.chat.service;
+
+import com.example.system.chat.mapper.FriendMapper;
+import com.example.system.chat.model.Friend;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class FriendService {
+ @Autowired
+ private FriendMapper friendMapper;
+
+ /**
+ * 获取好友列表
+ */
+ public List getFriendList(Integer userId) {
+ List ret = friendMapper.getFriendList(userId);
+ return ret;
+ }
+
+ //添加好友
+ public Object addFriend(Integer userId, String userName, Integer friendId, String friendName) {
+ return 2 == friendMapper.addFriend(userId, userName, friendId, friendName);
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/service/MessageService.java b/System/src/main/java/com/example/system/chat/service/MessageService.java
new file mode 100644
index 0000000..0ea496b
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/service/MessageService.java
@@ -0,0 +1,28 @@
+package com.example.system.chat.service;
+
+import com.example.system.chat.mapper.MessageMapper;
+import com.example.system.chat.model.Message;
+import com.example.system.mapper.UserMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class MessageService {
+ @Resource
+ private UserMapper userMapper;
+ @Resource
+ private MessageMapper messageMapper;
+ //根据会话id和start来获取10条消息
+ public Object getHistoryMessage(Integer sessionId, Integer start) {
+ List list = new ArrayList<>();
+ list = messageMapper.getHistoryMessage(sessionId, start);
+ Iterable iterable = new ArrayList<>(list);
+ for (Message message : iterable) {
+ message.setUserName(userMapper.getNameById(message.getUserId()));
+ }
+ return list;
+ }
+}
diff --git a/System/src/main/java/com/example/system/chat/service/SessionService.java b/System/src/main/java/com/example/system/chat/service/SessionService.java
new file mode 100644
index 0000000..fc14197
--- /dev/null
+++ b/System/src/main/java/com/example/system/chat/service/SessionService.java
@@ -0,0 +1,58 @@
+package com.example.system.chat.service;
+
+import com.example.system.chat.mapper.MessageMapper;
+import com.example.system.chat.mapper.SessionMassageMapper;
+import com.example.system.chat.model.SessionMassage;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class SessionService {
+ @Autowired
+ private SessionMassageMapper sessionMassageMapper;
+ @Autowired
+ private MessageMapper messageMapper;
+
+ /**
+ * 根据用户id获取所有会话
+ * @param userId
+ * @return 会话列表
+ */
+ public List getMessageSession(Integer userId) {
+ //获取所有和当前用户有关的会话id
+ List sessionIds = sessionMassageMapper.getSessionIdByUserId(userId);
+ //获取这些会话中的好友信息(排除自己)
+ List ret = new ArrayList<>();
+ for (Integer id : sessionIds) {
+ SessionMassage sessionMassage = new SessionMassage();
+ sessionMassage.setSessionId(id);
+ sessionMassage.setFriend(sessionMassageMapper.getSessionBySessionId(id, userId));
+ String lastMessage = messageMapper.getNewMessage(id);
+ if (lastMessage == null) {
+ sessionMassage.setLastMessage("");
+ }
+ else {
+ sessionMassage.setLastMessage(lastMessage);
+ }
+ ret.add(sessionMassage);
+ }
+ return ret;
+ }
+
+ //创建会话
+ @Transactional
+ public Object createSession(List friendIds) {
+ //创建会话
+ SessionMassage sessionMassage = new SessionMassage();
+ sessionMassageMapper.insertSession(sessionMassage);
+ //创建会话和用户的关系
+ for (Integer friendId: friendIds) {
+ sessionMassageMapper.insertUserFriend(friendId, sessionMassage.getSessionId());
+ }
+ return sessionMassage;
+ }
+}
diff --git a/System/src/main/java/com/example/system/constant/ContestGrade.java b/System/src/main/java/com/example/system/constant/ContestGrade.java
new file mode 100644
index 0000000..fcbe603
--- /dev/null
+++ b/System/src/main/java/com/example/system/constant/ContestGrade.java
@@ -0,0 +1,20 @@
+package com.example.system.constant;
+
+public enum ContestGrade {
+ COUNTRY("国家级"),
+ PROVINCE("省级"),
+ CITY("市/区级"),
+ STUDENT("校级"),
+ COLLEGE("院级"),
+ OTHER("其他");
+
+ private String desc;
+
+ ContestGrade(String desc) {
+ this.desc = desc;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/constant/ResultCode.java b/System/src/main/java/com/example/system/constant/ResultCode.java
new file mode 100644
index 0000000..aa93c8e
--- /dev/null
+++ b/System/src/main/java/com/example/system/constant/ResultCode.java
@@ -0,0 +1,17 @@
+package com.example.system.constant;
+
+import lombok.Getter;
+
+public enum ResultCode {
+ SUCCESS("success", 200),
+ FAIL("fail", 500),
+ NOT_LOGIN("notLogin", -1);
+ @Getter
+ private Integer code;
+ private String desc;
+
+ ResultCode(String desc, Integer code) {
+ this.code = code;
+ this.desc = desc;
+ }
+}
diff --git a/System/src/main/java/com/example/system/controller/ArticleController.java b/System/src/main/java/com/example/system/controller/ArticleController.java
new file mode 100644
index 0000000..200a8a9
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/ArticleController.java
@@ -0,0 +1,109 @@
+package com.example.system.controller;
+
+import com.example.system.model.ArticleTable;
+import com.example.system.model.Result;
+import com.example.system.service.ArticleService;
+import com.example.system.service.UserService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.sql.Date;
+
+
+@Slf4j
+@RestController
+@CrossOrigin
+@RequestMapping("/article")
+public class ArticleController {
+
+ @Autowired
+ private ArticleService articleService;
+
+ @Autowired
+ private UserService userService;
+
+ //获取历史文章并按照升序排列
+ @RequestMapping(value = "/getHistoryArticle")
+ public Object getHistoryArticle() {
+ log.info("获取历史文章");
+ return articleService.getHistoryArticle();
+ }
+
+ // 创建一篇文章 创建成功返回true,失败返回false 必传内容:文章标题,文章类型,文章内容, 比赛id
+ @PostMapping("/createArticle")
+ public Object createArticle(ArticleTable article, HttpServletRequest request) {
+ log.info("创建一篇文章 article: {}", article);
+ if (article.getArticleTitle() == null
+ || article.getArticleContent() == null
+ || article.getArticleType() == null
+ || article.getCompetitionId() == null) {
+ return Result.fail("参数不全");
+ }
+ String userToken =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(userToken);
+ article.setUserId((Integer)claims.get("userId"));
+ article.setPublishTime(new Date(System.currentTimeMillis()));
+ Integer articleId = articleService.createArticle(article);
+ if (articleId != null) {
+ return Result.success(articleId);
+ } else {
+ return Result.fail("文章创建失败");
+ }
+ }
+
+ //根据文章id获取对应的文章;
+ @RequestMapping("/getArticleById")
+ public Object getArticleById(Integer id) {
+ log.info("根据文章id获取对应的文章 id: {}", id);
+ if (id <= 0) {
+ return Result.fail("文章id不合法");
+ }
+ ArticleTable ret;
+ ret = articleService.getArticleById(id);
+ return ret;
+ }
+
+ //删除文章(根据文章id)
+ @RequestMapping("/deleteArticleById")
+ public Object deleteArticleById(Integer id, HttpServletRequest request) {
+ log.info("删除自己的文章(根据文章id) id: {}", id);
+ if (id <= 0) {
+ return Result.fail("文章id不合法");
+ }
+ Boolean ret = articleService.deleteArticleById(id);
+ return ret;
+ }
+
+ //根据文章id修改文章,只能修改自己的文章
+ @RequestMapping("/upData")
+ public Object upData(ArticleTable articleTable, HttpServletRequest request) {
+ log.info("修改自己的文章 articleTable: {}", articleTable);
+ if (articleTable.getUserId() == null
+ || articleTable.getArticleId() == null
+ || articleTable.getArticleTitle() == null
+ || articleTable.getArticleContent() == null
+ || articleTable.getArticleType() == null
+ ) {
+ return Result.fail("参数不全");
+ }
+ //获取用户的id
+ String userToken =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(userToken);
+ Integer userId = (Integer) claims.get("userId");
+ if (!userId.equals(articleTable.getUserId())) {
+ return Result.fail("只能修改自己的文章");
+ }
+ //修改文章
+ if (articleService.updateArticle(articleTable)) {
+ return Result.success("更新成功");
+ }
+ return Result.success("更新失败");
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/controller/CommentController.java b/System/src/main/java/com/example/system/controller/CommentController.java
new file mode 100644
index 0000000..f43893d
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/CommentController.java
@@ -0,0 +1,67 @@
+package com.example.system.controller;
+
+import com.example.system.model.CommentTable;
+import com.example.system.model.Result;
+import com.example.system.repository.CommentRepository;
+import com.example.system.service.CommpentService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.CrossOrigin;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.util.Date;
+import java.util.Objects;
+
+@Slf4j
+@RestController
+@CrossOrigin
+@RequestMapping("/comment")
+public class CommentController {
+
+ @Autowired
+ private CommentRepository commentRepository;
+ @Autowired
+ private CommpentService commpentService;
+
+ // 根据文章id获取所有评论
+ @GetMapping("/getAllById")
+ public Object getAllCommentsById(Integer id) {
+ log.info("根据文章id获取所有评论 id: {}", id);
+ if (id <= 0) {
+ return Result.fail("非法id");
+ }
+ return commpentService.getCommentById(id);
+ }
+
+ // 发布评论
+ @PostMapping("/creat")
+ public ResponseEntity addComment(CommentTable comment) {
+ log.info("发布评论 comment: {}", comment);
+ comment.setPublishTime(new Date(System.currentTimeMillis()));
+ CommentTable savedComment = commentRepository.save(comment);
+ return ResponseEntity.ok().body(savedComment);
+ }
+
+ // 删除评论
+ @DeleteMapping("/delete/{id}")
+ public Object deleteComment(@PathVariable Long id, HttpServletRequest request) {
+ log.info("删除评论 id: {}", id);
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ Integer userPrivileges = (Integer) claims.get("userPrivileges");
+ if (userPrivileges == 2) {
+ Integer userId = (Integer) claims.get("userId");
+ //根据评论id找到对应的评论
+ CommentTable comment = commpentService.getById(id);
+ if (!Objects.equals(comment.getUserId(), userId)) {
+ return Result.fail("不能删除别人的评论");
+ }
+ }
+ return commpentService.deleteById(id);
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/controller/CompetitionController.java b/System/src/main/java/com/example/system/controller/CompetitionController.java
new file mode 100644
index 0000000..485e97c
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/CompetitionController.java
@@ -0,0 +1,136 @@
+package com.example.system.controller;
+
+import com.example.system.model.CompetitionTable;
+import com.example.system.model.Result;
+import com.example.system.service.CompetitionService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Optional;
+
+@CrossOrigin
+@Slf4j
+@RestController
+@RequestMapping("/competition")
+public class CompetitionController {
+
+ @Autowired
+ private CompetitionService competitionService;
+
+
+
+ /**
+ * 添加竞赛信息
+ *
+ * @param competition 竞赛信息的请求体
+ * @return 竞赛信息实体,包含数据库保存后的完整信息
+ */
+ @PostMapping("/add")
+ public Object addCompetition(CompetitionTable competition, HttpServletRequest request) {
+ log.info("添加竞赛信息 competition: {}", competition);
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ Integer a = (Integer) claims.get("userPrivileges");
+ // 检查用户是否有权限添加竞赛信息
+ if (2 == a) {
+ // 如果用户无权限,禁止访问
+ return Result.fail("无权限添加竞赛信息");
+ }
+ // 调用服务层添加竞赛信息,并返回添加的竞赛信息
+ CompetitionTable competitionTable = competitionService.addCompetition(competition);
+ return competitionTable;
+ }
+
+
+
+ /**
+ * 删除竞赛信息
+ *
+ * @param id 竞赛信息的ID
+ * @return 删除成功的提示信息
+ */
+ @DeleteMapping(value = "/delete/{id}", produces = "application/json")
+ public Object deleteCompetition(@PathVariable Long id, HttpServletRequest request) {
+ log.info("删除竞赛信息 id: {}", id);
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ Integer a = (Integer) claims.get("userPrivileges");
+ // 检查用户是否有权限删除竞赛信息
+ if (2 == a) {
+ return Result.fail("无权限删除竞赛信息");
+ }
+ // 尝试删除竞赛信息,若竞赛信息不存在,抛出404异常
+ boolean isDeleted = competitionService.deleteCompetition(id);
+ if (!isDeleted) {
+ return Result.fail("未找到要删除的竞赛信息");
+ }
+ return "竞赛信息删除成功";
+ }
+
+ /**
+ * 更新竞赛信息
+ *
+ * @param competition 待更新的竞赛信息
+ * @return 更新后的竞赛信息
+ */
+ @PutMapping("/update")
+ public Object updateCompetition(CompetitionTable competition, HttpServletRequest request) {
+ log.info("更新竞赛信息 competition: {}", competition);
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ Integer a = (Integer) claims.get("userPrivileges");
+ // 检查用户是否有权限进行更新操作
+ if (2 == a) {
+ return Result.fail("无权限修改竞赛信息");
+ }
+
+ // 验证待更新的竞赛信息是否存在
+ Optional existingCompetition = competitionService.getCompetitionById(Long.valueOf(competition.getCompetitionId()));
+ if (!existingCompetition.isPresent()) {
+ return Result.fail("未找到指定的竞赛信息,无法进行更新");
+ }
+
+ // 执行更新操作
+ try {
+ return competitionService.updateCompetition(competition);
+ } catch (Exception e) {
+ // 处理更新操作中可能出现的异常
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "更新竞赛信息时发生错误");
+ }
+ }
+
+
+ /**
+ * 根据搜索词条模糊匹配竞赛名称或简介
+ *
+ * @param searchTerm 搜索词条,可以是竞赛的一部分名称或简介
+ * @return 匹配到的竞赛信息列表
+ */
+ @GetMapping("/search")
+ public Object searchCompetitions(String searchTerm) {
+
+ // 调用服务层的方法来执行基于competitionName的模糊搜索
+ List competitions = competitionService.searchCompetitionsByName(searchTerm);
+ if (competitions.isEmpty()) {
+ return Result.fail("未找到匹配的竞赛信息");
+ }
+ return competitions;
+ }
+
+ /**
+ * 获取所有竞赛信息的列表。
+ *
+ * @return 竞赛信息列表
+ */
+ @GetMapping("/list")
+ public Object listCompetitions() {
+ return competitionService.getAllCompetitions();
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/controller/EmailController.java b/System/src/main/java/com/example/system/controller/EmailController.java
new file mode 100644
index 0000000..3507ffc
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/EmailController.java
@@ -0,0 +1,110 @@
+package com.example.system.controller;
+import com.example.system.model.ArticleTable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.example.system.repository.ArticleRepository;
+import com.example.system.repository.RegistrationRepository;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.mail.*;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import java.util.List;
+import java.util.Optional;
+import java.util.Properties;
+import org.springframework.web.bind.annotation.CrossOrigin;
+
+@RestController
+@CrossOrigin
+@RequestMapping("/api")
+@Component
+public final class EmailController {
+ @Autowired
+ private RegistrationRepository registrationRepository;
+
+ @Autowired
+ private ArticleRepository articleRepository;
+
+ @PostMapping("/sendemail")
+ public ResponseEntity sendemail(@RequestParam Long competitionId, @RequestParam Integer articleId) {
+ Optional articleOpt = articleRepository.findById(articleId);
+ if (articleOpt.isEmpty()) {
+ return new ResponseEntity<>("未找到公告", HttpStatus.NOT_FOUND);
+ }
+ ArticleTable article = articleOpt.get();
+ List emails = registrationRepository.findompetitionemailId(competitionId);
+ if (emails.isEmpty()) {
+ return new ResponseEntity<>("未寻找到参加比赛的用户", HttpStatus.NOT_FOUND);
+ }
+ String briefContent = article.getBriefContent();
+ String articleTitle = article.getArticleTitle();
+ for (String email : emails) {
+ if (email != null && !email.isEmpty()) {
+ boolean sendStatus = sendMail(email, "您参加的 ["+articleTitle+"] 比赛有新的公告内容:\n" + briefContent +"\n请前往镐京学院竞赛管理平台官网查看。", "比赛公告");
+ if (!sendStatus) {
+ System.out.println("Failed to send email to: " + email);
+ }
+ }
+ }
+ return new ResponseEntity<>("邮件发送成功", HttpStatus.OK);
+ }
+
+ @Value("${mail.user}")
+ private String USER; // 发件人邮箱地址
+
+ @Value("${mail.password}")
+ private String PASSWORD; // 如果是qq邮箱可以使户端授权码
+
+ /**
+ * 发送邮件
+ * @param to 收件人邮箱
+ * @param text 邮件正文
+ * @param title 标题
+ */
+ public boolean sendMail(String to, String text, String title){
+ try {
+ final Properties props = new Properties();
+ props.put("mail.smtp.auth", "true");
+ props.put("mail.smtp.host", "smtpdm.aliyun.com"); // 请根据你的邮箱服务商替换为相应的地址
+
+ // 发件人的账号
+ props.put("mail.user", "shuguang@email.92wap.cn");
+ //发件人的密码
+ props.put("mail.password", "LIUSHUguang520");
+
+ Authenticator authenticator = new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ String userName = props.getProperty("mail.user");
+ String password = props.getProperty("mail.password");
+ return new PasswordAuthentication(userName, password);
+ }
+ };
+ Session mailSession = Session.getInstance(props, authenticator);
+
+ MimeMessage message = new MimeMessage(mailSession);
+ String username = props.getProperty("mail.user");
+ InternetAddress form = new InternetAddress(username);
+ message.setFrom(form);
+
+ InternetAddress toAddress = new InternetAddress(to);
+ message.setRecipient(Message.RecipientType.TO, toAddress);
+
+ message.setSubject(title);
+
+ message.setContent(text, "text/html;charset=UTF-8");
+
+ Transport.send(message);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+}
diff --git a/System/src/main/java/com/example/system/controller/InformationController.java b/System/src/main/java/com/example/system/controller/InformationController.java
new file mode 100644
index 0000000..f6113e5
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/InformationController.java
@@ -0,0 +1,87 @@
+package com.example.system.controller;
+
+import com.example.system.model.InformationTable;
+import com.example.system.model.ResultInformationTable;
+import com.example.system.model.UserTable;
+import com.example.system.service.InformationService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import org.apache.ibatis.javassist.NotFoundException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.crossstore.ChangeSetPersister;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
+
+import java.util.List;
+import org.springframework.web.bind.annotation.CrossOrigin;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.servlet.http.HttpSession;
+
+@RestController
+@CrossOrigin
+@RequestMapping("/api/information")
+public class InformationController {
+
+ @Autowired
+ private InformationService informationService;
+
+ // 获取用户的文档资料列表
+ @GetMapping("/user/{userId}")
+ public ResponseEntity> getUserInformation(@PathVariable("userId") Long userId) {
+ List informationList = informationService.getUserInformation(userId);
+ return new ResponseEntity<>(informationList, HttpStatus.OK);
+ }
+
+ // 创建新的文档资料
+ @PostMapping("/user/{userId}/competition/{competitionId}")
+ public ResponseEntity createInformation(@PathVariable("userId") Long userId,
+ @PathVariable("competitionId") Long competitionId,
+ @RequestBody InformationTable information) {
+ InformationTable createdInformation = informationService.createInformation(userId, competitionId, information);
+ return new ResponseEntity<>(createdInformation, HttpStatus.CREATED);
+ }
+
+ // 编辑文档资料
+ @PutMapping("/{informationId}")
+ public ResponseEntity updateInformation(@PathVariable("informationId") Long informationId,
+ @RequestBody InformationTable information) {
+ InformationTable updatedInformation;
+ try {
+ updatedInformation = informationService.updateInformation(informationId, information);
+ } catch (NotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ return new ResponseEntity<>(updatedInformation, HttpStatus.OK);
+ }
+
+ // 删除文档资料
+ @DeleteMapping("/{informationId}")
+ public ResponseEntity deleteInformation(@PathVariable("informationId") Long informationId) {
+ informationService.deleteInformation(informationId);
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ // 获取所有资料
+ @RequestMapping("/getAll")
+ public List getAll() {
+ return informationService.getAll();
+ }
+
+ //获取比赛相关的资料
+ @RequestMapping("/getPortion")
+ public List getPortion(Long competitionId) {
+ return informationService.getPortion(competitionId);
+ }
+ //获取自己的资料
+ @RequestMapping("/getSelf")
+ public List getSelf(HttpSession session) {
+ String toKen = (String) session.getAttribute("Authorization");
+ System.out.println("Token: " + toKen);
+ Claims claims = JWTUtil.checkToken(toKen);
+ Long userId = (Long) claims.get("userId");
+ return informationService.getSelf(userId);
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/controller/OssController.java b/System/src/main/java/com/example/system/controller/OssController.java
new file mode 100644
index 0000000..3053a5c
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/OssController.java
@@ -0,0 +1,130 @@
+package com.example.system.controller;
+
+import com.example.system.model.InformationTable;
+import com.example.system.repository.InformationRepository;
+import com.example.system.utils.OssUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/oss")
+@CrossOrigin
+public class OssController {
+
+ @Autowired
+ OssUtils ossUtils;
+
+ @Autowired
+ InformationRepository informationRepository; // 注入信息表的数据库操作接口
+
+ @PostMapping("uploadOneFile")
+ public String uploadFile(@RequestPart("file") MultipartFile file,
+ @RequestParam("userId") Long userId,
+ @RequestParam("competitionId") Long competitionId,
+ @RequestParam("relatedData") String relatedData) {
+ log.info("上传文件");
+ // 上传文件到oss并获取URL
+ String url = ossUtils.uploadOneFile(file);
+
+ // 存储URL、userId、competitionId和relatedData到数据库
+ InformationTable information = new InformationTable();
+ information.setPersonalInfo(url);
+ information.setUserId(userId);
+ information.setCompetitionId(competitionId);
+ information.setRelatedData(relatedData);
+ informationRepository.save(information);
+
+ return url;
+ }
+
+ @PostMapping("uploadArrayFile")
+ public List uploadArrayFile(@RequestBody UploadArrayRequest uploadArrayRequest) {
+ // 上传多个文件到oss并获取URL列表
+ List urls = ossUtils.uploadArrayFile(uploadArrayRequest.getFiles());
+ // 存储URL、userId、competitionId和relatedData到数据库
+ for (String url : urls) {
+ InformationTable information = new InformationTable();
+ information.setPersonalInfo(url);
+ information.setUserId(uploadArrayRequest.getUserId());
+ information.setCompetitionId(uploadArrayRequest.getCompetitionId());
+ information.setRelatedData(uploadArrayRequest.getRelatedData());
+ informationRepository.save(information);
+ }
+
+ return urls;
+ }
+
+ @PostMapping("deleteFile")
+ public boolean deleteFile(@RequestBody DeleteRequest deleteRequest) {
+ // 删除oss上的文件
+ boolean deleted = ossUtils.deleteFile(deleteRequest.getFileUrl());
+
+ // 如果文件删除成功,则从数据库中删除相应的记录
+ if (deleted) {
+ InformationTable information = informationRepository.findByPersonalInfo(deleteRequest.getFileUrl());
+ if (information != null) {
+ informationRepository.delete(information);
+ }
+ }
+
+ return deleted;
+ }
+
+ // 内部类用于接收上传多个文件请求的参数
+ static class UploadArrayRequest {
+ private MultipartFile[] files;
+ private Long userId;
+ private Long competitionId;
+ private String relatedData;
+
+ public MultipartFile[] getFiles() {
+ return files;
+ }
+
+ public void setFiles(MultipartFile[] files) {
+ this.files = files;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public Long getCompetitionId() {
+ return competitionId;
+ }
+
+ public void setCompetitionId(Long competitionId) {
+ this.competitionId = competitionId;
+ }
+
+ public String getRelatedData() {
+ return relatedData;
+ }
+
+ public void setRelatedData(String relatedData) {
+ this.relatedData = relatedData;
+ }
+ }
+
+ // 内部类用于接收删除文件请求的参数
+ static class DeleteRequest {
+ private String fileUrl;
+
+ public String getFileUrl() {
+ return fileUrl;
+ }
+
+ public void setFileUrl(String fileUrl) {
+ this.fileUrl = fileUrl;
+ }
+ }
+}
diff --git a/System/src/main/java/com/example/system/controller/PhoneSendCodeController.java b/System/src/main/java/com/example/system/controller/PhoneSendCodeController.java
new file mode 100644
index 0000000..ab1af55
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/PhoneSendCodeController.java
@@ -0,0 +1,142 @@
+package com.example.system.controller;
+
+import com.example.system.model.ArticleTable;
+import com.example.system.model.UserTable;
+import com.example.system.repository.ArticleRepository;
+import com.example.system.repository.RegistrationRepository;
+import com.example.system.advice.SmsBaoConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import javax.sql.RowSet;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Optional;
+import org.springframework.web.bind.annotation.CrossOrigin;
+@CrossOrigin
+@RestController
+public class PhoneSendCodeController {
+
+ @Autowired
+ private SmsBaoConfig smsBaoConfig;
+
+ @Autowired
+ private RegistrationRepository registrationRepository;
+
+ @Autowired
+ private ArticleRepository articleRepository;
+
+ // 发送文章简介给参赛者
+ @PostMapping("/api/sendsms")
+ public ResponseEntity sendArticleBriefToParticipants(@RequestParam Long competitionId, @RequestParam Integer articleId) {
+// // 根据文章ID查找文章
+ Optional articleOpt = articleRepository.findById(articleId);
+ if (articleOpt.isEmpty()) {
+ return new ResponseEntity<>("未找到公告", HttpStatus.NOT_FOUND);
+ }
+ ArticleTable article = articleOpt.get();
+
+ // 根据竞赛ID查找参赛者
+ List phone = registrationRepository.findByCompetitionId(competitionId);
+ if (phone.isEmpty()) {
+ return new ResponseEntity<>("未找到参加比赛的用户", HttpStatus.NOT_FOUND);
+ }
+
+ // 获取文章简介内容
+ String briefContent = article.getBriefContent();
+ String ArticleTitle = article.getArticleTitle();
+ // 遍历参赛者并发送短信
+ for (String i : phone) {
+ if (i != null && !i.isEmpty()) {
+ boolean sendStatus = sendSms(i, "【计算机社团】您参加的 ["+ArticleTitle+"] 比赛有新的公告内容:\n" + briefContent +"\n请前往管理平台查看。");
+ if (!sendStatus) {
+ System.out.println("Failed to send SMS to: " + i);
+ }
+ }
+ }
+
+ return new ResponseEntity<>("短信发送成功", HttpStatus.OK);
+ }
+
+ // 发送短信
+ private boolean sendSms(String phone, String content) {
+ try {
+ String username = smsBaoConfig.getUsername();
+ String password = smsBaoConfig.getPassword();
+ String encodedContent = encodeUrlString(content, "UTF-8");
+
+ String smsBaoUrl = "http://api.smsbao.com/sms";
+ String httpArg = "u=" + username + "&p=" + md5(password) + "&m=" + phone + "&c=" + encodedContent;
+
+ String result = request(smsBaoUrl, httpArg);
+ return "0".equals(result);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ // 发起 HTTP 请求
+ private String request(String smsBaoUrl, String httpArg) {
+ StringBuilder result = new StringBuilder();
+ smsBaoUrl = smsBaoUrl + "?" + httpArg;
+
+ try {
+ URL url = new URL(smsBaoUrl);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+ InputStream is = connection.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ String strRead;
+ while ((strRead = reader.readLine()) != null) {
+ result.append(strRead);
+ }
+ reader.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result.toString();
+ }
+
+ // 计算 MD5 值
+ private String md5(String password) {
+ StringBuilder buf = new StringBuilder();
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(password.getBytes());
+ byte[] b = md.digest();
+ for (byte value : b) {
+ int i = value;
+ if (i < 0) i += 256;
+ if (i < 16) buf.append("0");
+ buf.append(Integer.toHexString(i));
+ }
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return buf.toString();
+ }
+
+ // 对字符串进行 URL 编码
+ private String encodeUrlString(String content, String charset) {
+ String strret = null;
+ if (content == null) return content;
+ try {
+ strret = java.net.URLEncoder.encode(content, charset);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return strret;
+ }
+}
diff --git a/System/src/main/java/com/example/system/controller/RegistrationController.java b/System/src/main/java/com/example/system/controller/RegistrationController.java
new file mode 100644
index 0000000..bb8479e
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/RegistrationController.java
@@ -0,0 +1,123 @@
+package com.example.system.controller;
+
+import com.example.system.model.RegistrationTable;
+import com.example.system.model.Result;
+import com.example.system.service.RegistrationService;
+import com.example.system.utils.JWTUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+@CrossOrigin
+@Slf4j
+@RestController
+@RequestMapping("/registration")
+public class RegistrationController {
+
+ private final RegistrationService registrationService;
+
+ @Autowired
+ public RegistrationController(RegistrationService registrationService) {
+ this.registrationService = registrationService;
+ }
+
+ /**
+ * 根据参赛类型获取参赛人数
+ * @return
+ */
+ @GetMapping("/getCountByCompetitionType")
+ public Object getCountByCompetitionType(String competitionType) {
+ log.info("根据参赛类型获取参赛人数 competitionType: {}", competitionType);
+ return registrationService.getCountByCompetitionType(competitionType);
+ }
+
+ /**
+ * 获取获奖人员的参赛记录
+ * @return
+ */
+ @GetMapping("/getWinInfo")
+ public Object getWinInfo() {
+ return registrationService.getWinInfo();
+ }
+
+ /**
+ * 获取参赛总人数
+ * @return
+ */
+ @RequestMapping("/getCount")
+ public Object getCount() {
+ return registrationService.getCount();
+ }
+
+ /**
+ * 获取成功报名并获奖的总人数
+ * @return
+ */
+ public Object getWinCount() {
+ return registrationService.getWinCount();
+ }
+
+ /**
+ * 根据获奖等级获取参赛人数
+ * @return
+ */
+ @RequestMapping("/getWinCountByLevel")
+ public Object getCountBy(String level) {
+ log.info("根据获奖等级获取参赛人数");
+ return registrationService.getCountByLevel(level);
+ }
+
+ // 学生报名比赛
+ @PostMapping("/enroll")
+ public Object enrollInCompetition(RegistrationTable registration, HttpServletRequest request) {
+ log.info("学生报名比赛 registration: {}", registration);
+ String token =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(token);
+ Integer userPrivileges = (Integer) claims.get("userPrivileges");
+ if (userPrivileges != 2) {
+ return Result.fail("只有学生可以报名");
+ }
+ return registrationService.enroll(registration);
+ }
+
+ // 教师审核学生的报名
+ @PutMapping("/review")
+ public Object reviewEnrollment(Long registrationId, String status, HttpServletRequest request) {
+ log.info("教师审核学生的报名");
+ String token =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(token);
+ Integer userPrivileges = (Integer) claims.get("userPrivileges");
+ if (userPrivileges == 2) {
+ return Result.fail("只有教师可以审核报名");
+ }
+ return registrationService.updateStatus(registrationId, status);
+ }
+
+ //获取所有的报名信息
+ @GetMapping("/getAll")
+ public Object getAll(HttpServletRequest request) {
+ log.info("获取所有的报名信息");
+ String token =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(token);
+ Integer userPrivileges = (Integer) claims.get("userPrivileges");
+// if (userPrivileges == 2) {
+// return Result.fail("只有教师可以");
+// }
+ return registrationService.getAll();
+ }
+ //教师修改获奖等级和证书路径和附加信息
+ @RequestMapping("/update")
+ public Object updateRegistration(RegistrationTable table, HttpServletRequest request) {
+ log.info("教师修改学生报名信息");
+ String token =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(token);
+ Integer userPrivileges = (Integer) claims.get("userPrivileges");
+ if (userPrivileges == 2) {
+ return Result.fail("只有教师可以修改");
+ }
+ return registrationService.update(table);
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/controller/UserController.java b/System/src/main/java/com/example/system/controller/UserController.java
new file mode 100644
index 0000000..e01300f
--- /dev/null
+++ b/System/src/main/java/com/example/system/controller/UserController.java
@@ -0,0 +1,232 @@
+package com.example.system.controller;
+
+import com.example.system.model.Result;
+import com.example.system.model.UserTable;
+import com.example.system.service.UserService;
+import com.example.system.utils.JWTUtil;
+import com.example.system.utils.MD5Util;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ResponseStatusException;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@Slf4j
+@RestController
+@Resource
+@CrossOrigin
+@RequestMapping("/user")
+public class UserController {
+ private final UserService userService;
+ private final PasswordEncoder passwordEncoder; // 注入 PasswordEncoder
+
+ public UserController(UserService userService, PasswordEncoder passwordEncoder) {
+ this.userService = userService;
+ this.passwordEncoder = passwordEncoder; // 注入 PasswordEncoder
+ }
+
+ /**
+ * 获取学生总数量
+ * @return
+ */
+ @RequestMapping("/getStudentCount")
+ public Object getStudentCount() {
+ log.info("获取学生总数量");
+ return userService.getStudentCount();
+ }
+
+ /**
+ * 获取老师总数量
+ * @return
+ */
+ @RequestMapping("/getTeacherCount")
+ public Object getTeacherCount() {
+ log.info("获取老师总数量");
+ return userService.getTeacherCount();
+ }
+
+ /**
+ * 获取用户总数量
+ * @return
+ */
+ @RequestMapping("/getCount")
+ public Object getCount() {
+ log.info("获取用户总数量");
+ return userService.getCount();
+ }
+
+ //批量删除用户
+ @DeleteMapping("/deleteList")
+ public Object deleteList(@RequestParam("list") List list, HttpServletRequest request) {
+ log.info("批量删除用户 list: {}", list);
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ Integer a = (Integer) claims.get("userPrivileges");
+ // 检查用户是否有权限添加竞赛信息
+ if (2 == a) {
+ // 如果用户无权限,禁止访问
+ return Result.fail("禁止删除用户");
+ }
+ return userService.deleteList(list);
+ }
+ //登录
+ @PostMapping("/login")
+ public Object login(@RequestBody Map requestData) {
+ String sTId = requestData.get("sTId");
+ String password = requestData.get("password");
+ System.out.println(requestData);
+ log.info("用户登录尝试 -> sTId: {}, password: [PROTECTED]", sTId);
+
+ if (!StringUtils.hasLength(sTId) || !StringUtils.hasLength(password)) {
+ return Result.fail("用户名或密码不能为空");
+ }
+
+ UserTable user = userService.findBySTId(sTId);
+
+ if (user == null || !MD5Util.verify(password, user.getUserPassword())) {
+ return Result.fail("用户名或密码错误");
+ }
+
+ log.info("登录成功: 用户ID: {}, 用户权限等级: {}", user.getUserId(), user.getUserPrivileges());
+ Map claims = new HashMap<>();
+ claims.put("userId", user.getUserId());
+ claims.put("userName", user.getUserName());
+ claims.put("sTId", user.getSTId());
+ claims.put("userPrivileges", user.getUserPrivileges());
+
+ String token = JWTUtil.getToken(claims);
+ return token;
+ }
+
+
+// /**
+// * 用户查看个人信息
+// * 假设用户已通过身份验证,并且我们可以从身份验证令牌中提取用户ID
+// *
+// * @param id 用户的学号或员工号
+// * @return 用户的个人信息
+// */
+ @GetMapping("/getUserInfo")
+ public Object getUserInfo(HttpServletRequest request) {
+ log.info("用户查看个人信息");
+ //先暂时这样写,因为现在还没有前端的支持
+ String toKen =request.getHeader("Authorization");
+
+ System.out.println("Token: " + toKen);
+ Claims claims = JWTUtil.checkToken(toKen);
+ UserTable user = userService.findBySTId((String) claims.get("sTId"));
+ if (user != null) {
+ return user; // Assuming UserTable has a method toMap() that converts it to a map
+ } else {
+ return Result.fail("未找到用户信息");
+ }
+ }
+
+ //更新用户个人信息 只能更新phone, email, user_password
+ @PutMapping("/update")
+ public Object updateUser(UserTable user, HttpServletRequest request) {
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ user.setSTId((String) claims.get("sTId"));
+ if (!userService.updateUser(user)) {
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "用户信息更新失败");
+ }
+ return Result.success("用户信息更新成功");
+ }
+
+ //管理员更新用户信息
+ @PutMapping("/updateOther")
+ public Object updateOther(UserTable user, HttpServletRequest request) {
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ Integer privileges = (Integer) claims.get("userPrivileges");
+ if (privileges != 0 && !userService.updateOther(user)) {
+ throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "用户信息更新失败");
+ }
+ return Result.success("用户信息更新成功");
+ }
+ /**
+ * 处理创建新用户的请求
+ * 只有老师和管理员(权限为0或1)可以添加新用户
+ */
+ @PostMapping("/create")
+ public Object createUser(UserTable user, HttpServletRequest request) {
+ log.info("创建新用户 user: {}", user);
+ String token =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(token);
+ Integer userPrivileges = (Integer) claims.get("userPrivileges");
+ if (userPrivileges == null || userPrivileges == 2) {
+ return Result.fail("权限不足");
+ }
+ if ( user.getUserName() == null
+ || user.getUserPrivileges() == null
+ || user.getEmail() == null
+ || user.getUserPassword() == null
+ || user.getSTId() == null
+ || user.getCollegeId() == null)
+ {
+ return Result.fail("用户信息不全");
+ }
+ // 用户密码进行加密
+ user.setUserPassword(MD5Util.puzzle(user.getUserPassword()));
+ return Result.success(userService.createUser(user));
+ }
+ /**
+ * 处理查看所有用户的请求
+ * 只有老师和管理员(权限为0或1)可以查看用户列表
+ */
+
+ // 查看所有用户信息
+ @GetMapping("/getUserAll")
+ public Object getUserAll(HttpServletRequest request) {
+ log.info("查看所有用户信息");
+ HttpSession session = request.getSession(true);
+ String toKen =request.getHeader("Authorization");
+ Claims claims = JWTUtil.checkToken(toKen);
+ List userList = userService.findAllUsers();
+// if (claims != null && ((Integer) claims.get("userPrivileges")) == 2) {
+// // 权限不足
+// return Result.fail("权限不足");
+// }
+ return userList;
+ }
+
+ // 用户导入接口
+ @PostMapping("/user/import")
+ public ResponseEntity importUsers(@RequestBody List userDataList) {
+ // 检查上传的用户数据列表是否为空
+ if (userDataList == null || userDataList.isEmpty()) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("上传的用户数据列表不能为空");
+ }
+ // 设置默认的userStatus值为0
+ for (UserTable user : userDataList) {
+ if (user.getUserStatus() == null) {
+ user.setUserStatus(0);
+ }
+ if (user.getUserPassword() == null || user.getUserPassword().isEmpty()) {
+ // 假设学号字段为sid,将密码设置为123456
+ user.setUserPassword("123456");
+ }
+ }
+ try {
+ // 保存用户数据到数据库
+ userService.importUsers(userDataList);
+ return ResponseEntity.ok("用户导入成功");
+ } catch (Exception e) {
+ e.printStackTrace();
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("用户导入失败");
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/dto/CreateUserDTO.java b/System/src/main/java/com/example/system/dto/CreateUserDTO.java
new file mode 100644
index 0000000..be62896
--- /dev/null
+++ b/System/src/main/java/com/example/system/dto/CreateUserDTO.java
@@ -0,0 +1,30 @@
+package com.example.system.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+@Getter
+@Setter
+public class CreateUserDTO {
+ @NotBlank(message = "用户名不能为空")
+ @Size(min = 3, max = 50, message = "用户名长度必须在3到50字符之间")
+ private String userName;
+
+ @NotBlank(message = "密码不能为空")
+ @Size(min = 6, message = "密码长度不能少于6个字符")
+ private String password; // 密码校验应当在后端处理加密
+
+ @NotBlank(message = "电子邮件不能为空")
+ @Email(message = "电子邮件格式不正确")
+ private String email;
+
+ @NotNull(message = "用户权限不能为空")
+ private Integer userPrivileges; // 其他所需字段...
+
+ // Lombok注解自动生成Getter和Setter
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/mapper/ArticleMapper.java b/System/src/main/java/com/example/system/mapper/ArticleMapper.java
new file mode 100644
index 0000000..e4fe149
--- /dev/null
+++ b/System/src/main/java/com/example/system/mapper/ArticleMapper.java
@@ -0,0 +1,33 @@
+package com.example.system.mapper;
+
+import com.example.system.model.ArticleTable;
+import org.apache.ibatis.annotations.*;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import java.util.List;
+
+@Mapper
+public interface ArticleMapper {
+
+ //获取历史文章记录并按照升序排列
+ @Select("select * from article_table order by publish_time asc;")
+ List getHistoryArticle();
+
+ //发布文章
+ Integer createArticle(ArticleTable article);
+
+ //根据文章id来获取对应的文章
+ @Select("select * from article_table where article_id=#{id};")
+ ArticleTable getArticleById(Integer id);
+
+ //根据文章id来删除对应的文章
+ @Delete("DELETE FROM article_table WHERE article_id = #{id};")
+ Integer deleteArticleById(Integer userId);
+
+ //更新对应的文章信息
+ @Update("UPDATE article_table SET " +
+ "article_title = #{articleTitle}, brief_content = #{briefContent}, " +
+ "article_content = #{articleContent}, article_type = #{articleType} , publish_time=#{publishTime}" +
+ "WHERE article_id = #{articleId}")
+ Integer updataArtical(ArticleTable articleTable);
+}
diff --git a/System/src/main/java/com/example/system/mapper/CommentMapper.java b/System/src/main/java/com/example/system/mapper/CommentMapper.java
new file mode 100644
index 0000000..a9b6e91
--- /dev/null
+++ b/System/src/main/java/com/example/system/mapper/CommentMapper.java
@@ -0,0 +1,28 @@
+package com.example.system.mapper;
+
+import com.example.system.model.CommentTable;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Mapper
+public interface CommentMapper {
+ //删除对应文章的所有评论
+ @Delete("DELETE FROM comment_table WHERE article_id = #{id};")
+ Integer deleteCommentByArticleId(Integer id);
+
+ //根据文章id获取所有的评论
+ @Select("select * from comment_table where article_id=#{id}")
+ List getCommentById(Integer id);
+
+ //根据评论id获取对应的评论
+ @Select("select * from comment_table where comment_id=#{id}")
+ CommentTable getById(Long id);
+
+ //根据评论id删除评论
+ @Delete("DELETE from comment_table where comment_id=#{id};")
+ int deleteById(Long id);
+}
diff --git a/System/src/main/java/com/example/system/mapper/CompetitionMapper.java b/System/src/main/java/com/example/system/mapper/CompetitionMapper.java
new file mode 100644
index 0000000..9c0f0f6
--- /dev/null
+++ b/System/src/main/java/com/example/system/mapper/CompetitionMapper.java
@@ -0,0 +1,17 @@
+package com.example.system.mapper;
+
+import com.example.system.model.ResultCompetitionTable;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface CompetitionMapper {
+ //获取所有竞赛信息
+ @Select("select * from competition_table;")
+ List getCompetition();
+
+ @Select("select competition_name from competition_table where competition_id=#{competitionId}")
+ String getNameById(Long competitionId);
+}
diff --git a/System/src/main/java/com/example/system/mapper/InformationMapper.java b/System/src/main/java/com/example/system/mapper/InformationMapper.java
new file mode 100644
index 0000000..914a99d
--- /dev/null
+++ b/System/src/main/java/com/example/system/mapper/InformationMapper.java
@@ -0,0 +1,17 @@
+package com.example.system.mapper;
+
+import com.example.system.model.ResultInformationTable;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface InformationMapper {
+ //获取指定项目的所有资料
+ @Select("select * from information_table where competition_id=#{competitionId};")
+ List getPortion(Long competitionId);
+ //获取自己的所有资料
+ @Select("select * from information_table where user_id=#{userId};")
+ List getSelf(Long userId);
+}
diff --git a/System/src/main/java/com/example/system/mapper/RegistrationMapper.java b/System/src/main/java/com/example/system/mapper/RegistrationMapper.java
new file mode 100644
index 0000000..bd42f10
--- /dev/null
+++ b/System/src/main/java/com/example/system/mapper/RegistrationMapper.java
@@ -0,0 +1,51 @@
+package com.example.system.mapper;
+
+import com.example.system.model.RegistrationTable;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import java.util.List;
+
+@Mapper
+public interface RegistrationMapper {
+ //插入信息
+ @Insert("insert into registration_table" +
+ "(student_id, competition_id, team_leader_id, competition_type, registration_time, registration_status) values " +
+ "(#{studentId}, #{competitionId}, #{teamLeaderId}, #{competitionType}, #{registrationTime}, #{registrationStatus})")
+ Integer creatData(RegistrationTable registration);
+
+ //获取所有报名信息
+ @Select("select * from registration_table")
+ List getRegistration();
+
+ //修改报名审核状态
+ @Update("update registration_table set registration_status= #{status} where registration_id=#{registrationId};")
+ Integer updateStatus(Long registrationId, String status);
+ //修改获奖等级和证书路径和附加信息
+ @Update("update registration_table set " +
+ "award_level = #{awardLevel}, " +
+ "certificate_path = #{certificatePath},"+
+ "additional_info = #{additionalInfo}"+
+ "where registration_id=#{registrationId};")
+ Integer update(RegistrationTable table);
+
+ //获取获奖人员的参赛记录
+ @Select("SELECT * FROM registration_table WHERE award_level IS NOT NULL;")
+ List getWinInfo();
+ //获取参赛总人数
+ @Select("SELECT COUNT(registration_id) FROM registration_table;")
+ Integer getCount();
+
+ //获取成功报名并获奖的总人数
+ @Select("SELECT COUNT(registration_id) FROM registration_table WHERE award_level IS NOT NULL AND registration_status = '成功报名';")
+ Object getWinCount();
+ //根据参赛类型获取参赛人数
+ @Select("SELECT * FROM registration_table WHERE competition_id=(SELECT competition_id FROM competition_table WHERE competition_name=#{competitionType});")
+ Object getCountByCompetitionType(String competitionType);
+ //根据获奖等级获取参赛人数
+ @Select("SELECT COUNT(*) FROM registration_table WHERE award_level=#{level};")
+ Object getCountByLevel(String level);
+}
diff --git a/System/src/main/java/com/example/system/mapper/UserMapper.java b/System/src/main/java/com/example/system/mapper/UserMapper.java
new file mode 100644
index 0000000..b237830
--- /dev/null
+++ b/System/src/main/java/com/example/system/mapper/UserMapper.java
@@ -0,0 +1,64 @@
+package com.example.system.mapper;
+
+import com.example.system.model.UserTable;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+@Mapper
+public interface UserMapper {
+
+ @Insert("INSERT INTO user_table (user_name, s_t_id, user_password, email, phone, user_privileges, college_id) " +
+ "VALUES (#{userName}, #{sTId}, #{userPassword}, #{email}, #{phone}, #{userPrivileges}, #{collegeId})")
+ @Options(useGeneratedKeys = true, keyProperty = "userId")
+ void createUser(UserTable user);
+
+ @Select("SELECT * FROM user_table WHERE s_t_id=#{sTId}")
+ UserTable findBySTId(String sTId);
+
+ @Update("UPDATE user_table SET phone=#{phone}, email=#{email}, user_password=#{userPassword} WHERE s_t_id=#{sTId} and user_status=0")
+ Integer updateUser(UserTable user);
+
+ @Update("UPDATE user_table SET user_status=0 WHERE s_t_id=#{sTId}")
+ Integer updateUserStatus(String sTId);
+
+ @Select("SELECT * FROM user_table WHERE user_name=#{userName} and user_status=0")
+ UserTable findUserByUserName(String userName);
+
+ @Select("SELECT * FROM user_table WHERE user_id=#{userId} and user_status=0")
+ UserTable findUserById(Long userId);
+
+ @Select("SELECT * FROM user_table WHERE user_status=0")
+ List findAllUsers();
+
+ //批量删除用户
+ @Update("")
+ Integer deleteList(List list);
+ //根据用户id查找用户姓名
+ @Select("select user_name from user_table where user_id=#{studentId}")
+ String getNameById(Integer studentId);
+
+ @Update("update user_table SET " +
+ "user_name=#{userName}, s_t_id=#{sTId}, user_password=#{userPassword}, " +
+ "user_privileges=#{userPrivileges}, college_id=#{collegeId}, major_table_id=#{majorTableId}," +
+ "teacher_title=#{teacherTitle},birthdate=#{birthdate},gender=#{gender}," +
+ "phone=#{phone}, email=#{email}, user_password=#{userPassword}" +
+ "WHERE user_id=#{userId}")
+ int updateOther(UserTable user);
+
+ //获取用户总数量
+ @Select("SELECT COUNT(user_id) FROM user_table;")
+ Object getCount();
+
+ //获取老师总数量
+ @Select("SELECT COUNT(user_id) FROM user_table WHERE user_privileges=1;")
+ Object getTeacherCount();
+
+ //获取学生总数量
+ @Select("SELECT COUNT(user_id) FROM user_table WHERE user_privileges=2;")
+ Object getStudentCount();
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/model/ArticleTable.java b/System/src/main/java/com/example/system/model/ArticleTable.java
new file mode 100644
index 0000000..ffe8fa4
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/ArticleTable.java
@@ -0,0 +1,32 @@
+package com.example.system.model;
+
+import com.example.system.utils.DateUtil;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Data
+@Entity
+@Table(name = "article_table")
+public class ArticleTable {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // 假设使用的是自增主键
+ private Integer articleId;
+
+ private Integer userId;
+
+ @Column(name = "competition_id") // 明确指定数据库中的列名
+ private Integer competitionId;
+
+ private String articleTitle;
+
+ private String briefContent;
+
+ private String articleContent;
+
+ private String articleType;
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date publishTime;
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/model/CollegeTable.java b/System/src/main/java/com/example/system/model/CollegeTable.java
new file mode 100644
index 0000000..467523b
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/CollegeTable.java
@@ -0,0 +1,19 @@
+package com.example.system.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * 学院实体类,对应数据库中的college_table表。
+ */
+@Data // Lombok注解,自动生成getters和setters等。
+@Entity // JPA注解,标记这是一个实体类。
+@Table(name = "college_table") // JPA注解,指定这个实体类对应的表名是college_table。
+public class CollegeTable {
+ @Id // JPA注解,标记这个字段为表的主键。
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // JPA注解,标记主键的生成策略为数据库自增。
+ private Long collegeId; // 学院ID,对应college_table表中的college_id字段,为自增长主键。
+
+ private String collegeName; // 学院名称,对应college_table表中的college_name字段。
+}
diff --git a/System/src/main/java/com/example/system/model/CommentTable.java b/System/src/main/java/com/example/system/model/CommentTable.java
new file mode 100644
index 0000000..437f9c3
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/CommentTable.java
@@ -0,0 +1,31 @@
+package com.example.system.model;
+
+import com.example.system.utils.DateUtil;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * 评论实体类,对应数据库中的comment_table表。
+ */
+@Data // Lombok注解,用于自动生成getter、setter、toString、equals、hashCode方法。
+@Entity // JPA注解,标记这是一个JPA实体。
+@Table(name = "comment_table") // JPA注解,用于指定实体对应的数据库表名。
+public class CommentTable {
+ @Id // JPA注解,指明这个字段是表的主键。
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // JPA注解,主键的生成策略为数据库自增。
+ private Long commentId; // 评论ID,对应数据库中的comment_id字段。
+
+ @JoinColumn(name = "user_id", nullable = false) // JPA注解,指定用于关联的外键列。
+ private Integer userId; // 对应数据库中的user_id外键。
+
+ @JoinColumn(name = "article_id", nullable = false) // JPA注解,指定用于关联的外键列。
+ private Integer articleId; // 文章实体,对应数据库中的article_id外键。
+
+ @Column(nullable = false) // JPA注解,配置列的详细信息,比如非空约束。
+ private String commentContent; // 评论内容,对应数据库中的comment_content字段。
+
+ @Column(nullable = false) // JPA注解,配置列的详细信息,比如非空约束。
+ private Date publishTime; // 发布时间,对应数据库中的publish_time字段。
+}
diff --git a/System/src/main/java/com/example/system/model/CompetitionTable.java b/System/src/main/java/com/example/system/model/CompetitionTable.java
new file mode 100644
index 0000000..3c5127d
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/CompetitionTable.java
@@ -0,0 +1,41 @@
+package com.example.system.model;
+
+import com.example.system.utils.DateUtil;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * 竞赛实体类,对应数据库中的competition_table表。
+ */
+@Data // Lombok注解,为类的所有字段自动生成getter和setter方法,以及toString、equals、hashCode方法。
+@Entity // JPA注解,标记该类为一个JPA实体。
+@Table(name = "competition_table") // JPA注解,指定该实体对应的数据库表名。
+public class CompetitionTable {
+ @Id // JPA注解,指示该字段为表的主键。
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // JPA注解,主键的生成策略为数据库自增。
+ private Long competitionId; // 竞赛ID,对应数据库中的competition_id字段。
+
+ @Column(nullable = false, length = 50) // JPA注解,配置列的详细信息,如非空约束和长度限制。
+ private String competitionName; // 竞赛名称,对应数据库中的competition_name字段。
+
+ @JoinColumn(name = "user_id", nullable = false) // JPA注解,指定用于关联的外键列。
+ private Integer userId; // 对应数据库中的user_id外键。
+
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Column(nullable = false) // JPA注解,配置列的详细信息,如非空约束。
+ private Date registrationStartTime; // 注册开始时间,对应数据库中的registration_start_time字段。
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Column(nullable = false) // JPA注解,配置列的详细信息,如非空约束。
+ private Date registrationEndTime; // 注册结束时间,对应数据库中的registration_end_time字段。
+
+ private String announcementLink; // 公告链接,对应数据库中的announcement_link字段。
+
+ @Column(nullable = false) // JPA注解,配置列的详细信息,如非空约束和默认值。
+ private Integer competitionStatus = 0; // 竞赛状态,对应数据库中的competition_status字段,默认为0。
+
+}
diff --git a/System/src/main/java/com/example/system/model/InformationTable.java b/System/src/main/java/com/example/system/model/InformationTable.java
new file mode 100644
index 0000000..47b561e
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/InformationTable.java
@@ -0,0 +1,60 @@
+package com.example.system.model;
+
+import lombok.Getter;
+
+import javax.persistence.*;
+
+@Getter
+@Entity
+@Table(name = "information_table")
+public class InformationTable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "profile_id")
+ private Long profileId;
+
+ @Column(name = "user_id")
+ private Long userId;
+
+ @Column(name = "competition_id")
+ private Long competitionId;
+
+ @Column(name = "personal_info", columnDefinition = "TEXT")
+ private String personalInfo;
+
+ @Column(name = "related_data", columnDefinition = "TEXT")
+ private String relatedData;
+
+ // Constructors, Getters, and Setters
+
+ public InformationTable() {
+ }
+
+ public InformationTable(Long userId, Long competitionId, String personalInfo, String relatedData) {
+ this.userId = userId;
+ this.competitionId = competitionId;
+ this.personalInfo = personalInfo;
+ this.relatedData = relatedData;
+ }
+
+ public void setProfileId(Long profileId) {
+ this.profileId = profileId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public void setCompetitionId(Long competitionId) {
+ this.competitionId = competitionId;
+ }
+
+ public void setPersonalInfo(String personalInfo) {
+ this.personalInfo = personalInfo;
+ }
+
+ public void setRelatedData(String relatedData) {
+ this.relatedData = relatedData;
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/model/MajorTable.java b/System/src/main/java/com/example/system/model/MajorTable.java
new file mode 100644
index 0000000..d42093c
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/MajorTable.java
@@ -0,0 +1,25 @@
+package com.example.system.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * 专业实体类,对应数据库中的major_table表。
+ */
+@Data // Lombok库的注解,自动为类的字段生成getter、setter方法以及toString、equals、hashCode方法。
+@Entity // JPA注解,标记这是一个JPA实体。
+@Table(name = "major_table") // JPA注解,指定这个实体对应的数据库表名。
+public class MajorTable {
+ @Id // JPA注解,表明该字段为表的主键。
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // JPA注解,指定主键的生成策略为数据库的自增。
+ @Column(name = "major_table_id") // JPA注解,指定映射到数据库表的哪个列。
+ private Long majorTableId; // 专业ID,对应数据库中的major_table_id字段,为自增长主键。
+
+ @Column(name = "major_table_name") // JPA注解,指定映射到数据库表的哪个列。
+ private String majorTableName; // 专业名称,对应数据库中的major_table_name字段。
+
+ @ManyToOne(fetch = FetchType.LAZY) // JPA注解,标明该字段表示多对一的关联关系。
+ @JoinColumn(name = "college_id") // JPA注解,指定用于关联的外键列。
+ private CollegeTable college; // 关联的学院实体,对应数据库中的college_id外键。
+}
diff --git a/System/src/main/java/com/example/system/model/RegistrationTable.java b/System/src/main/java/com/example/system/model/RegistrationTable.java
new file mode 100644
index 0000000..b2d2acb
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/RegistrationTable.java
@@ -0,0 +1,47 @@
+package com.example.system.model;
+
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * 报名实体类,对应数据库中的registration_table表。
+ */
+@Data // Lombok注解,自动生成getter、setter、toString、equals、hashCode方法。
+@Entity // JPA注解,标记这是一个JPA实体。
+@Table(name = "registration_table") // JPA注解,指定实体对应的数据库表名。
+public class RegistrationTable {
+ @Id // JPA注解,指示这个字段是表的主键。
+ @GeneratedValue(strategy = GenerationType.IDENTITY) // JPA注解,主键的生成策略为数据库自增。
+ private Long registrationId; // 报名ID,对应数据库中的registration_id字段。
+
+ @JoinColumn(name = "student_id", nullable = false) // JPA注解,指定用于关联的外键列。
+ private Integer studentId; //对应数据库中的student_id外键。
+ private String studentName;
+
+ @JoinColumn(name = "competition_id", nullable = false) // JPA注解,指定用于关联的外键列。
+ private Long competitionId; //对应数据库中的competition_id外键。
+ private String competitionName;
+
+ @JoinColumn(name = "team_leader_id") // JPA注解,指定用于关联的外键列。
+ private Integer teamLeaderId; // 团队领导者实体,对应数据库中的team_leader_id外键。
+ private String teamLeaderName;
+
+ @Column(nullable = false) // JPA注解,配置列的详细信息,如非空约束。
+ private String competitionType; // 竞赛类型,对应数据库中的competition_type字段。
+
+ private String awardLevel; // 获奖等级,对应数据库中的award_level字段。
+
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Column(nullable = false) // JPA注解,配置列的详细信息,如非空约束。
+ private Date registrationTime; // 报名时间,对应数据库中的registration_time字段。
+
+ @Column(nullable = false) // JPA注解,配置列的详细信息,如非空约束。
+ private String registrationStatus; // 报名状态,对应数据库中的registration_status字段。
+
+ private String certificatePath; // 证书路径,对应数据库中的certificate_path字段。
+
+ private String additionalInfo; // 额外信息,对应数据库中的additional_info字段。
+}
diff --git a/System/src/main/java/com/example/system/model/Result.java b/System/src/main/java/com/example/system/model/Result.java
new file mode 100644
index 0000000..b370b5b
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/Result.java
@@ -0,0 +1,49 @@
+package com.example.system.model;
+
+import com.example.system.constant.ResultCode;
+import lombok.Data;
+
+@Data
+public class Result{
+ private ResultCode code;//状态码
+ private String errorInfo;//异常信息
+ T data;//成功信息
+
+ public Integer getCode() {
+ return code.getCode();
+ }
+
+ /**
+ * 后端响应成功
+ * @param data
+ * @return
+ * @param
+ */
+ public static Result success(T data) {
+ Result ret = new Result<>();
+ ret.code = ResultCode.SUCCESS;
+ ret.data = data;
+ return ret;
+ }
+ /**
+ * 后端响应失败
+ * @param error
+ * @return
+ */
+ public static Result fail(String error) {
+ Result ret = new Result<>();
+ ret.code = ResultCode.FAIL;
+ ret.data = error;
+ return ret;
+ }
+ /**
+ * 用户未登录
+ * @return
+ */
+ public static Result notLogin() {
+ Result ret = new Result<>();
+ ret.code = ResultCode.NOT_LOGIN;
+ ret.errorInfo = "请登录";
+ return ret;
+ }
+}
diff --git a/System/src/main/java/com/example/system/model/ResultCompetitionTable.java b/System/src/main/java/com/example/system/model/ResultCompetitionTable.java
new file mode 100644
index 0000000..9509ff8
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/ResultCompetitionTable.java
@@ -0,0 +1,17 @@
+package com.example.system.model;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class ResultCompetitionTable {
+ private Long competitionId; // 竞赛ID,对应数据库中的competition_id字段。
+ private String competitionName; // 竞赛名称,对应数据库中的competition_name字段。
+ private Integer userId; // 对应数据库中的user_id外键。
+ private String userName;
+ private Date registrationStartTime; // 注册开始时间,对应数据库中的registration_start_time字段。
+ private Date registrationEndTime; // 注册结束时间,对应数据库中的registration_end_time字段。
+ private String announcementLink; // 公告链接,对应数据库中的announcement_link字段。
+ private Integer competitionStatus = 0; // 竞赛状态,对应数据库中的competition_status字段,默认为0。
+}
diff --git a/System/src/main/java/com/example/system/model/ResultInformationTable.java b/System/src/main/java/com/example/system/model/ResultInformationTable.java
new file mode 100644
index 0000000..eba58bf
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/ResultInformationTable.java
@@ -0,0 +1,14 @@
+package com.example.system.model;
+
+import lombok.Data;
+
+@Data
+public class ResultInformationTable {
+ private Long profileId;
+ private Long userId;
+ private String userName;
+ private Long competitionId;
+ private String competitionName;
+ private String personalInfo;
+ private String relatedData;
+}
diff --git a/System/src/main/java/com/example/system/model/UserTable.java b/System/src/main/java/com/example/system/model/UserTable.java
new file mode 100644
index 0000000..1294935
--- /dev/null
+++ b/System/src/main/java/com/example/system/model/UserTable.java
@@ -0,0 +1,59 @@
+package com.example.system.model;
+
+import com.example.system.utils.DateUtil;
+import lombok.Data;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Data
+@Entity
+@Table(name = "user_table")
+@EntityListeners(AuditingEntityListener.class)
+public class UserTable {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "user_id")
+ private Long userId;
+
+ @Column(name = "user_name", nullable = false, length = 50)
+ private String userName;
+
+ @Column(name = "s_t_id", nullable = false, length = 20)
+ private String sTId;
+
+ @Column(name = "user_password", nullable = false)
+ private String userPassword;
+
+ @Column(name = "user_privileges", nullable = false, columnDefinition = "INT DEFAULT 2")
+ private Integer userPrivileges;
+
+ @Column(name = "email", nullable = false, length = 50)
+ private String email;
+
+ @Column(name = "college_id", nullable = false)
+ private Integer collegeId;
+
+ @Column(name = "major_table_id")
+ private Integer majorTableId;
+
+ @Column(name = "phone", length = 20)
+ private String phone;
+
+ @Column(name = "teacher_title", length = 50)
+ private String teacherTitle;
+
+ @Column(name = "birthdate")
+ @Temporal(TemporalType.DATE)
+ private Date birthdate;
+
+ @Column(name = "gender", columnDefinition = "VARCHAR(10) CHECK (gender IN ('男', '女'))")
+ private String gender;
+
+ @Column(name = "user_status", columnDefinition = "INT DEFAULT 0")
+ private Integer userStatus;
+
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/repository/ArticleRepository.java b/System/src/main/java/com/example/system/repository/ArticleRepository.java
new file mode 100644
index 0000000..f6ae075
--- /dev/null
+++ b/System/src/main/java/com/example/system/repository/ArticleRepository.java
@@ -0,0 +1,19 @@
+package com.example.system.repository;
+
+import com.example.system.model.ArticleTable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import java.util.List; // 确保导入了List
+@Repository
+public interface ArticleRepository extends JpaRepository {
+ // 这里可以根据需要添加自定义的查询方法,例如:
+
+ // 根据文章类型查找文章
+ List findByArticleType(String articleType);
+
+ // 根据用户ID查找文章
+ List findByUserId(Integer userId);
+
+ // 根据竞赛ID查找文章
+ List findByCompetitionId(Integer competitionId);
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/repository/CommentRepository.java b/System/src/main/java/com/example/system/repository/CommentRepository.java
new file mode 100644
index 0000000..721093b
--- /dev/null
+++ b/System/src/main/java/com/example/system/repository/CommentRepository.java
@@ -0,0 +1,10 @@
+package com.example.system.repository;
+
+import com.example.system.model.CommentTable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface CommentRepository extends JpaRepository {
+ // 这里可以根据需要添加自定义的查询方法
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/repository/CompetitionRepository.java b/System/src/main/java/com/example/system/repository/CompetitionRepository.java
new file mode 100644
index 0000000..a400f57
--- /dev/null
+++ b/System/src/main/java/com/example/system/repository/CompetitionRepository.java
@@ -0,0 +1,14 @@
+package com.example.system.repository;
+
+import com.example.system.model.CompetitionTable;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+/**
+ * 竞赛信息的JPA仓库接口,提供对竞赛信息的CRUD操作及模糊搜索功能。
+ */
+public interface CompetitionRepository extends JpaRepository {
+ // 仅根据competitionName进行模糊搜索
+ List findByCompetitionNameContaining(String competitionName);
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/repository/InformationRepository.java b/System/src/main/java/com/example/system/repository/InformationRepository.java
new file mode 100644
index 0000000..bd6e1e1
--- /dev/null
+++ b/System/src/main/java/com/example/system/repository/InformationRepository.java
@@ -0,0 +1,14 @@
+package com.example.system.repository;
+
+import com.example.system.model.InformationTable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface InformationRepository extends JpaRepository {
+ List findByUserId(Long userId);
+
+ @Query("SELECT i FROM InformationTable i WHERE i.personalInfo = :personalInfo")
+ InformationTable findByPersonalInfo(String personalInfo);
+}
diff --git a/System/src/main/java/com/example/system/repository/RegistrationRepository.java b/System/src/main/java/com/example/system/repository/RegistrationRepository.java
new file mode 100644
index 0000000..cce69fb
--- /dev/null
+++ b/System/src/main/java/com/example/system/repository/RegistrationRepository.java
@@ -0,0 +1,23 @@
+package com.example.system.repository;
+
+import com.example.system.model.RegistrationTable;
+import com.example.system.model.UserTable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import java.util.List;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import java.util.List;
+
+public interface RegistrationRepository extends JpaRepository {
+ @Query(value = "SELECT u.phone " +
+ "FROM registration_table r " +
+ "JOIN user_table u ON r.student_id= u.user_id " +
+ " WHERE r.competition_id = ?", nativeQuery = true)
+ List findByCompetitionId(Long competitionId);
+ @Query(value = "SELECT u.email " +
+ "FROM registration_table r " +
+ "JOIN user_table u ON r.student_id= u.user_id " +
+ " WHERE r.competition_id = ?", nativeQuery = true)
+ List findompetitionemailId(Long competitionId);
+}
diff --git a/System/src/main/java/com/example/system/repository/UserRepository.java b/System/src/main/java/com/example/system/repository/UserRepository.java
new file mode 100644
index 0000000..9781bc2
--- /dev/null
+++ b/System/src/main/java/com/example/system/repository/UserRepository.java
@@ -0,0 +1,11 @@
+package com.example.system.repository;
+
+import com.example.system.model.UserTable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserRepository extends JpaRepository {
+ // 这里可以定义一些根据业务需求的方法,例如按名字查找用户等
+ // 示例:List findByName(String name);
+}
diff --git a/System/src/main/java/com/example/system/service/ArticleService.java b/System/src/main/java/com/example/system/service/ArticleService.java
new file mode 100644
index 0000000..2074538
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/ArticleService.java
@@ -0,0 +1,27 @@
+package com.example.system.service;
+
+import com.example.system.model.ArticleTable;
+import org.springframework.transaction.annotation.Transactional;
+import java.util.List;
+
+public interface ArticleService {
+ // 获取所有历史文章
+ List getHistoryArticle();
+
+ // 创建文章并在创建成功时发送短信通知
+ @Transactional
+ Integer createArticle(ArticleTable article);
+
+ // 根据文章ID获取文章
+ ArticleTable getArticleById(Integer id);
+
+ // 根据文章ID来删除对应的文章
+ Boolean deleteArticleById(Integer id);
+
+ // 修改文章
+ Boolean updateArticle(ArticleTable articleTable);
+
+ // 通知所有参与指定竞赛的用户(发送短信)
+ void notifyParticipants(Integer competitionId);
+
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/CommpentService.java b/System/src/main/java/com/example/system/service/CommpentService.java
new file mode 100644
index 0000000..37ab59b
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/CommpentService.java
@@ -0,0 +1,18 @@
+package com.example.system.service;
+
+import com.example.system.model.CommentTable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+public interface CommpentService {
+
+ //根据文章id获取所有的评论
+ List getCommentById(Integer id);
+
+ //根据评论id获取对应的评论
+ CommentTable getById(Long id);
+
+ //根据评论id删除评论
+ Boolean deleteById(Long id);
+}
diff --git a/System/src/main/java/com/example/system/service/CompetitionService.java b/System/src/main/java/com/example/system/service/CompetitionService.java
new file mode 100644
index 0000000..c72b64e
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/CompetitionService.java
@@ -0,0 +1,27 @@
+package com.example.system.service;
+
+import com.example.system.model.CompetitionTable;
+import com.example.system.model.ResultCompetitionTable;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface CompetitionService {
+ // 添加竞赛信息
+ CompetitionTable addCompetition(CompetitionTable competition);
+
+ // 尝试删除指定ID的竞赛信息,返回一个布尔值指示是否成功执行删除操作
+ boolean deleteCompetition(Long id);
+
+ // 更新竞赛信息
+ CompetitionTable updateCompetition(CompetitionTable competition);
+
+ // 根据ID获取竞赛信息
+ Optional getCompetitionById(Long id);
+
+ // 获取所有竞赛信息的列表
+ List getAllCompetitions();
+
+ // 根据搜索词条搜索竞赛信息
+ List searchCompetitionsByName(String searchTerm);
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/InformationService.java b/System/src/main/java/com/example/system/service/InformationService.java
new file mode 100644
index 0000000..011e58c
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/InformationService.java
@@ -0,0 +1,20 @@
+package com.example.system.service;
+
+import com.example.system.model.InformationTable;
+import com.example.system.model.ResultInformationTable;
+import org.apache.ibatis.javassist.NotFoundException;
+
+import java.util.List;
+
+public interface InformationService {
+ List getUserInformation(Long userId);
+ InformationTable createInformation(Long userId, Long competitionId, InformationTable information);
+ InformationTable updateInformation(Long informationId, InformationTable information) throws NotFoundException;
+ void deleteInformation(Long informationId);
+ //获取所有资料
+ List getAll();
+ //获取指定项目的所有资料
+ List getPortion(Long competitionId);
+ //获取自己的资料
+ List getSelf(Long userId);
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/RegistrationService.java b/System/src/main/java/com/example/system/service/RegistrationService.java
new file mode 100644
index 0000000..99471ed
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/RegistrationService.java
@@ -0,0 +1,24 @@
+package com.example.system.service;
+
+import com.example.system.model.RegistrationTable;
+
+public interface RegistrationService {
+ //学生报名比赛
+ Boolean enroll(RegistrationTable registration);
+ //根据id修改报名状态
+ Boolean updateStatus(Long registrationId, String status);
+ //获取所有的报名信息
+ Object getAll();
+ //教师修改获奖等级和证书路径和附加信息
+ Object update(RegistrationTable table);
+ //获取获奖人员的参赛记录
+ Object getWinInfo();
+ //获取参赛总人数
+ Object getCount();
+ //获取成功报名并获奖的总人数
+ Object getWinCount();
+ //根据参赛类型获取参赛人数
+ Object getCountByCompetitionType(String competitionType);
+ //根据获奖等级获取参赛人数
+ Object getCountByLevel(String level);
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/UserService.java b/System/src/main/java/com/example/system/service/UserService.java
new file mode 100644
index 0000000..2d47a2e
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/UserService.java
@@ -0,0 +1,52 @@
+package com.example.system.service;
+
+import com.example.system.dto.CreateUserDTO;
+import com.example.system.model.RegistrationTable;
+import com.example.system.model.UserTable;
+
+import java.util.List;
+
+public interface UserService {
+
+ UserTable findUserById(Long userId);
+
+ List findAllUsers();
+
+ boolean createUser(UserTable user);
+
+ boolean updateUser(UserTable user);
+
+
+ UserTable validateUserLogin(String userName, String password);
+
+ UserTable findUserByUserName(String userName);
+
+ UserTable getUserInfo(String studentId);
+
+ boolean updateStudentInfo(UserTable student);
+
+ UserTable findBySTId(String sTId);
+
+ boolean checkPassword(String password, String userPassword);
+
+
+
+ boolean createRegistration(RegistrationTable registration);
+
+ int getUserPrivileges(String username);
+
+ String getPhoneNumberByUserId(Integer userId);
+
+ List getUserIdsByCompetitionId(Integer competitionId);
+ void importUsers(List users);
+ //批量删除用户
+ Boolean deleteList(List list);
+ //管理员更新用户信息
+ boolean updateOther(UserTable user);
+ //获取用户总数量
+ Object getCount();
+ //获取老师总数量
+ Object getTeacherCount();
+ //获取学生总数量
+ Object getStudentCount();
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/impl/ArticleServiceImpl.java b/System/src/main/java/com/example/system/service/impl/ArticleServiceImpl.java
new file mode 100644
index 0000000..9344ee6
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/impl/ArticleServiceImpl.java
@@ -0,0 +1,61 @@
+package com.example.system.service.impl;
+
+import com.example.system.mapper.ArticleMapper;
+import com.example.system.mapper.CommentMapper;
+import com.example.system.model.ArticleTable;
+import com.example.system.model.UserTable;
+import com.example.system.repository.RegistrationRepository;
+import com.example.system.service.ArticleService;
+import com.example.system.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+public class ArticleServiceImpl implements ArticleService {
+
+ @Autowired
+ private ArticleMapper articleMapper;
+
+ @Autowired
+ private CommentMapper commentMapper;
+
+
+ @Override
+ @Transactional
+ public Integer createArticle(ArticleTable article) {
+ articleMapper.createArticle(article);
+ return article.getArticleId();
+ }
+
+
+ @Override
+ public List getHistoryArticle() {
+ return articleMapper.getHistoryArticle();
+ }
+
+ @Override
+ public ArticleTable getArticleById(Integer id) {
+ return articleMapper.getArticleById(id);
+ }
+
+ @Override
+ public Boolean deleteArticleById(Integer id) {
+ //删除该篇文章的评论
+ commentMapper.deleteCommentByArticleId(id);
+ //删除该篇文章
+ return articleMapper.deleteArticleById(id) == 1;
+ }
+
+ @Override
+ public Boolean updateArticle(ArticleTable articleTable) {
+ return articleMapper.updataArtical(articleTable) == 1;
+ }
+
+ @Override
+ public void notifyParticipants(Integer competitionId) {
+
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/impl/CommpentServiceimpl.java b/System/src/main/java/com/example/system/service/impl/CommpentServiceimpl.java
new file mode 100644
index 0000000..7bf0ccf
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/impl/CommpentServiceimpl.java
@@ -0,0 +1,32 @@
+package com.example.system.service.impl;
+
+import com.example.system.mapper.CommentMapper;
+import com.example.system.model.CommentTable;
+import com.example.system.service.CommpentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class CommpentServiceimpl implements CommpentService {
+ @Autowired
+ private CommentMapper commentMapper;
+
+ @Override//根据文章id获取所有的评论
+ public List getCommentById(Integer id) {
+ return commentMapper.getCommentById(id);
+ }
+
+ @Override
+ //根据评论id获取对应的评论
+ public CommentTable getById(Long id) {
+ return commentMapper.getById(id);
+ }
+
+ @Override
+ //根据评论id删除评论
+ public Boolean deleteById(Long id) {
+ return 1 == commentMapper.deleteById(id);
+ }
+}
diff --git a/System/src/main/java/com/example/system/service/impl/CompetitionServiceImpl.java b/System/src/main/java/com/example/system/service/impl/CompetitionServiceImpl.java
new file mode 100644
index 0000000..e5d05e9
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/impl/CompetitionServiceImpl.java
@@ -0,0 +1,75 @@
+package com.example.system.service.impl;
+
+import com.example.system.mapper.CompetitionMapper;
+import com.example.system.mapper.UserMapper;
+import com.example.system.model.CompetitionTable;
+import com.example.system.model.ResultCompetitionTable;
+import com.example.system.repository.CompetitionRepository;
+import com.example.system.service.CompetitionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class CompetitionServiceImpl implements CompetitionService {
+ private final CompetitionRepository competitionRepository;
+
+ @Autowired
+ private UserMapper userMapper;
+ @Autowired
+ private CompetitionMapper competitionMapper;
+
+ @Autowired
+ public CompetitionServiceImpl(CompetitionRepository competitionRepository) {
+ this.competitionRepository = competitionRepository;
+ }
+
+ @Override
+ public CompetitionTable addCompetition(CompetitionTable competition) {
+ // 添加竞赛信息,此处可加入额外业务逻辑
+ return competitionRepository.save(competition);
+ }
+
+ @Override
+ public boolean deleteCompetition(Long id) {
+ // 尝试删除竞赛信息,如果竞赛信息不存在,则捕获异常并返回false
+ try {
+ competitionRepository.deleteById(id);
+ return true;
+ } catch (EmptyResultDataAccessException e) {
+ // 如果没有找到要删除的记录,返回false
+ return false;
+ }
+ }
+
+ @Override
+ public CompetitionTable updateCompetition(CompetitionTable competition) {
+ // 更新竞赛信息,此处可加入额外业务逻辑
+ return competitionRepository.save(competition);
+ }
+
+ @Override
+ public Optional getCompetitionById(Long id) {
+ // 根据ID获取竞赛信息
+ return competitionRepository.findById(id);
+ }
+
+ @Override
+ public List getAllCompetitions() {
+ // 获取所有竞赛信息
+ List competitionTables = competitionMapper.getCompetition();
+ for (ResultCompetitionTable competitionTable : competitionTables) {
+ String userName = userMapper.getNameById(competitionTable.getUserId());
+ competitionTable.setUserName(userName);
+ }
+ return competitionTables;
+ }
+
+ @Override
+ public List searchCompetitionsByName(String searchTerm) {
+ return competitionRepository.findByCompetitionNameContaining(searchTerm);
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/impl/InformationServiceImpl.java b/System/src/main/java/com/example/system/service/impl/InformationServiceImpl.java
new file mode 100644
index 0000000..9929aae
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/impl/InformationServiceImpl.java
@@ -0,0 +1,115 @@
+package com.example.system.service.impl;
+
+import com.example.system.mapper.CompetitionMapper;
+import com.example.system.mapper.InformationMapper;
+import com.example.system.mapper.UserMapper;
+import com.example.system.model.InformationTable;
+import com.example.system.model.ResultInformationTable;
+import com.example.system.model.UserTable;
+import com.example.system.repository.InformationRepository;
+import com.example.system.service.InformationService;
+import org.apache.ibatis.javassist.NotFoundException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class InformationServiceImpl implements InformationService {
+
+ @Autowired
+ private InformationRepository informationRepository;
+ private UserMapper userMapper;
+ @Autowired
+ private CompetitionMapper competitionMapper;
+ @Autowired
+ private InformationMapper informationMapper;
+ @Autowired
+ public InformationServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ @Override
+ public List getUserInformation(Long userId) {
+ return informationRepository.findByUserId(userId);
+ }
+
+ @Override
+ public InformationTable createInformation(Long userId, Long competitionId, InformationTable information) {
+ information.setUserId(userId);
+ information.setCompetitionId(competitionId);
+ return informationRepository.save(information);
+ }
+
+ @Override
+ public InformationTable updateInformation(Long informationId, InformationTable information) throws NotFoundException {
+ Optional existingInformationOptional = informationRepository.findById(informationId);
+ if (existingInformationOptional.isPresent()) {
+ InformationTable existingInformation = existingInformationOptional.get();
+ existingInformation.setPersonalInfo(information.getPersonalInfo());
+ existingInformation.setRelatedData(information.getRelatedData());
+ return informationRepository.save(existingInformation);
+ } else {
+ throw new NotFoundException("InformationTable with id " + informationId + " not found");
+ }
+ }
+
+ @Override
+ public void deleteInformation(Long informationId) {
+ informationRepository.deleteById(informationId);
+ }
+
+ //获取所有资料
+ @Override
+ public List getAll() {
+ List informationTables = informationRepository.findAll();
+ List ret = new ArrayList<>();
+ for (InformationTable table : informationTables) {
+ ResultInformationTable tmp = new ResultInformationTable();
+ tmp.setProfileId(table.getProfileId());
+ tmp.setCompetitionId(table.getCompetitionId());
+ tmp.setCompetitionName(competitionMapper.getNameById(tmp.getCompetitionId()));
+ tmp.setRelatedData(table.getRelatedData());
+ tmp.setPersonalInfo(table.getPersonalInfo());
+ tmp.setUserId(table.getUserId());
+ UserTable user = userMapper.findUserById(tmp.getUserId());
+ tmp.setUserName(user == null ? null : user.getUserName());
+ ret.add(tmp);
+ }
+ return ret;
+ }
+
+ //获取指定项目的所有资料
+ @Override
+ public List getPortion(Long competitionId) {
+ List tables = informationMapper.getPortion(competitionId);
+ for (ResultInformationTable tmp : tables) {
+ tmp.setProfileId(tmp.getProfileId());
+ tmp.setCompetitionId(tmp.getCompetitionId());
+ tmp.setCompetitionName(competitionMapper.getNameById(tmp.getCompetitionId()));
+ tmp.setRelatedData(tmp.getRelatedData());
+ tmp.setPersonalInfo(tmp.getPersonalInfo());
+ tmp.setUserId(tmp.getUserId());
+ tmp.setUserName((userMapper.findUserById(tmp.getUserId())).getUserName());
+ }
+ return tables;
+ }
+
+ //获取自己的资料
+ @Override
+ public List getSelf(Long userId) {
+ List tables = informationMapper.getSelf(userId);
+ for (ResultInformationTable tmp : tables) {
+ tmp.setProfileId(tmp.getProfileId());
+ tmp.setCompetitionId(tmp.getCompetitionId());
+ tmp.setCompetitionName(competitionMapper.getNameById(tmp.getCompetitionId()));
+ tmp.setRelatedData(tmp.getRelatedData());
+ tmp.setPersonalInfo(tmp.getPersonalInfo());
+ tmp.setUserId(tmp.getUserId());
+ tmp.setUserName((userMapper.findUserById(tmp.getUserId())).getUserName());
+ }
+ return tables;
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/impl/RegistrationServiceImpl.java b/System/src/main/java/com/example/system/service/impl/RegistrationServiceImpl.java
new file mode 100644
index 0000000..3e35375
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/impl/RegistrationServiceImpl.java
@@ -0,0 +1,96 @@
+package com.example.system.service.impl;
+
+import com.example.system.mapper.CompetitionMapper;
+import com.example.system.mapper.RegistrationMapper;
+import com.example.system.mapper.UserMapper;
+import com.example.system.model.RegistrationTable;
+import com.example.system.service.RegistrationService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class RegistrationServiceImpl implements RegistrationService {
+
+ @Autowired
+ private RegistrationMapper registrationMapper;
+ @Autowired
+ private UserMapper userMapper;
+ @Autowired
+ private CompetitionMapper competitionMapper;
+
+ //根据id修改报名状态
+ @Override
+ public Boolean updateStatus(Long registrationId, String status) {
+ return 1 == registrationMapper.updateStatus(registrationId, status);
+ }
+
+ //学生报名比赛
+ @Override
+ @Transactional
+ public Boolean enroll(RegistrationTable registration) {
+ return registrationMapper.creatData(registration) == 1;
+ }
+ @Override
+ //获取所有的报名信息
+ public Object getAll() {
+ List registrationTables = registrationMapper.getRegistration();
+ for (RegistrationTable registrationTable: registrationTables) {
+ String studentName = userMapper.getNameById(registrationTable.getStudentId());
+ registrationTable.setStudentName(studentName);
+ String competitionName = competitionMapper.getNameById(registrationTable.getCompetitionId());
+ registrationTable.setCompetitionName(competitionName);
+ String teamLeaderName = userMapper.getNameById(registrationTable.getTeamLeaderId());
+ registrationTable.setTeamLeaderName(teamLeaderName);
+ }
+ return registrationTables;
+ }
+
+ //教师修改获奖等级和证书路径和附加信息
+ @Override
+ @Transactional
+ public Object update(RegistrationTable table) {
+ return 1 == registrationMapper.update(table);
+ }
+
+ //获取获奖人员的参赛记录
+ @Override
+ public Object getWinInfo() {
+ List list = registrationMapper.getWinInfo();
+ for (RegistrationTable table : list) {
+ table.setStudentName(userMapper.getNameById(table.getStudentId()));
+ table.setCompetitionName(competitionMapper.getNameById(table.getCompetitionId()));
+ table.setTeamLeaderName(userMapper.getNameById(table.getTeamLeaderId()));
+ log.info(":{}",table);
+ }
+ return list;
+ }
+
+ //获取参赛总人数
+ @Override
+ public Object getCount() {
+ return registrationMapper.getCount();
+ }
+
+ //获取成功报名并获奖的总人数
+ @Override
+ public Object getWinCount() {
+ return registrationMapper.getWinCount();
+ }
+
+ //根据参赛类型获取参赛人数
+ @Override
+ public Object getCountByCompetitionType(String competitionType) {
+ return registrationMapper.getCountByCompetitionType(competitionType);
+ }
+
+ //根据获奖等级获取参赛人数
+ @Override
+ public Object getCountByLevel(String level) {
+ return registrationMapper.getCountByLevel(level);
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/service/impl/UserServiceImpl.java b/System/src/main/java/com/example/system/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..0db3d2b
--- /dev/null
+++ b/System/src/main/java/com/example/system/service/impl/UserServiceImpl.java
@@ -0,0 +1,175 @@
+package com.example.system.service.impl;
+
+import com.example.system.mapper.UserMapper;
+import com.example.system.model.RegistrationTable;
+import com.example.system.model.UserTable;
+import com.example.system.repository.UserRepository;
+import com.example.system.service.UserService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class UserServiceImpl implements UserService {
+ private final UserMapper userMapper;
+ private final BCryptPasswordEncoder passwordEncoder;
+
+ //管理员更新用户信息
+ @Transactional
+ @Override
+ public boolean updateOther(UserTable user) {
+ int tmp = userMapper.updateOther(user);
+ if (tmp == 1) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ //获取用户总数量
+ @Override
+ public Object getCount() {
+ return userMapper.getCount();
+ }
+
+ //获取老师总数量
+ @Override
+ public Object getTeacherCount() {
+ return userMapper.getTeacherCount();
+ }
+
+ //获取学生总数量
+ @Override
+ public Object getStudentCount() {
+ return userMapper.getStudentCount();
+ }
+
+ @Autowired
+ public UserServiceImpl(UserMapper userMapper, BCryptPasswordEncoder passwordEncoder) {
+ this.userMapper = userMapper;
+ this.passwordEncoder = passwordEncoder;
+ }
+ @Autowired
+ private UserRepository userRepository; // 假设这是你的JPA仓库
+
+
+
+ @Transactional(rollbackFor = Exception.class) // 添加事务管理,遇到异常时回滚
+ public boolean createUser(UserTable user) {
+ try {
+ if (userMapper.findBySTId(user.getSTId()) != null) {
+ return 0 != userMapper.updateUserStatus(user.getSTId());
+ }
+ userMapper.createUser(user);
+ return true;
+ } catch (Exception e) {
+ // 异常处理,记录日志等
+ System.out.println(e);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean createRegistration(RegistrationTable registration) {
+ return false;
+ }
+
+ @Override
+ public boolean updateUser(UserTable user) {
+ return 1 == userMapper.updateUser(user);
+ }
+
+ @Override
+ public UserTable validateUserLogin(String userName, String password) {
+ UserTable user = findUserByUserName(userName);
+ if (user != null && passwordEncoder.matches(password, user.getUserPassword())) {
+ return user;
+ }
+ return null;
+ }
+
+ @Override
+ public UserTable findUserByUserName(String userName) {
+ return userMapper.findUserByUserName(userName);
+ }
+
+ @Override
+ public UserTable getUserInfo(String studentId) {
+ return null;
+ }
+
+ @Override
+ public boolean updateStudentInfo(UserTable student) {
+ return false;
+ }
+
+ @Override
+ public UserTable findBySTId(String sTId) {
+ return userMapper.findBySTId(sTId);
+ }
+
+ @Override
+ public boolean checkPassword(String rawPassword, String storedPassword) {
+ // 直接比较原始密码和数据库中存储的密码是否相同
+ return rawPassword.equals(storedPassword);
+ }
+
+ @Override
+ public UserTable findUserById(Long userId) {
+ return userMapper.findUserById(userId);
+ }
+
+ @Override
+ public List findAllUsers() {
+ return userMapper.findAllUsers();
+ }
+
+
+ @Override
+ public int getUserPrivileges(String username) {
+ UserTable user = findUserByUserName(username);
+ if (user != null) {
+ return user.getUserPrivileges();
+ }
+ return -1; // Or other error code or handling mechanism
+ }
+
+ @Override
+ public String getPhoneNumberByUserId(Integer userId) {
+ return null;
+ }
+
+ @Override
+ public List getUserIdsByCompetitionId(Integer competitionId) {
+ return null;
+ }
+
+ // Assuming implementation for createRegistration and other methods if needed
+
+ @Override
+ @Transactional
+ public void importUsers(List users) {
+ userRepository.saveAll(users);
+ }
+
+ @Override
+ //批量删除用户
+ @Transactional
+ public Boolean deleteList(List list) {
+ int size = list.size();
+ if (size == userMapper.deleteList(list)) {
+ return true;
+ }
+ else{
+ log.info("删除数量于前端传入数量不同");
+ throw new NullPointerException();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/com/example/system/utils/DateUtil.java b/System/src/main/java/com/example/system/utils/DateUtil.java
new file mode 100644
index 0000000..4eef5fc
--- /dev/null
+++ b/System/src/main/java/com/example/system/utils/DateUtil.java
@@ -0,0 +1,11 @@
+package com.example.system.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateUtil {
+ public static String getDate(Date date) {
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return simpleDateFormat.format(date);
+ }
+}
diff --git a/System/src/main/java/com/example/system/utils/JWTUtil.java b/System/src/main/java/com/example/system/utils/JWTUtil.java
new file mode 100644
index 0000000..c20646b
--- /dev/null
+++ b/System/src/main/java/com/example/system/utils/JWTUtil.java
@@ -0,0 +1,44 @@
+package com.example.system.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.io.Decoders;
+import io.jsonwebtoken.security.Keys;
+import lombok.extern.slf4j.Slf4j;
+
+import java.security.Key;
+import java.util.Date;
+import java.util.Map;
+
+@Slf4j
+public class JWTUtil {
+ private static final long DURING_TIME = 1000*60*60*24;
+ private static final String STR = "7pphFphDj5GK12AE9R7/y723Cx7hujdhDy/eDV7MLM4=";
+ private static final Key KEY = Keys.hmacShaKeyFor(Decoders.BASE64.decode(STR));
+
+ public static String getToken(Map map) {
+ String token = Jwts.builder()
+ .addClaims(map)
+ .setExpiration(new Date(System.currentTimeMillis() + DURING_TIME))
+ .signWith(KEY)
+ .compact();
+ return token;
+ }
+
+ public static Claims checkToken(String token) {
+ Claims body = null;
+ try{
+ body = Jwts.parserBuilder()
+ .setSigningKey(KEY)
+ .build()
+ .parseClaimsJws(token)
+ .getBody();
+ }catch (ExpiredJwtException e) {
+ log.warn("token 令牌过期 :{}", e.getMessage());
+ }catch (Exception e) {
+ log.warn("token 令牌解析异常 :{}", e.getMessage());
+ }
+ return body;
+ }
+}
diff --git a/System/src/main/java/com/example/system/utils/MD5Util.java b/System/src/main/java/com/example/system/utils/MD5Util.java
new file mode 100644
index 0000000..e92aeb5
--- /dev/null
+++ b/System/src/main/java/com/example/system/utils/MD5Util.java
@@ -0,0 +1,45 @@
+package com.example.system.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.DigestUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.UUID;
+
+@Slf4j
+public class MD5Util {
+ /**
+ * 对密码使用MD5进行加密
+ * @param password
+ * @return
+ */
+ public static String puzzle(String password) {
+ String uuid = UUID.randomUUID().toString().replace("-", "");
+ String md5 = DigestUtils.md5DigestAsHex((password+uuid).getBytes(StandardCharsets.UTF_8));
+ return (md5 + uuid);
+ }
+
+ /**
+ * 使用MD5校验密码和密文是否相同
+ * @param password
+ * @param puzzleMd5
+ * @return
+ */
+ public static boolean verify(String password, String puzzleMd5) {
+ if (puzzleMd5.length() != 64) {
+ log.error("数据库密文存储有误:{}", puzzleMd5);
+ return false;
+ }
+ String uuid = puzzleMd5.substring(32, 64);
+ String md5 = puzzleMd5.substring(0, 32);
+ String tmp = DigestUtils.md5DigestAsHex((password+uuid).getBytes(StandardCharsets.UTF_8));
+ if (md5.equals(tmp)) {
+ log.info("密码正确");
+ return true;
+ }
+ else {
+ log.info("密码错误");
+ return false;
+ }
+ }
+}
diff --git a/System/src/main/java/com/example/system/utils/OssUtils.java b/System/src/main/java/com/example/system/utils/OssUtils.java
new file mode 100644
index 0000000..e8057c2
--- /dev/null
+++ b/System/src/main/java/com/example/system/utils/OssUtils.java
@@ -0,0 +1,108 @@
+package com.example.system.utils;
+
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.multipart.MultipartFile;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import org.joda.time.DateTime;
+import java.util.List;
+import java.util.ArrayList; // 添加缺失的导入语句
+import java.util.UUID;
+
+@Component
+public class OssUtils {
+
+ @Value("${aliyun.accessKeyId}")
+ private String accessKeyId;
+
+ @Value("${aliyun.secretAccessKey}")
+ private String secretAccessKey;
+
+ @Value("${aliyun.oss.endPoint}")
+ private String endPoint;
+
+ @Value("${aliyun.oss.bucketName}")
+ private String bucketName;
+
+ public String uploadOneFile(MultipartFile file) {
+
+ // 创建OSSClient实例。
+ OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey);
+ //设置文件名
+ String fileName = new DateTime().toString("yyyy/MM/dd")
+ + UUID.randomUUID().toString().replace("-", "")
+ + file.getOriginalFilename();
+
+ try {
+ // 创建PutObject请求。
+ ossClient.putObject(bucketName, fileName, file.getInputStream());
+
+ String url = "http://" + bucketName + "." + endPoint + "/" + fileName;
+ return url;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+ }
+
+ public List uploadArrayFile(MultipartFile[] files) {
+ // 创建OSSClient实例。
+ OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey);
+ List list = new ArrayList<>();
+
+ try {
+ //设置文件名
+ for (MultipartFile file : files) {
+ String fileName = new DateTime().toString("yyyy/MM/dd")
+ + UUID.randomUUID().toString().replace("-", "")
+ + file.getOriginalFilename();
+ // 创建PutObject请求。
+ ossClient.putObject(bucketName, fileName, file.getInputStream());
+
+ String url = "http://" + bucketName + "." + endPoint + "/" + fileName;
+ list.add(url);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+ return list;
+
+ }
+
+ public boolean deleteFile(String fileUrl) {
+
+ // 创建OSSClient实例。
+ OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey);
+ /** oss删除文件是根据文件完成路径删除的,但文件完整路径中不能包含Bucket名称。
+ * 比如文件路径为:http://edu-czf.oss-cn-guangzhou.aliyuncs.com/2022/08/abc.jpg",
+ * 则完整路径就是:2022/08/abc.jpg
+ */
+ int begin = ("http://" + bucketName + "." + endPoint + "/").length(); //找到文件路径的开始下标
+ String deleteUrl = fileUrl.substring(begin);
+
+ try {
+ // 删除文件请求
+ ossClient.deleteObject(bucketName, deleteUrl);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+ }
+
+}
diff --git a/System/src/main/java/com/example/system/utils/SecurityConfig.java b/System/src/main/java/com/example/system/utils/SecurityConfig.java
new file mode 100644
index 0000000..0c70133
--- /dev/null
+++ b/System/src/main/java/com/example/system/utils/SecurityConfig.java
@@ -0,0 +1,14 @@
+package com.example.system.utils;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+@Configuration
+public class SecurityConfig {
+
+ @Bean
+ public BCryptPasswordEncoder bCryptPasswordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+}
\ No newline at end of file
diff --git a/System/src/main/java/openGauss-5.0.1-JDBC.tar.gz b/System/src/main/java/openGauss-5.0.1-JDBC.tar.gz
new file mode 100644
index 0000000..7670f14
Binary files /dev/null and b/System/src/main/java/openGauss-5.0.1-JDBC.tar.gz differ
diff --git a/System/src/main/resources/application.yml b/System/src/main/resources/application.yml
new file mode 100644
index 0000000..a920ad1
--- /dev/null
+++ b/System/src/main/resources/application.yml
@@ -0,0 +1,51 @@
+spring:
+# datasource:
+# url: jdbc:postgresql://10.10.206.79:7000/sjk?ssl=false
+# username: shiwang
+# password: Gongchengshi@123
+# driver-class-name: org.postgresql.Driver
+# hikari:
+# connection-timeout: 10000 # 设置连接超时时间为10秒
+# maximum-pool-size: 200 # 根据实际情况调整
+# minimum-idle: 5 # 设置最小空闲连接数
+# idle-timeout: 30000 # 设置连接空闲超时时间为30秒
+ datasource:
+ url: jdbc:mysql://222.186.56.185:3306/jingsaisystem?useSSL=false&serverTimezone=UTC
+ username: jingsaisystem
+ password: Aa123456...
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ hikari:
+ connection-timeout: 10000 # 设置连接超时时间为10秒
+ maximum-pool-size: 200 # 根据实际情况调整
+ minimum-idle: 5 # 设置最小空闲连接数
+ idle-timeout: 30000 # 设置连接空闲超时时间为30秒
+ servlet:
+ multipart:
+ max-file-size: 500MB
+ max-request-size: 500MB
+mybatis:
+ configuration:
+ map-underscore-to-camel-case: true #设置数据库驼峰自动转换
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql代码
+ mapper-locations: classpath:mapper/**Mapper.xml #配置mapper路径
+logging:
+ file:
+ name: spring-blog.log #存储日志
+server:
+ port: 8887
+
+#操作oss需要的一些参数
+aliyun:
+ accessKeyId: LTAI4G4gC7aGdcskaUE36y94 # 阿里云的accessKeyId
+ secretAccessKey: HxWodbFxKjjb1mp3HTt8Pc9eDFkjRm # accessKey 密码
+ oss:
+ endPoint: oss-cn-beijing.aliyuncs.com # Endpoint:在阿里云oss控制台查看自己使用的endpoint
+ bucketName: cloudreveplus # bucket 名称
+# 短信配置
+smsbao:
+ username: 15829561090
+ password: 13991564254
+mail:
+ user: shuguang@email.92wap.cn
+ password: LIUSHUguang520
+
diff --git a/System/src/main/resources/mapper/ArticleMapper.xml b/System/src/main/resources/mapper/ArticleMapper.xml
new file mode 100644
index 0000000..1dedbde
--- /dev/null
+++ b/System/src/main/resources/mapper/ArticleMapper.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ insert into article_table
+ (user_id, article_title, brief_content,
+ article_content, article_type, competition_id, publish_time)
+ values
+ (#{userId}, #{articleTitle}, #{briefContent},
+ #{articleContent}, #{articleType}, #{competitionId}, #{publishTime});
+
+
+
\ No newline at end of file
diff --git a/System/src/test/java/com/example/system/SystemApplicationTests.java b/System/src/test/java/com/example/system/SystemApplicationTests.java
new file mode 100644
index 0000000..f1321d3
--- /dev/null
+++ b/System/src/test/java/com/example/system/SystemApplicationTests.java
@@ -0,0 +1,19 @@
+//package com.example.system;
+//
+//import org.junit.jupiter.api.Test;
+//import org.springframework.boot.test.context.SpringBootTest;
+//import org.springframework.util.DigestUtils;
+//
+//import java.nio.charset.StandardCharsets;
+//import java.util.UUID;
+//
+//@SpringBootTest
+//class SystemApplicationTests {
+// @Test
+// public void getMD5() {
+// String password = "1234";
+// String uuid = UUID.randomUUID().toString().replace("-", "");
+// String md5 = DigestUtils.md5DigestAsHex((uuid+password).getBytes(StandardCharsets.UTF_8));
+// System.out.println((md5 + uuid));
+// }
+//}
diff --git a/spring-blog.log b/spring-blog.log
new file mode 100644
index 0000000..c3b7158
--- /dev/null
+++ b/spring-blog.log
@@ -0,0 +1,5 @@
+2024-06-23 19:28:43.485 WARN 12068 --- [HikariPool-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=22h14m15s564ms927µs100ns).
+2024-06-23 19:30:01.637 WARN 12068 --- [HikariPool-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1m32s933ms399µs100ns).
+2024-06-23 19:51:59.923 INFO 12068 --- [SpringApplicationShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2024-06-23 19:51:59.948 INFO 12068 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
+2024-06-23 19:51:59.957 INFO 12068 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
diff --git a/spring-blog.log.2024-06-20.0.gz b/spring-blog.log.2024-06-20.0.gz
new file mode 100644
index 0000000..500f17e
Binary files /dev/null and b/spring-blog.log.2024-06-20.0.gz differ
diff --git a/spring-blog.log.2024-06-21.0.gz b/spring-blog.log.2024-06-21.0.gz
new file mode 100644
index 0000000..ac088e5
Binary files /dev/null and b/spring-blog.log.2024-06-21.0.gz differ
diff --git a/spring-blog.log.2024-06-22.0.gz b/spring-blog.log.2024-06-22.0.gz
new file mode 100644
index 0000000..b479de7
Binary files /dev/null and b/spring-blog.log.2024-06-22.0.gz differ