feat-0330: INIT PROJECT

This commit is contained in:
曙光 2025-02-27 21:35:01 +08:00
commit eac3915a11
102 changed files with 4877 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

9
.idea/System(7).iml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

19
.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="System" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="System" options="-parameters" />
</option>
</component>
</project>

18
.idea/dataSources.xml generated Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="jingsaisystem@127.0.0.1" uuid="2f980dca-9d52-49f3-bdc2-b94441a356c7">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<imported>true</imported>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://127.0.0.1:3309/jingsaisystem?useSSL=false&amp;serverTimezone=UTC</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

6
.idea/encodings.xml generated Normal file
View File

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

20
.idea/jarRepositories.xml generated Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

15
.idea/misc.xml generated Normal file
View File

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

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/System(7).iml" filepath="$PROJECT_DIR$/.idea/System(7).iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

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

33
System/.gitignore vendored Normal file
View File

@ -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/

219
System/pom.xml Normal file
View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>System</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>System</name>
<description>System</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.67</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okio/okio -->
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- druid 连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!-- hutool依赖-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.4</version> <!-- 或者你选择的其他版本 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!--JWT-->
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.15.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--阿里云oss依赖-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- <configuration>-->
<!-- <excludes>-->
<!-- <exclude>-->
<!-- <groupId>org.projectlombok</groupId>-->
<!-- <artifactId>lombok</artifactId>-->
<!-- </exclude>-->
<!-- </excludes>-->
<!-- </configuration>-->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

152
System/sjk.sql Normal file
View File

@ -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');

208
System/spring-blog.log Normal file
View File

@ -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 2055 (2)\竞赛管理系统spring boot-2024.4.23 2055\竞赛管理系统spring boot-2024.4.23 2055\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

Binary file not shown.

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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("服务端发生异常");
}
}

View File

@ -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 路径
// }
//
//}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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<RoleContent> 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<Text> 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> 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;
}
}
}

View File

@ -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");
}
}

View File

@ -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<String, WebSocketClient> webSocketMap = new ConcurrentHashMap<>();
public ConcurrentHashMap<String, WebSocketClient> 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--;
}
}

View File

@ -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();
}
}

View File

@ -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<Friend> 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);
}
}

View File

@ -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);
}
}

View File

@ -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<SessionMassage> 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<Integer> 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;
}
}

View File

@ -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());
}
}

View File

@ -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<UserTable> 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<String> list = handshakeHeaders.get("sec-websocket-protocol");
String userToken =list.get(0);
Claims claims = JWTUtil.checkToken(userToken);
return (String) claims.get("userName");
}
}

View File

@ -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<Friend> 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);
}

View File

@ -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<Message> getHistoryMessage(Integer sessionId, Integer start);
//发送消息
@Insert("INSERT INTO message VALUE (NULL, #{sessionId}, #{userId}, #{content}, NOW());")
Integer sendMessage(Integer userId, Integer sessionId, String content);
}

View File

@ -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<Integer> 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<UserTable> 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);
}

View File

@ -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<Integer, WebSocketSession> 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);
}
}

View File

@ -0,0 +1,10 @@
package com.example.system.chat.model;
import lombok.Data;
//好友
@Data
public class Friend {
private Integer friendId;
private String friendName;
}

View File

@ -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;
}

View File

@ -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<UserTable> friend;
private String lastMessage;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<Friend> getFriendList(Integer userId) {
List<Friend> 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);
}
}

View File

@ -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<Message> list = new ArrayList<>();
list = messageMapper.getHistoryMessage(sessionId, start);
Iterable<Message> iterable = new ArrayList<>(list);
for (Message message : iterable) {
message.setUserName(userMapper.getNameById(message.getUserId()));
}
return list;
}
}

View File

@ -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<SessionMassage> getMessageSession(Integer userId) {
//获取所有和当前用户有关的会话id
List<Integer> sessionIds = sessionMassageMapper.getSessionIdByUserId(userId);
//获取这些会话中的好友信息排除自己
List<SessionMassage> 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<Integer> friendIds) {
//创建会话
SessionMassage sessionMassage = new SessionMassage();
sessionMassageMapper.insertSession(sessionMassage);
//创建会话和用户的关系
for (Integer friendId: friendIds) {
sessionMassageMapper.insertUserFriend(friendId, sessionMassage.getSessionId());
}
return sessionMassage;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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("更新失败");
}
}

View File

@ -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<CommentTable> 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);
}
}

View File

@ -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<CompetitionTable> 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<CompetitionTable> competitions = competitionService.searchCompetitionsByName(searchTerm);
if (competitions.isEmpty()) {
return Result.fail("未找到匹配的竞赛信息");
}
return competitions;
}
/**
* 获取所有竞赛信息的列表
*
* @return 竞赛信息列表
*/
@GetMapping("/list")
public Object listCompetitions() {
return competitionService.getAllCompetitions();
}
}

View File

@ -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<String> sendemail(@RequestParam Long competitionId, @RequestParam Integer articleId) {
Optional<ArticleTable> articleOpt = articleRepository.findById(articleId);
if (articleOpt.isEmpty()) {
return new ResponseEntity<>("未找到公告", HttpStatus.NOT_FOUND);
}
ArticleTable article = articleOpt.get();
List<String> 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;
}
}

View File

@ -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<List<InformationTable>> getUserInformation(@PathVariable("userId") Long userId) {
List<InformationTable> informationList = informationService.getUserInformation(userId);
return new ResponseEntity<>(informationList, HttpStatus.OK);
}
// 创建新的文档资料
@PostMapping("/user/{userId}/competition/{competitionId}")
public ResponseEntity<InformationTable> 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<InformationTable> 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<Void> deleteInformation(@PathVariable("informationId") Long informationId) {
informationService.deleteInformation(informationId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
// 获取所有资料
@RequestMapping("/getAll")
public List<ResultInformationTable> getAll() {
return informationService.getAll();
}
//获取比赛相关的资料
@RequestMapping("/getPortion")
public List<ResultInformationTable> getPortion(Long competitionId) {
return informationService.getPortion(competitionId);
}
//获取自己的资料
@RequestMapping("/getSelf")
public List<ResultInformationTable> 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);
}
}

View File

@ -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);
// 存储URLuserIdcompetitionId和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<String> uploadArrayFile(@RequestBody UploadArrayRequest uploadArrayRequest) {
// 上传多个文件到oss并获取URL列表
List<String> urls = ossUtils.uploadArrayFile(uploadArrayRequest.getFiles());
// 存储URLuserIdcompetitionId和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;
}
}
}

View File

@ -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<String> sendArticleBriefToParticipants(@RequestParam Long competitionId, @RequestParam Integer articleId) {
// // 根据文章ID查找文章
Optional<ArticleTable> articleOpt = articleRepository.findById(articleId);
if (articleOpt.isEmpty()) {
return new ResponseEntity<>("未找到公告", HttpStatus.NOT_FOUND);
}
ArticleTable article = articleOpt.get();
// 根据竞赛ID查找参赛者
List<String> 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;
}
}

View File

@ -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);
}
}

View File

@ -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<Integer> 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<String, String> 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<String, Object> 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<UserTable> userList = userService.findAllUsers();
// if (claims != null && ((Integer) claims.get("userPrivileges")) == 2) {
// // 权限不足
// return Result.fail("权限不足");
// }
return userList;
}
// 用户导入接口
@PostMapping("/user/import")
public ResponseEntity<String> importUsers(@RequestBody List<UserTable> 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("用户导入失败");
}
}
}

View File

@ -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
}

View File

@ -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<ArticleTable> 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);
}

View File

@ -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<CommentTable> 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);
}

View File

@ -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<ResultCompetitionTable> getCompetition();
@Select("select competition_name from competition_table where competition_id=#{competitionId}")
String getNameById(Long competitionId);
}

View File

@ -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<ResultInformationTable> getPortion(Long competitionId);
//获取自己的所有资料
@Select("select * from information_table where user_id=#{userId};")
List<ResultInformationTable> getSelf(Long userId);
}

View File

@ -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<RegistrationTable> 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<RegistrationTable> 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);
}

View File

@ -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<UserTable> findAllUsers();
//批量删除用户
@Update("<script>"+"update user_table set user_status=1 where user_id in" +
"<foreach collection='list' item='userId' open='(' close=');' separator=','>" +
"#{userId}" +
"</foreach>"+
"</script>")
Integer deleteList(List<Integer> 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();
}

View File

@ -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;
}

View File

@ -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字段
}

View File

@ -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注解用于自动生成gettersettertoStringequalshashCode方法
@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字段
}

View File

@ -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方法以及toStringequalshashCode方法
@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
}

View File

@ -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;
}
}

View File

@ -0,0 +1,25 @@
package com.example.system.model;
import lombok.Data;
import javax.persistence.*;
/**
* 专业实体类对应数据库中的major_table表
*/
@Data // Lombok库的注解自动为类的字段生成gettersetter方法以及toStringequalshashCode方法
@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外键
}

View File

@ -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注解自动生成gettersettertoStringequalshashCode方法
@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字段
}

View File

@ -0,0 +1,49 @@
package com.example.system.model;
import com.example.system.constant.ResultCode;
import lombok.Data;
@Data
public class Result<T>{
private ResultCode code;//状态码
private String errorInfo;//异常信息
T data;//成功信息
public Integer getCode() {
return code.getCode();
}
/**
* 后端响应成功
* @param data
* @return
* @param <T>
*/
public static <T> Result<T> success(T data) {
Result<T> ret = new Result<>();
ret.code = ResultCode.SUCCESS;
ret.data = data;
return ret;
}
/**
* 后端响应失败
* @param error
* @return
*/
public static Result<String> fail(String error) {
Result<String> ret = new Result<>();
ret.code = ResultCode.FAIL;
ret.data = error;
return ret;
}
/**
* 用户未登录
* @return
*/
public static Result<String> notLogin() {
Result<String> ret = new Result<>();
ret.code = ResultCode.NOT_LOGIN;
ret.errorInfo = "请登录";
return ret;
}
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<ArticleTable, Integer> {
// 这里可以根据需要添加自定义的查询方法例如
// 根据文章类型查找文章
List<ArticleTable> findByArticleType(String articleType);
// 根据用户ID查找文章
List<ArticleTable> findByUserId(Integer userId);
// 根据竞赛ID查找文章
List<ArticleTable> findByCompetitionId(Integer competitionId);
}

View File

@ -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<CommentTable, Long> {
// 这里可以根据需要添加自定义的查询方法
}

View File

@ -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<CompetitionTable, Long> {
// 仅根据competitionName进行模糊搜索
List<CompetitionTable> findByCompetitionNameContaining(String competitionName);
}

View File

@ -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<InformationTable, Long> {
List<InformationTable> findByUserId(Long userId);
@Query("SELECT i FROM InformationTable i WHERE i.personalInfo = :personalInfo")
InformationTable findByPersonalInfo(String personalInfo);
}

View File

@ -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<RegistrationTable, Long> {
@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<String> 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<String> findompetitionemailId(Long competitionId);
}

View File

@ -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<UserTable, Long> {
// 这里可以定义一些根据业务需求的方法例如按名字查找用户等
// 示例List<UserTable> findByName(String name);
}

View File

@ -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<ArticleTable> getHistoryArticle();
// 创建文章并在创建成功时发送短信通知
@Transactional
Integer createArticle(ArticleTable article);
// 根据文章ID获取文章
ArticleTable getArticleById(Integer id);
// 根据文章ID来删除对应的文章
Boolean deleteArticleById(Integer id);
// 修改文章
Boolean updateArticle(ArticleTable articleTable);
// 通知所有参与指定竞赛的用户发送短信
void notifyParticipants(Integer competitionId);
}

View File

@ -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<CommentTable> getCommentById(Integer id);
//根据评论id获取对应的评论
CommentTable getById(Long id);
//根据评论id删除评论
Boolean deleteById(Long id);
}

View File

@ -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<CompetitionTable> getCompetitionById(Long id);
// 获取所有竞赛信息的列表
List<ResultCompetitionTable> getAllCompetitions();
// 根据搜索词条搜索竞赛信息
List<CompetitionTable> searchCompetitionsByName(String searchTerm);
}

View File

@ -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<InformationTable> getUserInformation(Long userId);
InformationTable createInformation(Long userId, Long competitionId, InformationTable information);
InformationTable updateInformation(Long informationId, InformationTable information) throws NotFoundException;
void deleteInformation(Long informationId);
//获取所有资料
List<ResultInformationTable> getAll();
//获取指定项目的所有资料
List<ResultInformationTable> getPortion(Long competitionId);
//获取自己的资料
List<ResultInformationTable> getSelf(Long userId);
}

View File

@ -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);
}

View File

@ -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<UserTable> 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<Integer> getUserIdsByCompetitionId(Integer competitionId);
void importUsers(List<UserTable> users);
//批量删除用户
Boolean deleteList(List<Integer> list);
//管理员更新用户信息
boolean updateOther(UserTable user);
//获取用户总数量
Object getCount();
//获取老师总数量
Object getTeacherCount();
//获取学生总数量
Object getStudentCount();
}

View File

@ -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<ArticleTable> 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) {
}
}

View File

@ -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<CommentTable> 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);
}
}

View File

@ -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<CompetitionTable> getCompetitionById(Long id) {
// 根据ID获取竞赛信息
return competitionRepository.findById(id);
}
@Override
public List<ResultCompetitionTable> getAllCompetitions() {
// 获取所有竞赛信息
List<ResultCompetitionTable> competitionTables = competitionMapper.getCompetition();
for (ResultCompetitionTable competitionTable : competitionTables) {
String userName = userMapper.getNameById(competitionTable.getUserId());
competitionTable.setUserName(userName);
}
return competitionTables;
}
@Override
public List<CompetitionTable> searchCompetitionsByName(String searchTerm) {
return competitionRepository.findByCompetitionNameContaining(searchTerm);
}
}

View File

@ -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<InformationTable> 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<InformationTable> 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<ResultInformationTable> getAll() {
List<InformationTable> informationTables = informationRepository.findAll();
List<ResultInformationTable> 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<ResultInformationTable> getPortion(Long competitionId) {
List<ResultInformationTable> 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<ResultInformationTable> getSelf(Long userId) {
List<ResultInformationTable> 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;
}
}

View File

@ -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<RegistrationTable> 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<RegistrationTable> 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);
}
}

View File

@ -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<UserTable> 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<Integer> getUserIdsByCompetitionId(Integer competitionId) {
return null;
}
// Assuming implementation for createRegistration and other methods if needed
@Override
@Transactional
public void importUsers(List<UserTable> users) {
userRepository.saveAll(users);
}
@Override
//批量删除用户
@Transactional
public Boolean deleteList(List<Integer> list) {
int size = list.size();
if (size == userMapper.deleteList(list)) {
return true;
}
else{
log.info("删除数量于前端传入数量不同");
throw new NullPointerException();
}
}
}

View File

@ -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);
}
}

View File

@ -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<String, Object> 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;
}
}

View File

@ -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;
}
}
}

View File

@ -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<String> uploadArrayFile(MultipartFile[] files) {
// 创建OSSClient实例
OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, secretAccessKey);
List<String> 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();
}
}
}
}

View File

@ -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();
}
}

Binary file not shown.

View File

@ -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

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.system.mapper.ArticleMapper">
<insert id="createArticle" useGeneratedKeys="true" keyProperty="articleId">
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});
</insert>
</mapper>

View File

@ -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));
// }
//}

5
spring-blog.log Normal file
View File

@ -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.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More