学生,成绩,班级,专业,教师,用户管理ok

main
魏灿斌 4 days ago
parent ef2bdacd19
commit 445dd509fd

@ -12,6 +12,13 @@
<option value="$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-redis/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-security/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-ssm-common/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-server/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-common/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-common/yuxingshi-sms-core/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-common/yuxingshi-sms-intercepter/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-common/yuxingshi-sms-mybatisplus/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-common/yuxingshi-sms-redis/pom.xml" />
<option value="$PROJECT_DIR$/yuxingshi-sms-common/yuxingshi-sms-security/pom.xml" />
</list>
</option>
</component>

@ -0,0 +1,2 @@
[auto]
server-uuid=59fe0b25-c5dd-11f0-ad71-0242ac180002

Binary file not shown.

Binary file not shown.

@ -0,0 +1 @@
{"mysqld_version_id":80402,"dd_version":80300,"sdi_version":80019,"dd_object_type":"Table","dd_object":{"name":"cond_instances","mysql_version_id":80402,"created":20251120065135,"last_altered":20251120065135,"hidden":1,"options":"avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;server_p_s_table=1;stats_auto_recalc=0;stats_sample_pages=0;","columns":[{"name":"NAME","type":16,"is_nullable":false,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":1,"char_length":512,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAA==","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":4,"column_type_utf8":"varchar(128)","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"OBJECT_INSTANCE_BEGIN","type":9,"is_nullable":false,"is_zerofill":false,"is_unsigned":true,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":2,"char_length":20,"numeric_precision":20,"numeric_scale":0,"numeric_scale_null":false,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAA=","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":2,"column_type_utf8":"bigint unsigned","elements":[],"collation_id":255,"is_explicit_collation":false}],"schema_ref":"performance_schema","se_private_id":18446744073709551615,"engine":"PERFORMANCE_SCHEMA","last_checked_for_upgrade_version_id":0,"comment":"","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","row_format":2,"partition_type":0,"partition_expression":"","partition_expression_utf8":"","default_partitioning":0,"subpartition_type":0,"subpartition_expression":"","subpartition_expression_utf8":"","default_subpartitioning":0,"indexes":[{"name":"PRIMARY","hidden":false,"is_generated":false,"ordinal_position":1,"comment":"","options":"flags=0;","se_private_data":"","type":1,"algorithm":4,"is_algorithm_explicit":false,"is_visible":true,"engine":"PERFORMANCE_SCHEMA","engine_attribute":"","secondary_engine_attribute":"","elements":[{"ordinal_position":1,"length":8,"order":1,"hidden":false,"column_opx":1}]},{"name":"NAME","hidden":false,"is_generated":false,"ordinal_position":2,"comment":"","options":"flags=0;","se_private_data":"","type":3,"algorithm":4,"is_algorithm_explicit":false,"is_visible":true,"engine":"PERFORMANCE_SCHEMA","engine_attribute":"","secondary_engine_attribute":"","elements":[{"ordinal_position":1,"length":512,"order":1,"hidden":false,"column_opx":0}]}],"foreign_keys":[],"check_constraints":[],"partitions":[],"collation_id":255}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
{"mysqld_version_id":80402,"dd_version":80300,"sdi_version":80019,"dd_object_type":"Table","dd_object":{"name":"session_status","mysql_version_id":80402,"created":20251120065135,"last_altered":20251120065135,"hidden":1,"options":"avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;server_p_s_table=1;stats_auto_recalc=0;stats_sample_pages=0;","columns":[{"name":"VARIABLE_NAME","type":16,"is_nullable":false,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":1,"char_length":256,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":2,"column_type_utf8":"varchar(64)","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"VARIABLE_VALUE","type":16,"is_nullable":true,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":2,"char_length":4096,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":false,"default_value_null":true,"srs_id_null":true,"srs_id":0,"default_value":"","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":1,"column_type_utf8":"varchar(1024)","elements":[],"collation_id":255,"is_explicit_collation":false}],"schema_ref":"performance_schema","se_private_id":18446744073709551615,"engine":"PERFORMANCE_SCHEMA","last_checked_for_upgrade_version_id":0,"comment":"","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","row_format":2,"partition_type":0,"partition_expression":"","partition_expression_utf8":"","default_partitioning":0,"subpartition_type":0,"subpartition_expression":"","subpartition_expression_utf8":"","default_subpartitioning":0,"indexes":[{"name":"PRIMARY","hidden":false,"is_generated":false,"ordinal_position":1,"comment":"","options":"flags=0;","se_private_data":"","type":1,"algorithm":4,"is_algorithm_explicit":false,"is_visible":true,"engine":"PERFORMANCE_SCHEMA","engine_attribute":"","secondary_engine_attribute":"","elements":[{"ordinal_position":1,"length":256,"order":1,"hidden":false,"column_opx":0}]}],"foreign_keys":[],"check_constraints":[],"partitions":[],"collation_id":255}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
{"mysqld_version_id":80402,"dd_version":80300,"sdi_version":80019,"dd_object_type":"Table","dd_object":{"name":"status_by_host","mysql_version_id":80402,"created":20251120065135,"last_altered":20251120065135,"hidden":1,"options":"avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;server_p_s_table=1;stats_auto_recalc=0;stats_sample_pages=0;","columns":[{"name":"HOST","type":29,"is_nullable":true,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":1,"char_length":255,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":false,"default_value_null":true,"srs_id_null":true,"srs_id":0,"default_value":"","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":4,"column_type_utf8":"char(255)","elements":[],"collation_id":11,"is_explicit_collation":true},{"name":"VARIABLE_NAME","type":16,"is_nullable":false,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":2,"char_length":256,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":1,"column_type_utf8":"varchar(64)","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"VARIABLE_VALUE","type":16,"is_nullable":true,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":3,"char_length":4096,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":false,"default_value_null":true,"srs_id_null":true,"srs_id":0,"default_value":"","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":1,"column_type_utf8":"varchar(1024)","elements":[],"collation_id":255,"is_explicit_collation":false}],"schema_ref":"performance_schema","se_private_id":18446744073709551615,"engine":"PERFORMANCE_SCHEMA","last_checked_for_upgrade_version_id":0,"comment":"","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","row_format":2,"partition_type":0,"partition_expression":"","partition_expression_utf8":"","default_partitioning":0,"subpartition_type":0,"subpartition_expression":"","subpartition_expression_utf8":"","default_subpartitioning":0,"indexes":[{"name":"HOST","hidden":false,"is_generated":false,"ordinal_position":1,"comment":"","options":"flags=0;","se_private_data":"","type":2,"algorithm":4,"is_algorithm_explicit":false,"is_visible":true,"engine":"PERFORMANCE_SCHEMA","engine_attribute":"","secondary_engine_attribute":"","elements":[{"ordinal_position":1,"length":255,"order":1,"hidden":false,"column_opx":0},{"ordinal_position":2,"length":256,"order":1,"hidden":false,"column_opx":1}]}],"foreign_keys":[],"check_constraints":[],"partitions":[],"collation_id":255}}

@ -0,0 +1 @@
{"mysqld_version_id":80402,"dd_version":80300,"sdi_version":80019,"dd_object_type":"Table","dd_object":{"name":"status_by_thread","mysql_version_id":80402,"created":20251120065135,"last_altered":20251120065135,"hidden":1,"options":"avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;server_p_s_table=1;stats_auto_recalc=0;stats_sample_pages=0;","columns":[{"name":"THREAD_ID","type":9,"is_nullable":false,"is_zerofill":false,"is_unsigned":true,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":1,"char_length":20,"numeric_precision":20,"numeric_scale":0,"numeric_scale_null":false,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAA=","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":2,"column_type_utf8":"bigint unsigned","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"VARIABLE_NAME","type":16,"is_nullable":false,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":2,"char_length":256,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":2,"column_type_utf8":"varchar(64)","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"VARIABLE_VALUE","type":16,"is_nullable":true,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":3,"char_length":4096,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":false,"default_value_null":true,"srs_id_null":true,"srs_id":0,"default_value":"","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":1,"column_type_utf8":"varchar(1024)","elements":[],"collation_id":255,"is_explicit_collation":false}],"schema_ref":"performance_schema","se_private_id":18446744073709551615,"engine":"PERFORMANCE_SCHEMA","last_checked_for_upgrade_version_id":0,"comment":"","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","row_format":2,"partition_type":0,"partition_expression":"","partition_expression_utf8":"","default_partitioning":0,"subpartition_type":0,"subpartition_expression":"","subpartition_expression_utf8":"","default_subpartitioning":0,"indexes":[{"name":"PRIMARY","hidden":false,"is_generated":false,"ordinal_position":1,"comment":"","options":"flags=0;","se_private_data":"","type":1,"algorithm":4,"is_algorithm_explicit":false,"is_visible":true,"engine":"PERFORMANCE_SCHEMA","engine_attribute":"","secondary_engine_attribute":"","elements":[{"ordinal_position":1,"length":8,"order":1,"hidden":false,"column_opx":0},{"ordinal_position":2,"length":256,"order":1,"hidden":false,"column_opx":1}]}],"foreign_keys":[],"check_constraints":[],"partitions":[],"collation_id":255}}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
{"mysqld_version_id":80402,"dd_version":80300,"sdi_version":80019,"dd_object_type":"Table","dd_object":{"name":"user_variables_by_thread","mysql_version_id":80402,"created":20251120065135,"last_altered":20251120065135,"hidden":1,"options":"avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;server_p_s_table=1;stats_auto_recalc=0;stats_sample_pages=0;","columns":[{"name":"THREAD_ID","type":9,"is_nullable":false,"is_zerofill":false,"is_unsigned":true,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":1,"char_length":20,"numeric_precision":20,"numeric_scale":0,"numeric_scale_null":false,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAA=","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":2,"column_type_utf8":"bigint unsigned","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"VARIABLE_NAME","type":16,"is_nullable":false,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":2,"char_length":256,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":true,"default_value_null":false,"srs_id_null":true,"srs_id":0,"default_value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":2,"column_type_utf8":"varchar(64)","elements":[],"collation_id":255,"is_explicit_collation":false},{"name":"VARIABLE_VALUE","type":26,"is_nullable":true,"is_zerofill":false,"is_unsigned":false,"is_auto_increment":false,"is_virtual":false,"hidden":1,"ordinal_position":3,"char_length":4294967295,"numeric_precision":0,"numeric_scale":0,"numeric_scale_null":true,"datetime_precision":0,"datetime_precision_null":1,"has_no_default":false,"default_value_null":true,"srs_id_null":true,"srs_id":0,"default_value":"","default_value_utf8_null":true,"default_value_utf8":"","default_option":"","update_option":"","comment":"","generation_expression":"","generation_expression_utf8":"","options":"interval_count=0;","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","column_key":1,"column_type_utf8":"longblob","elements":[],"collation_id":63,"is_explicit_collation":true}],"schema_ref":"performance_schema","se_private_id":18446744073709551615,"engine":"PERFORMANCE_SCHEMA","last_checked_for_upgrade_version_id":0,"comment":"","se_private_data":"","engine_attribute":"","secondary_engine_attribute":"","row_format":2,"partition_type":0,"partition_expression":"","partition_expression_utf8":"","default_partitioning":0,"subpartition_type":0,"subpartition_expression":"","subpartition_expression_utf8":"","default_subpartitioning":0,"indexes":[{"name":"PRIMARY","hidden":false,"is_generated":false,"ordinal_position":1,"comment":"","options":"flags=0;","se_private_data":"","type":1,"algorithm":4,"is_algorithm_explicit":false,"is_visible":true,"engine":"PERFORMANCE_SCHEMA","engine_attribute":"","secondary_engine_attribute":"","elements":[{"ordinal_position":1,"length":8,"order":1,"hidden":false,"column_opx":0},{"ordinal_position":2,"length":256,"order":1,"hidden":false,"column_opx":1}]}],"foreign_keys":[],"check_constraints":[],"partitions":[],"collation_id":255}}

Binary file not shown.

@ -0,0 +1,3 @@
yuxingshi.ssm.common.intercepter.config.WebConfig
yuxingshi.ssm.common.intercepter.filer.AuthInterceptor
yuxingshi.ssm.common.intercepter.config.IgnoreWhiteProperties

@ -0,0 +1,2 @@
yuxingshi.ssm.common.mybatisplus.config.MyBatisPlusConfig
yuxingshi.ssm.common.mybatisplus.handler.MyMetaObjectHandler

@ -0,0 +1,2 @@
yuxingshi.ssm.common.redis.config.RedisConfig
yuxingshi.ssm.common.redis.server.RedisService

@ -0,0 +1,2 @@
yuxingshi.ssm.common.security.service.TokenService
yuxingshi.ssm.common.security.config.PasswordEncoderConfig

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
</parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-sms</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>yuxingshi-sms-common</module>
<module>yuxingshi-sms-server</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<!--依赖版本-->
<spring-boot.version>3.3.3</spring-boot.version>
<spring-cloud-alibaba.version>2023.0.1.2</spring-cloud-alibaba.version>
<spring-cloud.version>2023.0.3</spring-cloud.version>
<redisson.version>3.50.0</redisson.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<commons-collections4.version>4.4</commons-collections4.version>
<aliyun.oss.version>3.17.4</aliyun.oss.version>
<pagehelper.boot.version>2.0.0</pagehelper.boot.version>
<jwt.version>0.9.1</jwt.version>
<jaxb.version>2.3.0</jaxb.version>
<hutool.version>5.8.22</hutool.version>
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
<dysmsapi20170525.version>3.1.1</dysmsapi20170525.version>
<spring-retry.version>2.0.8</spring-retry.version>
<seata.version>1.5.2</seata.version>
<canal.version>1.2.1-RELEASE</canal.version>
<idworker-snowflake.version>1.0.0</idworker-snowflake.version>
<alipay.version>4.35.0.ALL</alipay.version>
<xxljiob.version>3.2.0</xxljiob.version>
<!--运行环境-->
<runenv>test</runenv>
<java.opts.default>-Xmx256m</java.opts.default>
</properties>
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>4.0.3</version>
</dependency>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>${transmittable-thread-local.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>${spring-retry.version}</version>
</dependency>
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>${canal.version}</version>
</dependency>
<dependency>
<groupId>com.a3test.component</groupId>
<artifactId>idworker-snowflake</artifactId>
<version>${idworker-snowflake.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

@ -41,5 +41,10 @@
<artifactId>yuxingshi-sms-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,83 @@
package yuxingshi.sms.server.controller;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yuxingshi.sms.server.service.CourseService;
import yuxingshi.sms.server.domain.dto.course.CourseManageDTO;
import yuxingshi.sms.server.domain.dto.course.CourseQueryReqDTO;
import yuxingshi.sms.server.domain.dto.course.CourseRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.domain.vo.R;
import yuxingshi.sms.common.core.domain.enums.UserRole;
import yuxingshi.sms.common.intercepter.annotation.RequireIdentity;
@Slf4j
@RestController
@RequestMapping("/api/courses")
public class CourseController {
@Autowired
private CourseService courseService;
/**
*
*/
@PostMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<String> createCourse(@Valid @RequestBody CourseManageDTO dto) {
String courseId = courseService.createCourse(dto);
return R.ok(courseId, "课程创建成功");
}
/**
*
*/
@PutMapping("/{courseId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<Void> updateCourse(@PathVariable(value = "courseId") String courseId, @Valid @RequestBody CourseManageDTO dto) {
courseService.updateCourse(courseId, dto);
return R.ok();
}
/**
*
*/
@DeleteMapping("/{courseId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<Void> deleteCourse(@PathVariable(value = "courseId") String courseId) {
courseService.deleteCourse(courseId);
return R.ok();
}
/**
*
*/
@PutMapping("/{courseId}/disable")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<Void> disableCourse(@PathVariable(value = "courseId") String courseId) {
courseService.disableCourse(courseId);
return R.ok();
}
/**
*
*/
@PutMapping("/{courseId}/enable")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<Void> enableCourse(@PathVariable(value = "courseId") String courseId) {
courseService.enableCourse(courseId);
return R.ok();
}
/**
*
*/
@GetMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<BasePageDTO<CourseRespDTO>> queryCourses(@Valid CourseQueryReqDTO queryReq) {
BasePageDTO<CourseRespDTO> pageDTO = courseService.queryCourses(queryReq);
return R.ok(pageDTO);
}
}

@ -0,0 +1,89 @@
package yuxingshi.sms.server.controller;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yuxingshi.sms.server.service.CourseScoreService;
import yuxingshi.sms.server.domain.dto.score.CourseScoreManageDTO;
import yuxingshi.sms.server.domain.dto.score.CourseScoreQueryReqDTO;
import yuxingshi.sms.server.domain.dto.score.CourseScoreRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.domain.vo.R;
import yuxingshi.sms.common.core.domain.enums.UserRole;
import yuxingshi.sms.common.intercepter.annotation.RequireIdentity;
@Slf4j
@RestController
@RequestMapping("/api/course-scores")
public class CourseScoreController {
@Autowired
private CourseScoreService courseScoreService;
/**
*
*/
@PostMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<String> addCourseScore(@Valid @RequestBody CourseScoreManageDTO dto) {
String scoreId = courseScoreService.addCourseScore(dto);
return R.ok(scoreId, "成绩添加成功");
}
/**
*
*/
@PutMapping("/{scoreId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<Void> updateCourseScore(@PathVariable(value = "scoreId") String scoreId, @Valid @RequestBody CourseScoreManageDTO dto) {
courseScoreService.updateCourseScore(scoreId, dto);
return R.ok();
}
/**
*
*/
@DeleteMapping("/{scoreId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<Void> deleteCourseScore(@PathVariable(value = "scoreId") String scoreId) {
courseScoreService.deleteCourseScore(scoreId);
return R.ok();
}
/**
*
*/
@GetMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<BasePageDTO<CourseScoreRespDTO>> queryCourseScores(@Valid CourseScoreQueryReqDTO queryReq) {
BasePageDTO<CourseScoreRespDTO> pageDTO = courseScoreService.queryCourseScores(queryReq);
return R.ok(pageDTO);
}
/**
*
*/
@GetMapping("/student/{studentId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<BasePageDTO<CourseScoreRespDTO>> queryStudentScores(
@PathVariable(value = "studentId") String studentId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
BasePageDTO<CourseScoreRespDTO> pageDTO = courseScoreService.queryStudentScores(studentId, pageNum, pageSize);
return R.ok(pageDTO);
}
/**
*
*/
@GetMapping("/course/{courseId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<BasePageDTO<CourseScoreRespDTO>> queryCourseStudentScores(
@PathVariable(value = "courseId") String courseId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
BasePageDTO<CourseScoreRespDTO> pageDTO = courseScoreService.queryCourseStudentScores(courseId, pageNum, pageSize);
return R.ok(pageDTO);
}
}

@ -0,0 +1,100 @@
package yuxingshi.sms.server.controller;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yuxingshi.sms.server.service.MajorService;
import yuxingshi.sms.server.domain.dto.major.MajorManageDTO;
import yuxingshi.sms.server.domain.dto.major.MajorQueryReqDTO;
import yuxingshi.sms.server.domain.dto.major.MajorRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.domain.vo.R;
import yuxingshi.sms.common.core.domain.enums.UserRole;
import yuxingshi.sms.common.intercepter.annotation.RequireIdentity;
@Slf4j
@RestController
@RequestMapping("/api/majors")
public class MajorController {
@Autowired
private MajorService majorService;
/**
*
*/
@PostMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<String> createMajor(@Valid @RequestBody MajorManageDTO dto) {
String majorId = majorService.createMajor(dto);
return R.ok(majorId, "专业创建成功");
}
/**
*
*/
@PutMapping("/{majorId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> updateMajor(@PathVariable(value = "majorId") String majorId, @Valid @RequestBody MajorManageDTO dto) {
majorService.updateMajor(majorId, dto);
return R.ok();
}
/**
*
*/
@DeleteMapping("/{majorId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> deleteMajor(@PathVariable(value = "majorId") String majorId) {
majorService.deleteMajor(majorId);
return R.ok();
}
/**
*
*/
@GetMapping("/{majorId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<MajorRespDTO> getMajorById(@PathVariable(value = "majorId") String majorId) {
MajorRespDTO major = majorService.getMajorById(majorId);
if (major == null) {
return R.fail("专业不存在");
}
return R.ok(major);
}
/**
*
*/
@PutMapping("/{majorId}/disable")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> disableMajor(@PathVariable(value = "majorId") String majorId) {
majorService.disableMajor(majorId);
return R.ok();
}
/**
*
*/
@PutMapping("/{majorId}/enable")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> enableMajor(@PathVariable(value = "majorId") String majorId) {
majorService.enableMajor(majorId);
return R.ok();
}
/**
*
*/
@GetMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<BasePageDTO<MajorRespDTO>> queryMajors(@Valid MajorQueryReqDTO queryReq) {
BasePageDTO<MajorRespDTO> pageDTO = majorService.queryMajors(queryReq);
return R.ok(pageDTO);
}
}

@ -0,0 +1,83 @@
package yuxingshi.sms.server.controller;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import yuxingshi.sms.server.service.TeacherService;
import yuxingshi.sms.server.domain.dto.teacher.TeacherManageDTO;
import yuxingshi.sms.server.domain.dto.teacher.TeacherQueryReqDTO;
import yuxingshi.sms.server.domain.dto.teacher.TeacherRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.domain.vo.R;
import yuxingshi.sms.common.core.domain.enums.UserRole;
import yuxingshi.sms.common.intercepter.annotation.RequireIdentity;
@Slf4j
@RestController
@RequestMapping("/api/teachers")
public class TeacherController {
@Autowired
private TeacherService teacherService;
/**
* ()
*/
@PostMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<String> createTeacher(@Valid @RequestBody TeacherManageDTO dto) {
String teacherId = teacherService.createTeacher(dto);
return R.ok(teacherId, "教师创建成功");
}
/**
*
*/
@PutMapping("/{teacherId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> updateTeacher(@PathVariable(value = "teacherId") String teacherId, @Valid @RequestBody TeacherManageDTO dto) {
teacherService.updateTeacher(teacherId, dto);
return R.ok();
}
/**
*
*/
@DeleteMapping("/{teacherId}")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> deleteTeacher(@PathVariable(value = "teacherId") String teacherId) {
teacherService.deleteTeacher(teacherId);
return R.ok();
}
/**
*
*/
@PutMapping("/{teacherId}/disable")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> disableTeacher(@PathVariable(value = "teacherId") String teacherId) {
teacherService.disableTeacher(teacherId);
return R.ok();
}
/**
*
*/
@PutMapping("/{teacherId}/enable")
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN})
public R<Void> enableTeacher(@PathVariable(value = "teacherId") String teacherId) {
teacherService.enableTeacher(teacherId);
return R.ok();
}
/**
*
*/
@GetMapping
@RequireIdentity({UserRole.ROLE_SYS_ADMIN, UserRole.ROLE_ADMIN, UserRole.ROLE_TEACHER})
public R<BasePageDTO<TeacherRespDTO>> queryTeachers(@Valid TeacherQueryReqDTO queryReq) {
BasePageDTO<TeacherRespDTO> pageDTO = teacherService.queryTeachers(queryReq);
return R.ok(pageDTO);
}
}

@ -0,0 +1,40 @@
package yuxingshi.sms.server.domain.dto.course;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* /DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseManageDTO {
@NotBlank(message = "教师ID不能为空")
private String teacherId;
@NotBlank(message = "课程名称不能为空")
@Size(max = 100, message = "课程名称长度不能超过100个字符")
private String courseName;
@NotBlank(message = "课程代码不能为空")
@Pattern(regexp = "^[A-Z0-9]{4,20}$", message = "课程代码格式不正确应为4-20位大写字母或数字")
private String courseCode;
@DecimalMin(value = "0.5", message = "学分不能小于0.5")
@DecimalMax(value = "10.0", message = "学分不能大于10.0")
private BigDecimal credit;
@Min(value = 1, message = "总学时不能小于1")
@Max(value = 500, message = "总学时不能大于500")
private Integer totalHours;
@Size(max = 500, message = "课程描述长度不能超过500个字符")
private String description;
}

@ -0,0 +1,24 @@
package yuxingshi.sms.server.domain.dto.course;
import yuxingshi.sms.common.core.domain.dto.BasePageReqDTO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseQueryReqDTO extends BasePageReqDTO {
private String teacherId;
private String courseName;
private String courseCode;
private Integer status;
}

@ -0,0 +1,41 @@
package yuxingshi.sms.server.domain.dto.course;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseRespDTO {
private String id;
private String teacherId;
private String courseName;
private String courseCode;
private BigDecimal credit;
private Integer totalHours;
private String description;
private Integer status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updatedTime;
}

@ -0,0 +1,29 @@
package yuxingshi.sms.server.domain.dto.major;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotBlank;
/**
* /DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MajorManageDTO {
@NotBlank(message = "专业代码不能为空")
private String majorCode;
@NotBlank(message = "专业名称不能为空")
private String majorName;
private String description;
}

@ -0,0 +1,31 @@
package yuxingshi.sms.server.domain.dto.major;
import lombok.Data;
import lombok.EqualsAndHashCode;
import yuxingshi.sms.common.core.domain.dto.BasePageReqDTO;
/**
* DTO
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MajorQueryReqDTO extends BasePageReqDTO {
/**
*
*/
private String majorName;
/**
*
*/
private String majorCode;
/**
* 0=1=
*/
private Integer status;
}

@ -0,0 +1,35 @@
package yuxingshi.sms.server.domain.dto.major;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MajorRespDTO {
private String id;
private String majorCode;
private String majorName;
private String description;
private Integer status;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
}

@ -0,0 +1,40 @@
package yuxingshi.sms.server.domain.dto.score;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* /DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseScoreManageDTO {
@NotBlank(message = "课程ID不能为空")
private String courseId;
@NotBlank(message = "学生ID不能为空")
private String studentId;
@DecimalMin(value = "0", message = "平时成绩不能小于0")
@DecimalMax(value = "100", message = "平时成绩不能大于100")
private BigDecimal usualScore;
@DecimalMin(value = "0", message = "期中成绩不能小于0")
@DecimalMax(value = "100", message = "期中成绩不能大于100")
private BigDecimal midtermScore;
@DecimalMin(value = "0", message = "期末成绩不能小于0")
@DecimalMax(value = "100", message = "期末成绩不能大于100")
private BigDecimal finalScore;
private String remark;
}

@ -0,0 +1,24 @@
package yuxingshi.sms.server.domain.dto.score;
import yuxingshi.sms.common.core.domain.dto.BasePageReqDTO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseScoreQueryReqDTO extends BasePageReqDTO {
private String courseId;
private String studentId;
private String grade;
private String sortBy; // 排序字段total_score, grade等
}

@ -0,0 +1,51 @@
package yuxingshi.sms.server.domain.dto.score;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CourseScoreRespDTO {
private String id;
private String courseId;
private String courseName;
private String courseCode;
private String studentId;
private String studentNo;
private String studentName;
private BigDecimal usualScore;
private BigDecimal midtermScore;
private BigDecimal finalScore;
private BigDecimal totalScore;
private String grade;
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updatedTime;
}

@ -0,0 +1,32 @@
package yuxingshi.sms.server.domain.dto.teacher;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* /DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TeacherManageDTO {
@NotBlank(message = "教师工号不能为空")
@Pattern(regexp = "^[A-Z0-9]{6,20}$", message = "教师工号格式不正确应为6-20位大写字母或数字")
private String teacherNo;
@NotBlank(message = "教师真实姓名不能为空")
@Size(max = 50, message = "真实姓名长度不能超过50个字符")
private String realName;
@Size(max = 100, message = "部门名称长度不能超过100个字符")
private String department;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
}

@ -0,0 +1,24 @@
package yuxingshi.sms.server.domain.dto.teacher;
import yuxingshi.sms.common.core.domain.dto.BasePageReqDTO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TeacherQueryReqDTO extends BasePageReqDTO {
private String teacherNo;
private String realName;
private String department;
private Integer status;
}

@ -0,0 +1,36 @@
package yuxingshi.sms.server.domain.dto.teacher;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TeacherRespDTO {
private String id;
private String teacherNo;
private String realName;
private String department;
private String phone;
private Integer status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updatedTime;
}

@ -0,0 +1,27 @@
package yuxingshi.sms.server.domain.dto.user;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserChangePasswordDTO {
@NotBlank(message = "旧密码不能为空")
private String oldPassword;
@NotBlank(message = "新密码不能为空")
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9@#$%^&*]{6,20}$",
message = "新密码必须包含字母和数字长度6-20")
private String newPassword;
}

@ -0,0 +1,27 @@
package yuxingshi.sms.server.domain.dto.user;
import lombok.Data;
import lombok.EqualsAndHashCode;
import yuxingshi.sms.common.core.domain.dto.BasePageReqDTO;
/**
* DTO
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class UserQueryReqDTO extends BasePageReqDTO {
/**
*
*/
private String username;
/**
* 1=2=3=4=
*/
private Integer role;
/**
* 0=1=2=
*/
private Integer status;
}

@ -0,0 +1,52 @@
package yuxingshi.sms.server.domain.dto.user;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserRespDTO {
/**
* ID
*/
private String id;
/**
*
*/
private String username;
/**
*
*/
private String email;
/**
* 1=2=3=4=
*/
private Integer role;
/**
* 0=1=2=
*/
private Integer status;
/**
*
*/
private LocalDateTime createdTime;
/**
*
*/
private LocalDateTime updatedTime;
}

@ -0,0 +1,21 @@
package yuxingshi.sms.server.domain.dto.user;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.Email;
/**
* DTO
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserUpdateDTO {
@Email(message = "邮箱格式不正确")
private String email;
}

@ -0,0 +1,43 @@
package yuxingshi.sms.server.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("courses")
public class Course {
@TableId(type = IdType.ASSIGN_ID)
private String id;
private String teacherId;
private String courseName;
private String courseCode;
private BigDecimal credit;
private Integer totalHours;
private String description;
private Integer status;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
}

@ -0,0 +1,47 @@
package yuxingshi.sms.server.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("course_scores")
public class CourseScore {
@TableId(type = IdType.ASSIGN_ID)
private String id;
private String courseId;
private String studentId;
private BigDecimal usualScore;
private BigDecimal midtermScore;
private BigDecimal finalScore;
private BigDecimal totalScore;
private String grade;
private Integer status;
private String remark;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
}

@ -0,0 +1,38 @@
package yuxingshi.sms.server.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
/**
*
*/
@Getter
@Setter
@ToString
@TableName("majors")
public class Major {
@TableId(type = IdType.ASSIGN_ID)
private String id;
private String majorCode;
private String majorName;
private String description;
private Integer status;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
}

@ -0,0 +1,40 @@
package yuxingshi.sms.server.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
*
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("teachers")
public class Teacher {
@TableId(type = IdType.ASSIGN_ID)
private String id;
private String userId;
private String teacherNo;
private String realName;
private String department;
private String phone;
private Integer status;
private LocalDateTime createdTime;
private LocalDateTime updatedTime;
}

@ -0,0 +1,12 @@
package yuxingshi.sms.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import yuxingshi.sms.server.domain.entity.Course;
/**
* Mapper
*/
@Mapper
public interface CourseMapper extends BaseMapper<Course> {
}

@ -0,0 +1,12 @@
package yuxingshi.sms.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import yuxingshi.sms.server.domain.entity.CourseScore;
/**
* Mapper
*/
@Mapper
public interface CourseScoreMapper extends BaseMapper<CourseScore> {
}

@ -0,0 +1,16 @@
package yuxingshi.sms.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import yuxingshi.sms.server.domain.entity.Major;
/**
* Mapper
*/
@Mapper
public interface MajorMapper extends BaseMapper<Major> {
}

@ -0,0 +1,12 @@
package yuxingshi.sms.server.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import yuxingshi.sms.server.domain.entity.Teacher;
/**
* Mapper
*/
@Mapper
public interface TeacherMapper extends BaseMapper<Teacher> {
}

@ -0,0 +1,62 @@
package yuxingshi.sms.server.service;
import yuxingshi.sms.server.domain.entity.CourseScore;
import yuxingshi.sms.server.domain.dto.score.CourseScoreManageDTO;
import yuxingshi.sms.server.domain.dto.score.CourseScoreQueryReqDTO;
import yuxingshi.sms.server.domain.dto.score.CourseScoreRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
/**
*
*/
public interface CourseScoreService {
/**
*
*/
String addCourseScore(CourseScoreManageDTO dto);
/**
*
*/
void updateCourseScore(String scoreId, CourseScoreManageDTO dto);
/**
*
*/
void deleteCourseScore(String scoreId);
/**
* ID
*/
CourseScore getCourseScoreById(String scoreId);
/**
*
*/
CourseScore getCourseScore(String courseId, String studentId);
/**
*
*/
void deleteCourseAllScores(String courseId);
/**
*
*/
void deleteStudentAllScores(String studentId);
/**
*
*/
BasePageDTO<CourseScoreRespDTO> queryCourseScores(CourseScoreQueryReqDTO queryReq);
/**
*
*/
BasePageDTO<CourseScoreRespDTO> queryStudentScores(String studentId, Integer pageNum, Integer pageSize);
/**
*
*/
BasePageDTO<CourseScoreRespDTO> queryCourseStudentScores(String courseId, Integer pageNum, Integer pageSize);
}

@ -0,0 +1,52 @@
package yuxingshi.sms.server.service;
import yuxingshi.sms.server.domain.entity.Course;
import yuxingshi.sms.server.domain.dto.course.CourseManageDTO;
import yuxingshi.sms.server.domain.dto.course.CourseQueryReqDTO;
import yuxingshi.sms.server.domain.dto.course.CourseRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
/**
*
*/
public interface CourseService {
/**
*
*/
String createCourse(CourseManageDTO dto);
/**
*
*/
void updateCourse(String courseId, CourseManageDTO dto);
/**
*
*/
void deleteCourse(String courseId);
/**
* ID
*/
Course getCourseById(String courseId);
/**
*
*/
Course getCourseByCode(String courseCode);
/**
*
*/
void disableCourse(String courseId);
/**
*
*/
void enableCourse(String courseId);
/**
*
*/
BasePageDTO<CourseRespDTO> queryCourses(CourseQueryReqDTO queryReq);
}

@ -0,0 +1,52 @@
package yuxingshi.sms.server.service;
import yuxingshi.sms.server.domain.dto.major.MajorManageDTO;
import yuxingshi.sms.server.domain.dto.major.MajorQueryReqDTO;
import yuxingshi.sms.server.domain.dto.major.MajorRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
/**
*
*/
public interface MajorService {
/**
*
*/
String createMajor(MajorManageDTO dto);
/**
*
*/
void updateMajor(String majorId, MajorManageDTO dto);
/**
*
*/
void deleteMajor(String majorId);
/**
*
*/
MajorRespDTO getMajorById(String majorId);
/**
*
*/
MajorRespDTO getMajorByCode(String majorCode);
/**
*
*/
void disableMajor(String majorId);
/**
*
*/
void enableMajor(String majorId);
/**
*
*/
BasePageDTO<MajorRespDTO> queryMajors(MajorQueryReqDTO queryReq);
}

@ -0,0 +1,52 @@
package yuxingshi.sms.server.service;
import yuxingshi.sms.server.domain.entity.Teacher;
import yuxingshi.sms.server.domain.dto.teacher.TeacherManageDTO;
import yuxingshi.sms.server.domain.dto.teacher.TeacherQueryReqDTO;
import yuxingshi.sms.server.domain.dto.teacher.TeacherRespDTO;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
/**
*
*/
public interface TeacherService {
/**
*
*/
String createTeacher(TeacherManageDTO dto);
/**
*
*/
void updateTeacher(String teacherId, TeacherManageDTO dto);
/**
*
*/
void deleteTeacher(String teacherId);
/**
* ID
*/
Teacher getTeacherById(String teacherId);
/**
*
*/
Teacher getTeacherByNo(String teacherNo);
/**
*
*/
void disableTeacher(String teacherId);
/**
*
*/
void enableTeacher(String teacherId);
/**
*
*/
BasePageDTO<TeacherRespDTO> queryTeachers(TeacherQueryReqDTO queryReq);
}

@ -0,0 +1,332 @@
package yuxingshi.sms.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yuxingshi.sms.server.domain.entity.Course;
import yuxingshi.sms.server.domain.entity.CourseScore;
import yuxingshi.sms.server.domain.entity.Student;
import yuxingshi.sms.server.domain.dto.score.CourseScoreManageDTO;
import yuxingshi.sms.server.domain.dto.score.CourseScoreQueryReqDTO;
import yuxingshi.sms.server.domain.dto.score.CourseScoreRespDTO;
import yuxingshi.sms.server.mapper.CourseScoreMapper;
import yuxingshi.sms.server.mapper.CourseMapper;
import yuxingshi.sms.server.mapper.StudentMapper;
import yuxingshi.sms.server.service.CourseScoreService;
import yuxingshi.sms.server.utils.CourseScoreUtil;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.exception.ServiceException;
import yuxingshi.sms.common.core.utils.StringUtil;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class CourseScoreServiceImpl implements CourseScoreService {
@Autowired
private CourseScoreMapper courseScoreMapper;
@Autowired
private CourseMapper courseMapper;
@Autowired
private StudentMapper studentMapper;
@Override
public String addCourseScore(CourseScoreManageDTO dto) {
// 检查课程是否存在
Course course = courseMapper.selectById(dto.getCourseId());
if (course == null) {
throw new ServiceException("课程不存在");
}
// 检查学生是否存在
Student student = studentMapper.selectById(dto.getStudentId());
if (student == null) {
throw new ServiceException("学生不存在");
}
// 检查该学生是否已有该课程的成绩
CourseScore existing = getCourseScore(dto.getCourseId(), dto.getStudentId());
if (existing != null) {
throw new ServiceException("该学生已有该课程的成绩,请使用更新接口修改");
}
// 计算总成绩和等级
BigDecimal totalScore = CourseScoreUtil.calculateTotalScore(
dto.getUsualScore(), dto.getMidtermScore(), dto.getFinalScore());
String grade = CourseScoreUtil.calculateGrade(totalScore);
CourseScore courseScore = new CourseScore();
courseScore.setCourseId(dto.getCourseId());
courseScore.setStudentId(dto.getStudentId());
courseScore.setUsualScore(dto.getUsualScore());
courseScore.setMidtermScore(dto.getMidtermScore());
courseScore.setFinalScore(dto.getFinalScore());
courseScore.setTotalScore(totalScore);
courseScore.setGrade(grade);
courseScore.setRemark(dto.getRemark());
courseScore.setStatus(1);
courseScore.setCreatedTime(LocalDateTime.now());
courseScore.setUpdatedTime(LocalDateTime.now());
courseScoreMapper.insert(courseScore);
log.info("添加课程成绩成功: courseId={}, studentId={}, totalScore={}, grade={}",
dto.getCourseId(), dto.getStudentId(), totalScore, grade);
return courseScore.getId();
}
@Override
public void updateCourseScore(String scoreId, CourseScoreManageDTO dto) {
CourseScore courseScore = getCourseScoreById(scoreId);
if (courseScore == null) {
throw new ServiceException("成绩不存在");
}
// 检查课程是否存在
Course course = courseMapper.selectById(dto.getCourseId());
if (course == null) {
throw new ServiceException("课程不存在");
}
// 检查学生是否存在
Student student = studentMapper.selectById(dto.getStudentId());
if (student == null) {
throw new ServiceException("学生不存在");
}
// 如果更改了课程或学生,检查新的课程+学生组合是否已存在
if (!dto.getCourseId().equals(courseScore.getCourseId()) ||
!dto.getStudentId().equals(courseScore.getStudentId())) {
CourseScore existing = getCourseScore(dto.getCourseId(), dto.getStudentId());
if (existing != null) {
throw new ServiceException("该学生已有该课程的成绩");
}
}
// 重新计算总成绩和等级
BigDecimal totalScore = CourseScoreUtil.calculateTotalScore(
dto.getUsualScore(), dto.getMidtermScore(), dto.getFinalScore());
String grade = CourseScoreUtil.calculateGrade(totalScore);
courseScore.setCourseId(dto.getCourseId());
courseScore.setStudentId(dto.getStudentId());
courseScore.setUsualScore(dto.getUsualScore());
courseScore.setMidtermScore(dto.getMidtermScore());
courseScore.setFinalScore(dto.getFinalScore());
courseScore.setTotalScore(totalScore);
courseScore.setGrade(grade);
courseScore.setRemark(dto.getRemark());
courseScore.setUpdatedTime(LocalDateTime.now());
courseScoreMapper.updateById(courseScore);
log.info("更新课程成绩成功: scoreId={}, totalScore={}, grade={}", scoreId, totalScore, grade);
}
@Override
public void deleteCourseScore(String scoreId) {
CourseScore courseScore = getCourseScoreById(scoreId);
if (courseScore == null) {
throw new ServiceException("成绩不存在");
}
courseScoreMapper.deleteById(scoreId);
log.info("删除课程成绩成功: scoreId={}", scoreId);
}
@Override
public CourseScore getCourseScoreById(String scoreId) {
return courseScoreMapper.selectById(scoreId);
}
@Override
public CourseScore getCourseScore(String courseId, String studentId) {
LambdaQueryWrapper<CourseScore> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CourseScore::getCourseId, courseId)
.eq(CourseScore::getStudentId, studentId)
.eq(CourseScore::getStatus, 1);
return courseScoreMapper.selectOne(queryWrapper);
}
@Override
public void deleteCourseAllScores(String courseId) {
LambdaQueryWrapper<CourseScore> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CourseScore::getCourseId, courseId);
courseScoreMapper.delete(queryWrapper);
log.info("删除课程所有成绩成功: courseId={}", courseId);
}
@Override
public void deleteStudentAllScores(String studentId) {
LambdaQueryWrapper<CourseScore> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CourseScore::getStudentId, studentId);
courseScoreMapper.delete(queryWrapper);
log.info("删除学生所有成绩成功: studentId={}", studentId);
}
@Override
public BasePageDTO<CourseScoreRespDTO> queryCourseScores(CourseScoreQueryReqDTO queryReq) {
LambdaQueryWrapper<CourseScore> queryWrapper = new LambdaQueryWrapper<>();
// 根据课程ID查询
if (queryReq.getCourseId() != null) {
queryWrapper.eq(CourseScore::getCourseId, queryReq.getCourseId());
}
// 根据学生ID查询
if (queryReq.getStudentId() != null) {
queryWrapper.eq(CourseScore::getStudentId, queryReq.getStudentId());
}
// 根据等级查询
if (StringUtil.isNotEmpty(queryReq.getGrade())) {
queryWrapper.eq(CourseScore::getGrade, queryReq.getGrade());
}
// 状态过滤
queryWrapper.eq(CourseScore::getStatus, 1);
// 排序
if (StringUtil.isNotEmpty(queryReq.getSortBy())) {
if ("total_score".equals(queryReq.getSortBy())) {
queryWrapper.orderByDesc(CourseScore::getTotalScore);
} else if ("grade".equals(queryReq.getSortBy())) {
queryWrapper.orderByAsc(CourseScore::getGrade);
} else {
queryWrapper.orderByDesc(CourseScore::getCreatedTime);
}
} else {
queryWrapper.orderByDesc(CourseScore::getCreatedTime);
}
// 使用MyBatisPlus分页插件
Page<CourseScore> page = new Page<>(queryReq.getPageNo(), queryReq.getPageSize());
Page<CourseScore> pageResult = courseScoreMapper.selectPage(page, queryWrapper);
List<CourseScoreRespDTO> respList = pageResult.getRecords().stream()
.map(score -> {
// 查询课程信息
Course course = courseMapper.selectById(score.getCourseId());
// 查询学生信息
Student student = studentMapper.selectById(score.getStudentId());
return CourseScoreRespDTO.builder()
.id(score.getId())
.courseId(score.getCourseId())
.courseName(course != null ? course.getCourseName() : "")
.courseCode(course != null ? course.getCourseCode() : "")
.studentId(score.getStudentId())
.studentNo(student != null ? student.getStudentNo() : "")
.studentName(student != null ? student.getRealName() : "")
.usualScore(score.getUsualScore())
.midtermScore(score.getMidtermScore())
.finalScore(score.getFinalScore())
.totalScore(score.getTotalScore())
.grade(score.getGrade())
.remark(score.getRemark())
.createdTime(score.getCreatedTime())
.updatedTime(score.getUpdatedTime())
.build();
})
.collect(Collectors.toList());
return BasePageDTO.<CourseScoreRespDTO>builder()
.list(respList)
.totals(pageResult.getTotal())
.totalPages(BasePageDTO.calculateTotalPages(pageResult.getTotal(), queryReq.getPageSize()))
.build();
}
@Override
public BasePageDTO<CourseScoreRespDTO> queryStudentScores(String studentId, Integer pageNum, Integer pageSize) {
LambdaQueryWrapper<CourseScore> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CourseScore::getStudentId, studentId)
.eq(CourseScore::getStatus, 1)
.orderByDesc(CourseScore::getCreatedTime);
// 使用MyBatisPlus分页插件
Page<CourseScore> page = new Page<>(pageNum, pageSize);
Page<CourseScore> pageResult = courseScoreMapper.selectPage(page, queryWrapper);
List<CourseScoreRespDTO> respList = pageResult.getRecords().stream()
.map(score -> {
// 查询课程信息
Course course = courseMapper.selectById(score.getCourseId());
// 查询学生信息
Student student = studentMapper.selectById(score.getStudentId());
return CourseScoreRespDTO.builder()
.id(score.getId())
.courseId(score.getCourseId())
.courseName(course != null ? course.getCourseName() : "")
.courseCode(course != null ? course.getCourseCode() : "")
.studentId(score.getStudentId())
.studentNo(student != null ? student.getStudentNo() : "")
.studentName(student != null ? student.getRealName() : "")
.usualScore(score.getUsualScore())
.midtermScore(score.getMidtermScore())
.finalScore(score.getFinalScore())
.totalScore(score.getTotalScore())
.grade(score.getGrade())
.remark(score.getRemark())
.createdTime(score.getCreatedTime())
.updatedTime(score.getUpdatedTime())
.build();
})
.collect(Collectors.toList());
return BasePageDTO.<CourseScoreRespDTO>builder()
.list(respList)
.totals(pageResult.getTotal())
.totalPages(BasePageDTO.calculateTotalPages(pageResult.getTotal(), pageSize))
.build();
}
@Override
public BasePageDTO<CourseScoreRespDTO> queryCourseStudentScores(String courseId, Integer pageNum, Integer pageSize) {
LambdaQueryWrapper<CourseScore> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(CourseScore::getCourseId, courseId)
.eq(CourseScore::getStatus, 1)
.orderByDesc(CourseScore::getTotalScore);
// 使用MyBatisPlus分页插件
Page<CourseScore> page = new Page<>(pageNum, pageSize);
Page<CourseScore> pageResult = courseScoreMapper.selectPage(page, queryWrapper);
List<CourseScoreRespDTO> respList = pageResult.getRecords().stream()
.map(score -> {
// 查询课程信息
Course course = courseMapper.selectById(score.getCourseId());
// 查询学生信息
Student student = studentMapper.selectById(score.getStudentId());
return CourseScoreRespDTO.builder()
.id(score.getId())
.courseId(score.getCourseId())
.courseName(course != null ? course.getCourseName() : "")
.courseCode(course != null ? course.getCourseCode() : "")
.studentId(score.getStudentId())
.studentNo(student != null ? student.getStudentNo() : "")
.studentName(student != null ? student.getRealName() : "")
.usualScore(score.getUsualScore())
.midtermScore(score.getMidtermScore())
.finalScore(score.getFinalScore())
.totalScore(score.getTotalScore())
.grade(score.getGrade())
.remark(score.getRemark())
.createdTime(score.getCreatedTime())
.updatedTime(score.getUpdatedTime())
.build();
})
.collect(Collectors.toList());
return BasePageDTO.<CourseScoreRespDTO>builder()
.list(respList)
.totals(pageResult.getTotal())
.totalPages(BasePageDTO.calculateTotalPages(pageResult.getTotal(), pageSize))
.build();
}
}

@ -0,0 +1,271 @@
package yuxingshi.sms.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yuxingshi.sms.server.domain.entity.Course;
import yuxingshi.sms.server.domain.entity.CourseScore;
import yuxingshi.sms.server.domain.entity.Teacher;
import yuxingshi.sms.server.domain.dto.course.CourseManageDTO;
import yuxingshi.sms.server.domain.dto.course.CourseQueryReqDTO;
import yuxingshi.sms.server.domain.dto.course.CourseRespDTO;
import yuxingshi.sms.server.mapper.CourseMapper;
import yuxingshi.sms.server.mapper.CourseScoreMapper;
import yuxingshi.sms.server.mapper.TeacherMapper;
import yuxingshi.sms.server.service.CourseService;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.domain.enums.UserRole;
import yuxingshi.sms.common.core.exception.ServiceException;
import yuxingshi.sms.common.core.utils.StringUtil;
import yuxingshi.sms.common.core.utils.ThreadLocalUtil;
import yuxingshi.sms.common.core.constants.SecurityConstants;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Autowired
private TeacherMapper teacherMapper;
@Autowired
private CourseScoreMapper courseScoreMapper;
@Override
public String createCourse(CourseManageDTO dto) {
// 检查教师是否存在
Teacher teacher = teacherMapper.selectById(dto.getTeacherId());
if (teacher == null) {
throw new ServiceException("教师不存在");
}
// 权限检查:教师只能为自己创建课程
String currentUserId = ThreadLocalUtil.get(SecurityConstants.USER_ID, String.class);
Integer userIdentity = ThreadLocalUtil.get(SecurityConstants.USER_IDENTITY, Integer.class);
// 如果是教师角色,只能为自己创建课程
if (UserRole.ROLE_TEACHER.getValue().equals(userIdentity)) {
if (teacher.getUserId() == null || !currentUserId.equals(teacher.getUserId())) {
throw new ServiceException("无权限为其他教师创建课程");
}
}
// 检查课程代码是否已存在
Course codeExist = getCourseByCode(dto.getCourseCode());
if (codeExist != null) {
throw new ServiceException("课程代码已存在");
}
Course course = new Course();
course.setTeacherId(dto.getTeacherId());
course.setCourseName(dto.getCourseName());
course.setCourseCode(dto.getCourseCode());
course.setCredit(dto.getCredit());
course.setTotalHours(dto.getTotalHours());
course.setDescription(dto.getDescription());
course.setStatus(1);
course.setCreatedTime(LocalDateTime.now());
course.setUpdatedTime(LocalDateTime.now());
courseMapper.insert(course);
log.info("创建课程成功: courseCode={}, courseName={}, teacherId={}", dto.getCourseCode(), dto.getCourseName(), dto.getTeacherId());
return course.getId();
}
@Override
public void updateCourse(String courseId, CourseManageDTO dto) {
Course course = getCourseById(courseId);
if (course == null) {
throw new ServiceException("课程不存在");
}
// 权限检查:教师只能操作自己创建的课程
checkCoursePermission(courseId);
// 检查教师是否存在
Teacher teacher = teacherMapper.selectById(dto.getTeacherId());
if (teacher == null) {
throw new ServiceException("教师不存在");
}
// 检查课程代码是否被其他课程使用
if (!dto.getCourseCode().equals(course.getCourseCode())) {
Course codeExist = getCourseByCode(dto.getCourseCode());
if (codeExist != null) {
throw new ServiceException("课程代码已存在");
}
}
course.setTeacherId(dto.getTeacherId());
course.setCourseName(dto.getCourseName());
course.setCourseCode(dto.getCourseCode());
course.setCredit(dto.getCredit());
course.setTotalHours(dto.getTotalHours());
course.setDescription(dto.getDescription());
course.setUpdatedTime(LocalDateTime.now());
courseMapper.updateById(course);
log.info("更新课程成功: courseId={}", courseId);
}
@Override
public void deleteCourse(String courseId) {
Course course = getCourseById(courseId);
if (course == null) {
throw new ServiceException("课程不存在");
}
// 权限检查:教师只能操作自己创建的课程
checkCoursePermission(courseId);
// 检查是否有关联的成绩记录
LambdaQueryWrapper<CourseScore> scoreQuery = new LambdaQueryWrapper<>();
scoreQuery.eq(CourseScore::getCourseId, courseId);
long scoreCount = courseScoreMapper.selectCount(scoreQuery);
if (scoreCount > 0) {
throw new ServiceException("课程存在成绩记录,无法删除。请先删除相关成绩记录");
}
courseMapper.deleteById(courseId);
log.info("删除课程成功: courseId={}", courseId);
}
@Override
public Course getCourseById(String courseId) {
return courseMapper.selectById(courseId);
}
@Override
public Course getCourseByCode(String courseCode) {
LambdaQueryWrapper<Course> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Course::getCourseCode, courseCode);
return courseMapper.selectOne(queryWrapper);
}
@Override
public void disableCourse(String courseId) {
Course course = getCourseById(courseId);
if (course == null) {
throw new ServiceException("课程不存在");
}
// 权限检查:教师只能操作自己创建的课程
checkCoursePermission(courseId);
LambdaUpdateWrapper<Course> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Course::getId, courseId)
.set(Course::getStatus, 0)
.set(Course::getUpdatedTime, LocalDateTime.now());
courseMapper.update(null, updateWrapper);
log.info("禁用课程成功: courseId={}", courseId);
}
@Override
public void enableCourse(String courseId) {
Course course = getCourseById(courseId);
if (course == null) {
throw new ServiceException("课程不存在");
}
// 权限检查:教师只能操作自己创建的课程
checkCoursePermission(courseId);
LambdaUpdateWrapper<Course> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Course::getId, courseId)
.set(Course::getStatus, 1)
.set(Course::getUpdatedTime, LocalDateTime.now());
courseMapper.update(null, updateWrapper);
log.info("启用课程成功: courseId={}", courseId);
}
@Override
public BasePageDTO<CourseRespDTO> queryCourses(CourseQueryReqDTO queryReq) {
LambdaQueryWrapper<Course> queryWrapper = new LambdaQueryWrapper<>();
// 根据教师ID查询
if (queryReq.getTeacherId() != null) {
queryWrapper.eq(Course::getTeacherId, queryReq.getTeacherId());
}
// 根据课程名称模糊查询
if (StringUtil.isNotEmpty(queryReq.getCourseName())) {
queryWrapper.like(Course::getCourseName, queryReq.getCourseName());
}
// 根据课程代码模糊查询
if (StringUtil.isNotEmpty(queryReq.getCourseCode())) {
queryWrapper.like(Course::getCourseCode, queryReq.getCourseCode());
}
// 根据状态查询
if (queryReq.getStatus() != null) {
queryWrapper.eq(Course::getStatus, queryReq.getStatus());
}
// 按创建时间降序排序
queryWrapper.orderByDesc(Course::getCreatedTime);
// 使用MyBatisPlus分页插件
Page<Course> page = new Page<>(queryReq.getPageNo(), queryReq.getPageSize());
Page<Course> pageResult = courseMapper.selectPage(page, queryWrapper);
List<CourseRespDTO> respList = pageResult.getRecords().stream()
.map(course -> CourseRespDTO.builder()
.id(course.getId())
.teacherId(course.getTeacherId())
.courseName(course.getCourseName())
.courseCode(course.getCourseCode())
.credit(course.getCredit())
.totalHours(course.getTotalHours())
.description(course.getDescription())
.status(course.getStatus())
.createdTime(course.getCreatedTime())
.updatedTime(course.getUpdatedTime())
.build())
.collect(Collectors.toList());
return BasePageDTO.<CourseRespDTO>builder()
.list(respList)
.totals(pageResult.getTotal())
.totalPages(BasePageDTO.calculateTotalPages(pageResult.getTotal(), queryReq.getPageSize()))
.build();
}
/**
*
*
*/
private void checkCoursePermission(String courseId) {
String currentUserId = ThreadLocalUtil.get(SecurityConstants.USER_ID, String.class);
Integer userIdentity = ThreadLocalUtil.get(SecurityConstants.USER_IDENTITY, Integer.class);
// 管理员和系统管理员可以操作所有课程
if (UserRole.ROLE_ADMIN.getValue().equals(userIdentity) ||
UserRole.ROLE_SYS_ADMIN.getValue().equals(userIdentity)) {
return;
}
// 教师只能操作自己创建的课程
if (UserRole.ROLE_TEACHER.getValue().equals(userIdentity)) {
Course course = getCourseById(courseId);
if (course == null) {
throw new ServiceException("课程不存在");
}
// 通过teacherId查找对应的userId
Teacher teacher = teacherMapper.selectById(course.getTeacherId());
if (teacher == null || !currentUserId.equals(teacher.getUserId())) {
throw new ServiceException("无权限操作该课程");
}
}
}
}

@ -0,0 +1,221 @@
package yuxingshi.sms.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yuxingshi.sms.server.domain.dto.major.MajorManageDTO;
import yuxingshi.sms.server.domain.entity.Major;
import yuxingshi.sms.server.domain.entity.Student;
import yuxingshi.sms.server.domain.dto.major.MajorQueryReqDTO;
import yuxingshi.sms.server.domain.dto.major.MajorRespDTO;
import yuxingshi.sms.server.mapper.MajorMapper;
import yuxingshi.sms.server.mapper.StudentMapper;
import yuxingshi.sms.server.service.MajorService;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.exception.ServiceException;
import yuxingshi.sms.common.core.utils.StringUtil;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class MajorServiceImpl implements MajorService {
@Autowired
private MajorMapper majorMapper;
@Autowired
private StudentMapper studentMapper;
@Override
public String createMajor(MajorManageDTO dto) {
// 检查专业代码是否已存在
Major codeExist = getMajorByCodeInternal(dto.getMajorCode());
if (codeExist != null) {
throw new ServiceException("专业代码已存在");
}
Major major = new Major();
major.setMajorCode(dto.getMajorCode());
major.setMajorName(dto.getMajorName());
major.setDescription(dto.getDescription());
major.setStatus(1);
major.setCreatedTime(LocalDateTime.now());
major.setUpdatedTime(LocalDateTime.now());
majorMapper.insert(major);
log.info("创建专业成功: majorCode={}", dto.getMajorCode());
return major.getId();
}
@Override
public void updateMajor(String majorId, MajorManageDTO dto) {
Major major = getMajorByIdInternal(majorId);
if (major == null) {
throw new ServiceException("专业不存在");
}
// 检查专业代码是否被其他专业使用
if (!dto.getMajorCode().equals(major.getMajorCode())) {
Major codeExist = getMajorByCodeInternal(dto.getMajorCode());
if (codeExist != null) {
throw new ServiceException("专业代码已存在");
}
}
major.setMajorCode(dto.getMajorCode());
major.setMajorName(dto.getMajorName());
major.setDescription(dto.getDescription());
major.setUpdatedTime(LocalDateTime.now());
majorMapper.updateById(major);
log.info("更新专业成功: majorId={}", majorId);
}
@Override
public void deleteMajor(String majorId) {
Major major = getMajorByIdInternal(majorId);
if (major == null) {
throw new ServiceException("专业不存在");
}
// 检查专业是否有学生
LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Student::getMajorId, majorId);
long count = studentMapper.selectCount(queryWrapper);
if (count > 0) {
throw new ServiceException("专业中存在学生,无法删除");
}
majorMapper.deleteById(majorId);
log.info("删除专业成功: majorId={}", majorId);
}
@Override
public MajorRespDTO getMajorById(String majorId) {
Major major = getMajorByIdInternal(majorId);
if (major == null) {
return null;
}
return convertToRespDTO(major);
}
@Override
public MajorRespDTO getMajorByCode(String majorCode) {
Major major = getMajorByCodeInternal(majorCode);
if (major == null) {
return null;
}
return convertToRespDTO(major);
}
@Override
public void disableMajor(String majorId) {
Major major = getMajorByIdInternal(majorId);
if (major == null) {
throw new ServiceException("专业不存在");
}
LambdaUpdateWrapper<Major> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Major::getId, majorId)
.set(Major::getStatus, 0)
.set(Major::getUpdatedTime, LocalDateTime.now());
majorMapper.update(null, updateWrapper);
log.info("禁用专业成功: majorId={}", majorId);
}
@Override
public void enableMajor(String majorId) {
Major major = getMajorByIdInternal(majorId);
if (major == null) {
throw new ServiceException("专业不存在");
}
LambdaUpdateWrapper<Major> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Major::getId, majorId)
.set(Major::getStatus, 1)
.set(Major::getUpdatedTime, LocalDateTime.now());
majorMapper.update(null, updateWrapper);
log.info("启用专业成功: majorId={}", majorId);
}
@Override
public BasePageDTO<MajorRespDTO> queryMajors(MajorQueryReqDTO queryReq) {
LambdaQueryWrapper<Major> queryWrapper = new LambdaQueryWrapper<>();
// 根据专业名称模糊查询
if (StringUtil.isNotEmpty(queryReq.getMajorName())) {
queryWrapper.like(Major::getMajorName, queryReq.getMajorName());
}
// 根据专业代码模糊查询
if (StringUtil.isNotEmpty(queryReq.getMajorCode())) {
queryWrapper.like(Major::getMajorCode, queryReq.getMajorCode());
}
// 根据状态查询
if (queryReq.getStatus() != null) {
queryWrapper.eq(Major::getStatus, queryReq.getStatus());
}
// 按创建时间降序排序
queryWrapper.orderByDesc(Major::getCreatedTime);
// 使用MyBatisPlus分页插件
Page<Major> page = new Page<>(queryReq.getPageNo(), queryReq.getPageSize());
Page<Major> pageResult = majorMapper.selectPage(page, queryWrapper);
// 转换为DTO
List<MajorRespDTO> majorRespDTOs = pageResult.getRecords().stream()
.map(this::convertToRespDTO)
.collect(Collectors.toList());
return BasePageDTO.<MajorRespDTO>builder()
.list(majorRespDTOs)
.totals(pageResult.getTotal())
.totalPages(BasePageDTO.calculateTotalPages(pageResult.getTotal(), queryReq.getPageSize()))
.build();
}
/**
* ID
*/
private Major getMajorByIdInternal(String majorId) {
return majorMapper.selectById(majorId);
}
/**
*
*/
private Major getMajorByCodeInternal(String majorCode) {
LambdaQueryWrapper<Major> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Major::getMajorCode, majorCode);
return majorMapper.selectOne(queryWrapper);
}
/**
* DTO
*/
private MajorRespDTO convertToRespDTO(Major major) {
return MajorRespDTO.builder()
.id(major.getId())
.majorCode(major.getMajorCode())
.majorName(major.getMajorName())
.description(major.getDescription())
.status(major.getStatus())
.createdTime(major.getCreatedTime())
.updatedTime(major.getUpdatedTime())
.build();
}
}

@ -0,0 +1,264 @@
package yuxingshi.sms.server.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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 yuxingshi.sms.server.domain.entity.Teacher;
import yuxingshi.sms.server.domain.entity.User;
import yuxingshi.sms.server.domain.dto.teacher.TeacherManageDTO;
import yuxingshi.sms.server.domain.dto.teacher.TeacherQueryReqDTO;
import yuxingshi.sms.server.domain.dto.teacher.TeacherRespDTO;
import yuxingshi.sms.server.mapper.TeacherMapper;
import yuxingshi.sms.server.mapper.UserMapper;
import yuxingshi.sms.server.mapper.CourseMapper;
import yuxingshi.sms.server.service.TeacherService;
import yuxingshi.sms.server.utils.PasswordGeneratorUtil;
import yuxingshi.sms.common.core.domain.dto.BasePageDTO;
import yuxingshi.sms.common.core.domain.enums.UserStatus;
import yuxingshi.sms.common.core.exception.ServiceException;
import yuxingshi.sms.common.core.utils.StringUtil;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class TeacherServiceImpl implements TeacherService {
@Autowired
private TeacherMapper teacherMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private CourseMapper courseMapper;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
@Transactional
public String createTeacher(TeacherManageDTO dto) {
// 检查工号是否已存在
Teacher noExist = getTeacherByNo(dto.getTeacherNo());
if (noExist != null) {
throw new ServiceException("教师工号已存在");
}
// 生成随机密码
String randomPassword = PasswordGeneratorUtil.generatePassword();
// 创建用户账号
User user = new User();
user.setUsername(dto.getTeacherNo());
user.setPassword(passwordEncoder.encode(randomPassword));
user.setEmail(null);
user.setRole(3); // 教师角色
user.setStatus(UserStatus.ACTIVE.getValue());
user.setCreatedTime(LocalDateTime.now());
user.setUpdatedTime(LocalDateTime.now());
userMapper.insert(user);
// 创建教师信息
Teacher teacher = new Teacher();
teacher.setUserId(user.getId());
teacher.setTeacherNo(dto.getTeacherNo());
teacher.setRealName(dto.getRealName());
teacher.setDepartment(dto.getDepartment());
teacher.setPhone(dto.getPhone());
teacher.setStatus(1);
teacher.setCreatedTime(LocalDateTime.now());
teacher.setUpdatedTime(LocalDateTime.now());
teacherMapper.insert(teacher);
log.info("创建教师成功: teacherNo={}, realName={}, password={}", dto.getTeacherNo(), dto.getRealName(), randomPassword);
return teacher.getId();
}
@Override
@Transactional
public void updateTeacher(String teacherId, TeacherManageDTO dto) {
Teacher teacher = getTeacherById(teacherId);
if (teacher == null) {
throw new ServiceException("教师不存在");
}
// 检查工号是否被其他教师使用
if (!dto.getTeacherNo().equals(teacher.getTeacherNo())) {
Teacher noExist = getTeacherByNo(dto.getTeacherNo());
if (noExist != null) {
throw new ServiceException("教师工号已存在");
}
// 同步更新用户账号的username
if (teacher.getUserId() != null) {
LambdaUpdateWrapper<User> userUpdateWrapper = new LambdaUpdateWrapper<>();
userUpdateWrapper.eq(User::getId, teacher.getUserId())
.set(User::getUsername, dto.getTeacherNo())
.set(User::getUpdatedTime, LocalDateTime.now());
userMapper.update(null, userUpdateWrapper);
}
}
teacher.setTeacherNo(dto.getTeacherNo());
teacher.setRealName(dto.getRealName());
teacher.setDepartment(dto.getDepartment());
teacher.setPhone(dto.getPhone());
teacher.setUpdatedTime(LocalDateTime.now());
teacherMapper.updateById(teacher);
log.info("更新教师成功: teacherId={}", teacherId);
}
@Override
@Transactional
public void deleteTeacher(String teacherId) {
Teacher teacher = getTeacherById(teacherId);
if (teacher == null) {
throw new ServiceException("教师不存在");
}
// 检查是否有关联的课程
LambdaQueryWrapper<yuxingshi.sms.server.domain.entity.Course> courseQuery = new LambdaQueryWrapper<>();
courseQuery.eq(yuxingshi.sms.server.domain.entity.Course::getTeacherId, teacherId);
long courseCount = courseMapper.selectCount(courseQuery);
if (courseCount > 0) {
throw new ServiceException("教师关联了课程,无法删除。请先删除相关课程");
}
// 删除教师记录
teacherMapper.deleteById(teacherId);
// 删除关联的用户账号
if (teacher.getUserId() != null) {
userMapper.deleteById(teacher.getUserId());
log.info("删除教师关联用户账号: userId={}", teacher.getUserId());
}
log.info("删除教师成功: teacherId={}", teacherId);
}
@Override
public Teacher getTeacherById(String teacherId) {
return teacherMapper.selectById(teacherId);
}
@Override
public Teacher getTeacherByNo(String teacherNo) {
LambdaQueryWrapper<Teacher> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Teacher::getTeacherNo, teacherNo);
return teacherMapper.selectOne(queryWrapper);
}
@Override
@Transactional
public void disableTeacher(String teacherId) {
Teacher teacher = getTeacherById(teacherId);
if (teacher == null) {
throw new ServiceException("教师不存在");
}
// 更新教师状态
LambdaUpdateWrapper<Teacher> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Teacher::getId, teacherId)
.set(Teacher::getStatus, 0)
.set(Teacher::getUpdatedTime, LocalDateTime.now());
teacherMapper.update(null, updateWrapper);
// 同步禁用用户账号
if (teacher.getUserId() != null) {
LambdaUpdateWrapper<User> userUpdateWrapper = new LambdaUpdateWrapper<>();
userUpdateWrapper.eq(User::getId, teacher.getUserId())
.set(User::getStatus, UserStatus.DISABLED.getValue())
.set(User::getUpdatedTime, LocalDateTime.now());
userMapper.update(null, userUpdateWrapper);
}
log.info("禁用教师成功: teacherId={}", teacherId);
}
@Override
@Transactional
public void enableTeacher(String teacherId) {
Teacher teacher = getTeacherById(teacherId);
if (teacher == null) {
throw new ServiceException("教师不存在");
}
// 更新教师状态
LambdaUpdateWrapper<Teacher> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Teacher::getId, teacherId)
.set(Teacher::getStatus, 1)
.set(Teacher::getUpdatedTime, LocalDateTime.now());
teacherMapper.update(null, updateWrapper);
// 同步启用用户账号
if (teacher.getUserId() != null) {
LambdaUpdateWrapper<User> userUpdateWrapper = new LambdaUpdateWrapper<>();
userUpdateWrapper.eq(User::getId, teacher.getUserId())
.set(User::getStatus, UserStatus.ACTIVE.getValue())
.set(User::getUpdatedTime, LocalDateTime.now());
userMapper.update(null, userUpdateWrapper);
}
log.info("启用教师成功: teacherId={}", teacherId);
}
@Override
public BasePageDTO<TeacherRespDTO> queryTeachers(TeacherQueryReqDTO queryReq) {
LambdaQueryWrapper<Teacher> queryWrapper = new LambdaQueryWrapper<>();
// 根据工号模糊查询
if (StringUtil.isNotEmpty(queryReq.getTeacherNo())) {
queryWrapper.like(Teacher::getTeacherNo, queryReq.getTeacherNo());
}
// 根据真实姓名模糊查询
if (StringUtil.isNotEmpty(queryReq.getRealName())) {
queryWrapper.like(Teacher::getRealName, queryReq.getRealName());
}
// 根据部门查询
if (StringUtil.isNotEmpty(queryReq.getDepartment())) {
queryWrapper.eq(Teacher::getDepartment, queryReq.getDepartment());
}
// 根据状态查询
if (queryReq.getStatus() != null) {
queryWrapper.eq(Teacher::getStatus, queryReq.getStatus());
}
// 按创建时间降序排序
queryWrapper.orderByDesc(Teacher::getCreatedTime);
// 使用MyBatisPlus分页插件
Page<Teacher> page = new Page<>(queryReq.getPageNo(), queryReq.getPageSize());
Page<Teacher> pageResult = teacherMapper.selectPage(page, queryWrapper);
List<TeacherRespDTO> respList = pageResult.getRecords().stream()
.map(teacher -> TeacherRespDTO.builder()
.id(teacher.getId())
.teacherNo(teacher.getTeacherNo())
.realName(teacher.getRealName())
.department(teacher.getDepartment())
.phone(teacher.getPhone())
.status(teacher.getStatus())
.createdTime(teacher.getCreatedTime())
.updatedTime(teacher.getUpdatedTime())
.build())
.collect(Collectors.toList());
return BasePageDTO.<TeacherRespDTO>builder()
.list(respList)
.totals(pageResult.getTotal())
.totalPages(BasePageDTO.calculateTotalPages(pageResult.getTotal(), queryReq.getPageSize()))
.build();
}
}

@ -0,0 +1,68 @@
package yuxingshi.sms.server.utils;
import java.math.BigDecimal;
/**
*
* = *20% + *30% + *50%
*/
public class CourseScoreUtil {
private static final BigDecimal USUAL_WEIGHT = new BigDecimal("0.2");
private static final BigDecimal MIDTERM_WEIGHT = new BigDecimal("0.3");
private static final BigDecimal FINAL_WEIGHT = new BigDecimal("0.5");
/**
*
*
* @param usualScore
* @param midtermScore
* @param finalScore
* @return
*/
public static BigDecimal calculateTotalScore(BigDecimal usualScore, BigDecimal midtermScore, BigDecimal finalScore) {
if (usualScore == null || midtermScore == null || finalScore == null) {
return null;
}
BigDecimal totalScore = usualScore.multiply(USUAL_WEIGHT)
.add(midtermScore.multiply(MIDTERM_WEIGHT))
.add(finalScore.multiply(FINAL_WEIGHT));
// 四舍五入到2位小数
return totalScore.setScale(2, BigDecimal.ROUND_HALF_UP);
}
/**
*
*
* @param totalScore
* @return A/B/C/D/F
*/
public static String calculateGrade(BigDecimal totalScore) {
if (totalScore == null) {
return null;
}
if (totalScore.compareTo(new BigDecimal("90")) >= 0) {
return "A";
} else if (totalScore.compareTo(new BigDecimal("80")) >= 0) {
return "B";
} else if (totalScore.compareTo(new BigDecimal("70")) >= 0) {
return "C";
} else if (totalScore.compareTo(new BigDecimal("60")) >= 0) {
return "D";
} else {
return "F";
}
}
/**
* 0-100
*/
public static boolean isValidScore(BigDecimal score) {
if (score == null) {
return false;
}
return score.compareTo(BigDecimal.ZERO) >= 0 && score.compareTo(new BigDecimal("100")) <= 0;
}
}

@ -0,0 +1,64 @@
package yuxingshi.sms.server.utils;
import java.util.Random;
/**
*
*/
public class PasswordGeneratorUtil {
private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
private static final String DIGITS = "0123456789";
private static final String ALL_CHARS = UPPERCASE + LOWERCASE + DIGITS;
private static final int DEFAULT_LENGTH = 12;
private static final Random RANDOM = new Random();
/**
* 12
*
* @return
*/
public static String generatePassword() {
return generatePassword(DEFAULT_LENGTH);
}
/**
*
*
* @param length
* @return
*/
public static String generatePassword(int length) {
if (length < 6) {
length = 6;
}
StringBuilder password = new StringBuilder();
// 确保至少包含一个大写字母、一个小写字母和一个数字
password.append(UPPERCASE.charAt(RANDOM.nextInt(UPPERCASE.length())));
password.append(LOWERCASE.charAt(RANDOM.nextInt(LOWERCASE.length())));
password.append(DIGITS.charAt(RANDOM.nextInt(DIGITS.length())));
// 填充剩余位置
for (int i = password.length(); i < length; i++) {
password.append(ALL_CHARS.charAt(RANDOM.nextInt(ALL_CHARS.length())));
}
// 打乱顺序
return shufflePassword(password.toString());
}
/**
*
*/
private static String shufflePassword(String password) {
char[] chars = password.toCharArray();
for (int i = chars.length - 1; i > 0; i--) {
int j = RANDOM.nextInt(i + 1);
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
}
Loading…
Cancel
Save