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