diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index d58dfb7..0000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -wrapperVersion=3.3.2 -distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/pom.xml b/pom.xml index c8d1b31..e7cb5ba 100644 --- a/pom.xml +++ b/pom.xml @@ -5,18 +5,41 @@ org.springframework.boot spring-boot-starter-parent - 2.2.4.RELEASE + + 2.7.18 - com.bestsch.previewUnit - previewunit - 0.0.1-SNAPSHOT - previewunit + + BschClass + 0.1 + BschClass Demo project for Spring Boot 1.8 9.0.63 + + + + + + com.yunhai.platform + yh-platform-dependencies + 1.0.0-SNAPSHOT + pom + import + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + 2021.0.5.0 + pom + import + + + + org.springframework.boot @@ -30,21 +53,28 @@ org.projectlombok lombok + 1.18.36 true + + + + + mysql mysql-connector-java + 8.0.33 runtime - - com.bestsch - bsch-spring-boot-starter - 1.2.5-SNAPSHOT - + + + + + cn.hutool @@ -108,24 +138,10 @@ 20210307 - - - com.baidu.aip - java-sdk - 4.16.19 - - - - - ws.schild - jave-core - 2.4.6 - - com.squareup.okhttp3 okhttp - 4.10.0 + 3.14.9 @@ -136,7 +152,49 @@ 4.1.0 + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-aop + + + + + cn.afterturn + easypoi-spring-boot-starter + 4.2.0 + + + + + com.yunhai.platform + yh-auth-spring-boot-starter + + + com.yunhai.platform + yh-app-auth-spring-boot-starter + + + com.yunhai.platform + yh-openapi-spring-boot-starter + + + com.yunhai.platform + yh-api-std + + + + + org.jasig.cas.client + cas-client-core + 3.5.1 + @@ -149,4 +207,20 @@ + + + nexus-public + bsch/nexus public + http://nexus.yunhaixingtong.com/repository/maven-public/ + true + true + + + + diff --git a/sqlscript/dbschoolclass.sql b/sqlscript/dbschoolclass.sql new file mode 100644 index 0000000..a81a6fd --- /dev/null +++ b/sqlscript/dbschoolclass.sql @@ -0,0 +1,500 @@ +/* + Navicat Premium Data Transfer + + Source Server : 本地 + Source Server Type : MySQL + Source Server Version : 80044 + Source Host : localhost:3306 + Source Schema : dbschoolclass + + Target Server Type : MySQL + Target Server Version : 80044 + File Encoding : 65001 + + Date: 17/06/2026 10:30:52 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for base_dic_grade +-- ---------------------------- +DROP TABLE IF EXISTS `base_dic_grade`; +CREATE TABLE `base_dic_grade` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `code` int(0) NULL DEFAULT NULL COMMENT '年级编码', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '年级名称', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of base_dic_grade +-- ---------------------------- +INSERT INTO `base_dic_grade` VALUES (1, 1, '一年级'); +INSERT INTO `base_dic_grade` VALUES (2, 2, '二年级'); +INSERT INTO `base_dic_grade` VALUES (3, 3, '三年级'); +INSERT INTO `base_dic_grade` VALUES (4, 4, '四年级'); +INSERT INTO `base_dic_grade` VALUES (5, 5, '五年级'); +INSERT INTO `base_dic_grade` VALUES (6, 6, '六年级'); +INSERT INTO `base_dic_grade` VALUES (7, 7, '初一'); +INSERT INTO `base_dic_grade` VALUES (8, 8, '初二'); +INSERT INTO `base_dic_grade` VALUES (9, 9, '初三'); +INSERT INTO `base_dic_grade` VALUES (10, 10, '高一'); +INSERT INTO `base_dic_grade` VALUES (11, 11, '高二'); +INSERT INTO `base_dic_grade` VALUES (12, 12, '高三'); +INSERT INTO `base_dic_grade` VALUES (13, -4, '幼托'); +INSERT INTO `base_dic_grade` VALUES (14, -3, '幼小'); +INSERT INTO `base_dic_grade` VALUES (15, -2, '幼中'); +INSERT INTO `base_dic_grade` VALUES (16, -1, '幼大'); + +-- ---------------------------- +-- Table structure for base_dic_subject +-- ---------------------------- +DROP TABLE IF EXISTS `base_dic_subject`; +CREATE TABLE `base_dic_subject` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '编码', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '名称', + `sort` int(0) NULL DEFAULT NULL COMMENT '序号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of base_dic_subject +-- ---------------------------- +INSERT INTO `base_dic_subject` VALUES (1, 'SUB01', '语文', 1); +INSERT INTO `base_dic_subject` VALUES (2, 'SUB02', '数学', 2); +INSERT INTO `base_dic_subject` VALUES (3, 'SUB03', '英语', 3); +INSERT INTO `base_dic_subject` VALUES (4, 'SUB04', '物理', 4); +INSERT INTO `base_dic_subject` VALUES (5, 'SUB05', '化学', 5); +INSERT INTO `base_dic_subject` VALUES (6, 'SUB06', '生物', 6); +INSERT INTO `base_dic_subject` VALUES (7, 'SUB07', '历史', 7); +INSERT INTO `base_dic_subject` VALUES (8, 'SUB08', '地理', 8); +INSERT INTO `base_dic_subject` VALUES (9, 'SUB09', '政治', 9); +INSERT INTO `base_dic_subject` VALUES (10, 'SUB10', '艺术', 10); +INSERT INTO `base_dic_subject` VALUES (11, 'SUB11', '体育', 11); +INSERT INTO `base_dic_subject` VALUES (12, 'SUB12', '心理', 12); +INSERT INTO `base_dic_subject` VALUES (13, 'SUB13', '信息', 13); +INSERT INTO `base_dic_subject` VALUES (14, 'SUB14', '劳技', 14); +INSERT INTO `base_dic_subject` VALUES (15, 'SUB15', '跨学科', 15); +INSERT INTO `base_dic_subject` VALUES (16, 'SUB16', '美术', 16); +INSERT INTO `base_dic_subject` VALUES (17, 'SUB17', '音乐', 17); + +-- ---------------------------- +-- Table structure for base_sch_system +-- ---------------------------- +DROP TABLE IF EXISTS `base_sch_system`; +CREATE TABLE `base_sch_system` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称 ', + `academic_stage` int(0) NULL DEFAULT NULL COMMENT '学段(0学前 1小学 2初中 3高中 4高等)', + `start_grade_code` int(0) NULL DEFAULT NULL COMMENT '开班年级编码', + `end_grade_code` int(0) NULL DEFAULT NULL COMMENT '毕业年级编码', + `graduation_leng` int(0) NULL DEFAULT NULL COMMENT '毕业年长度', + `type` int(0) NULL DEFAULT NULL COMMENT '类型(1学前教育 2职业教育)', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of base_sch_system +-- ---------------------------- +INSERT INTO `base_sch_system` VALUES (1, '学前教育', 0, -3, -1, 3, 1); +INSERT INTO `base_sch_system` VALUES (2, '学前4年', 0, -4, -1, 4, 1); +INSERT INTO `base_sch_system` VALUES (3, '小学六年', 1, 1, 6, 6, 1); +INSERT INTO `base_sch_system` VALUES (4, '小学五年', 1, 1, 5, 5, 1); +INSERT INTO `base_sch_system` VALUES (5, '初中三年', 2, 7, 9, 3, 1); +INSERT INTO `base_sch_system` VALUES (6, '初中四年', 2, 6, 9, 4, 1); +INSERT INTO `base_sch_system` VALUES (7, '九年一贯制', 2, 1, 9, 9, 1); +INSERT INTO `base_sch_system` VALUES (8, '高中三年', 3, 10, 12, 3, 1); +INSERT INTO `base_sch_system` VALUES (9, '初高中七年制', 3, 6, 12, 7, 1); +INSERT INTO `base_sch_system` VALUES (10, '职高', 3, 0, 0, 3, 2); +INSERT INTO `base_sch_system` VALUES (11, '\r\n专科三年制', 4, 0, 0, 3, 2); +INSERT INTO `base_sch_system` VALUES (12, '\r\n专科五年制', 4, 0, 0, 5, 2); + +-- ---------------------------- +-- Table structure for base_sch_system_grade +-- ---------------------------- +DROP TABLE IF EXISTS `base_sch_system_grade`; +CREATE TABLE `base_sch_system_grade` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `grade_id` int(0) NULL DEFAULT NULL COMMENT '年级id', + `grade_nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '年级别名', + `sch_system_id` int(0) NULL DEFAULT NULL COMMENT '学制id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of base_sch_system_grade +-- ---------------------------- +INSERT INTO `base_sch_system_grade` VALUES (1, -3, '幼小', 1); +INSERT INTO `base_sch_system_grade` VALUES (2, -2, '幼中', 1); +INSERT INTO `base_sch_system_grade` VALUES (3, -1, '幼大', 1); +INSERT INTO `base_sch_system_grade` VALUES (4, -4, '幼托', 2); +INSERT INTO `base_sch_system_grade` VALUES (5, -3, '幼小', 2); +INSERT INTO `base_sch_system_grade` VALUES (6, -2, '幼中', 2); +INSERT INTO `base_sch_system_grade` VALUES (7, -1, '幼大', 2); +INSERT INTO `base_sch_system_grade` VALUES (8, 1, '小一', 3); +INSERT INTO `base_sch_system_grade` VALUES (9, 2, '小二', 3); +INSERT INTO `base_sch_system_grade` VALUES (10, 3, '小三', 3); +INSERT INTO `base_sch_system_grade` VALUES (11, 4, '小四', 3); +INSERT INTO `base_sch_system_grade` VALUES (12, 5, '小五', 3); +INSERT INTO `base_sch_system_grade` VALUES (13, 6, '小六', 3); +INSERT INTO `base_sch_system_grade` VALUES (14, 1, '小一', 4); +INSERT INTO `base_sch_system_grade` VALUES (15, 2, '小二', 4); +INSERT INTO `base_sch_system_grade` VALUES (16, 3, '小三', 4); +INSERT INTO `base_sch_system_grade` VALUES (17, 4, '小四', 4); +INSERT INTO `base_sch_system_grade` VALUES (18, 5, '小五', 4); +INSERT INTO `base_sch_system_grade` VALUES (19, 7, '初一', 5); +INSERT INTO `base_sch_system_grade` VALUES (20, 8, '初二', 5); +INSERT INTO `base_sch_system_grade` VALUES (21, 9, '初三', 5); +INSERT INTO `base_sch_system_grade` VALUES (22, 6, '预备', 6); +INSERT INTO `base_sch_system_grade` VALUES (23, 7, '初一', 6); +INSERT INTO `base_sch_system_grade` VALUES (24, 8, '初二', 6); +INSERT INTO `base_sch_system_grade` VALUES (25, 9, '初三', 6); +INSERT INTO `base_sch_system_grade` VALUES (26, 1, '小一', 7); +INSERT INTO `base_sch_system_grade` VALUES (27, 2, '小二', 7); +INSERT INTO `base_sch_system_grade` VALUES (28, 3, '小三', 7); +INSERT INTO `base_sch_system_grade` VALUES (29, 4, '小四', 7); +INSERT INTO `base_sch_system_grade` VALUES (30, 5, '小五', 7); +INSERT INTO `base_sch_system_grade` VALUES (31, 6, '小六', 7); +INSERT INTO `base_sch_system_grade` VALUES (32, 7, '初一', 7); +INSERT INTO `base_sch_system_grade` VALUES (33, 8, '初二', 7); +INSERT INTO `base_sch_system_grade` VALUES (34, 9, '初三', 7); +INSERT INTO `base_sch_system_grade` VALUES (35, 10, '高一', 8); +INSERT INTO `base_sch_system_grade` VALUES (36, 11, '高二', 8); +INSERT INTO `base_sch_system_grade` VALUES (37, 12, '高三', 8); +INSERT INTO `base_sch_system_grade` VALUES (38, 6, '预备', 9); +INSERT INTO `base_sch_system_grade` VALUES (39, 7, '初一', 9); +INSERT INTO `base_sch_system_grade` VALUES (40, 8, '初二', 9); +INSERT INTO `base_sch_system_grade` VALUES (41, 9, '初三', 9); +INSERT INTO `base_sch_system_grade` VALUES (42, 10, '高一', 9); +INSERT INTO `base_sch_system_grade` VALUES (43, 11, '高二', 9); +INSERT INTO `base_sch_system_grade` VALUES (44, 12, '高三', 9); + +-- ---------------------------- +-- Table structure for base_year_term +-- ---------------------------- +DROP TABLE IF EXISTS `base_year_term`; +CREATE TABLE `base_year_term` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `year` int(0) NULL DEFAULT NULL COMMENT '学年', + `year_start_date` date NULL DEFAULT NULL COMMENT '学年开始日期', + `year_end_date` date NULL DEFAULT NULL COMMENT '学年结束日期', + `first_term_start_date` date NULL DEFAULT NULL COMMENT '第一学期开始日期', + `first_term_end_date` date NULL DEFAULT NULL COMMENT '第一学期结束日期', + `second_term_start_date` date NOT NULL COMMENT '第二学期开始日期', + `second_term_end_date` date NULL DEFAULT NULL COMMENT '第二学期结束日期', + `upgrade_date` date NULL DEFAULT NULL COMMENT '毕业时间', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`, `second_term_start_date`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of base_year_term +-- ---------------------------- +INSERT INTO `base_year_term` VALUES (1, 2025, '2025-09-01', '2026-07-10', '2025-09-01', '2026-01-15', '2026-02-20', '2026-07-05', '2026-07-15', '2026-06-15 10:11:06', NULL, 100000, NULL); +INSERT INTO `base_year_term` VALUES (2, 2024, '2024-09-01', '2025-07-10', '2024-09-01', '2025-01-15', '2025-02-20', '2025-07-05', '2025-07-15', '2026-06-15 10:19:53', NULL, 100000, NULL); +INSERT INTO `base_year_term` VALUES (3, 2023, '2023-09-01', '2024-07-10', '2023-09-01', '2024-01-15', '2024-02-20', '2024-07-05', '2024-07-15', '2026-06-15 10:20:58', NULL, 100000, NULL); +INSERT INTO `base_year_term` VALUES (4, 2022, '2022-09-01', '2023-07-10', '2022-09-01', '2023-01-15', '2023-02-20', '2023-07-05', '2023-07-15', '2026-06-15 10:21:51', NULL, 100000, NULL); +INSERT INTO `base_year_term` VALUES (5, 2021, '2021-09-01', '2022-07-10', '2021-09-01', '2022-01-15', '2022-02-20', '2022-07-05', '2022-07-15', '2026-06-15 10:22:00', NULL, 100000, NULL); +INSERT INTO `base_year_term` VALUES (6, 2020, '2020-09-01', '2021-07-10', '2020-09-01', '2021-01-15', '2021-02-20', '2021-07-05', '2021-07-15', '2026-06-15 10:23:22', NULL, 100000, NULL); + +-- ---------------------------- +-- Table structure for sch_bin_sch_system +-- ---------------------------- +DROP TABLE IF EXISTS `sch_bin_sch_system`; +CREATE TABLE `sch_bin_sch_system` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `sch_system_id` int(0) NOT NULL COMMENT '学制id', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改日期', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_bin_sch_system +-- ---------------------------- +INSERT INTO `sch_bin_sch_system` VALUES (5, 6, 3260, '2026-06-11 15:21:34', 100000, '2026-06-11 15:21:34', 100000); +INSERT INTO `sch_bin_sch_system` VALUES (6, 8, 3260, '2026-06-11 15:21:34', 100000, '2026-06-11 15:21:34', 100000); + +-- ---------------------------- +-- Table structure for sch_class +-- ---------------------------- +DROP TABLE IF EXISTS `sch_class`; +CREATE TABLE `sch_class` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `code` int(10) UNSIGNED ZEROFILL NULL DEFAULT NULL COMMENT '编码', + `grade_id` int(0) NULL DEFAULT NULL COMMENT '年级id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '名称', + `cname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '别称', + `group_class_id` int(0) UNSIGNED NOT NULL COMMENT '班级组id', + `group_grade_id` int(0) NOT NULL COMMENT '年级组id', + `first_teacher_id` int(0) NULL DEFAULT NULL COMMENT '班主任', + `second_teacher_id` int(0) NULL DEFAULT NULL COMMENT '副班主任', + `campus_id` int(0) NULL DEFAULT NULL COMMENT '校区', + `division_id` int(0) NULL DEFAULT NULL COMMENT '系部', + `majors_id` int(0) NULL DEFAULT NULL COMMENT '专业', + `graduate` bit(1) NULL DEFAULT NULL COMMENT '毕业', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sch_class_teach +-- ---------------------------- +DROP TABLE IF EXISTS `sch_class_teach`; +CREATE TABLE `sch_class_teach` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `grade_id` int(0) NULL DEFAULT NULL COMMENT '年级id', + `class_id` int(0) NULL DEFAULT NULL COMMENT '班级id', + `sub_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学科id', + `tea_id` int(0) NULL DEFAULT NULL COMMENT '教师id', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sch_dic_campus +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_campus`; +CREATE TABLE `sch_dic_campus` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '校区', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `sort` int(0) NULL DEFAULT NULL COMMENT '序号', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '编辑日期', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '编辑用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_campus +-- ---------------------------- +INSERT INTO `sch_dic_campus` VALUES (1, '新渔区', 3260, 2, '2026-06-16 10:06:49', 209169, '2026-06-16 10:10:47', 209169); +INSERT INTO `sch_dic_campus` VALUES (2, '名宿区', 3260, 1, '2026-06-16 10:08:08', 209169, '2026-06-16 10:10:47', 209169); + +-- ---------------------------- +-- Table structure for sch_dic_course +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_course`; +CREATE TABLE `sch_dic_course` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '编码', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '课程名称', + `nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '别名', + `type` int(0) NULL DEFAULT NULL COMMENT '类型(1基础课程 2选修课程 3专业课程)', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_course +-- ---------------------------- +INSERT INTO `sch_dic_course` VALUES (1, 'MATH101', '高等数学', '高数', 3, 3260, '2026-06-16 22:11:35', '2026-06-17 00:40:54', 209169, 209169); +INSERT INTO `sch_dic_course` VALUES (2, 'MATH102', '就业指导', NULL, 1, 3260, '2026-06-16 22:29:21', '2026-06-17 00:39:55', 209169, 209169); +INSERT INTO `sch_dic_course` VALUES (3, 'MATH103', '中餐冷菜制作', NULL, 2, 3260, '2026-06-16 22:30:02', '2026-06-17 00:39:15', 209169, 209169); +INSERT INTO `sch_dic_course` VALUES (4, NULL, '计算机应用基础', NULL, 1, 3260, '2026-06-16 22:30:17', '2026-06-16 22:30:17', 209169, 209169); + +-- ---------------------------- +-- Table structure for sch_dic_course_division +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_course_division`; +CREATE TABLE `sch_dic_course_division` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `course_id` int(0) NULL DEFAULT NULL, + `division_id` int(0) NULL DEFAULT NULL, + `sch_id` int(0) NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_course_division +-- ---------------------------- +INSERT INTO `sch_dic_course_division` VALUES (3, 3, 5, 3260); +INSERT INTO `sch_dic_course_division` VALUES (4, 3, 6, 3260); +INSERT INTO `sch_dic_course_division` VALUES (5, 2, 3, 3260); +INSERT INTO `sch_dic_course_division` VALUES (6, 2, 4, 3260); +INSERT INTO `sch_dic_course_division` VALUES (9, 1, 1, 3260); +INSERT INTO `sch_dic_course_division` VALUES (10, 1, 2, 3260); + +-- ---------------------------- +-- Table structure for sch_dic_course_majors +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_course_majors`; +CREATE TABLE `sch_dic_course_majors` ( + `id` int(0) NOT NULL AUTO_INCREMENT, + `course_id` int(0) NULL DEFAULT NULL, + `majors_id` int(0) NULL DEFAULT NULL, + `sch_id` int(0) NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_course_majors +-- ---------------------------- +INSERT INTO `sch_dic_course_majors` VALUES (2, 3, 4, 3260); +INSERT INTO `sch_dic_course_majors` VALUES (3, 2, 2, 3260); +INSERT INTO `sch_dic_course_majors` VALUES (6, 1, 1, 3260); +INSERT INTO `sch_dic_course_majors` VALUES (7, 1, 5, 3260); + +-- ---------------------------- +-- Table structure for sch_dic_division +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_division`; +CREATE TABLE `sch_dic_division` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '系部', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `sort` int(0) NULL DEFAULT NULL COMMENT '序号', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '修改日期', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_division +-- ---------------------------- +INSERT INTO `sch_dic_division` VALUES (1, '中文系', 3260, 6, '2026-06-16 10:33:45', 209169, '2026-06-16 10:41:12', 209169); +INSERT INTO `sch_dic_division` VALUES (2, '历史系', 3260, 5, '2026-06-16 10:34:02', 209169, '2026-06-16 10:41:12', 209169); +INSERT INTO `sch_dic_division` VALUES (3, '外国语学院', 3260, 4, '2026-06-16 10:34:23', 209169, '2026-06-16 10:41:12', 209169); +INSERT INTO `sch_dic_division` VALUES (4, '新闻传播学院', 3260, 3, '2026-06-16 10:34:32', 209169, '2026-06-16 10:41:12', 209169); +INSERT INTO `sch_dic_division` VALUES (5, '哲学系', 3260, 2, '2026-06-16 10:34:41', 209169, '2026-06-16 10:41:12', 209169); +INSERT INTO `sch_dic_division` VALUES (6, '经济学院', 3260, 1, '2026-06-16 10:34:49', 209169, '2026-06-16 10:41:12', 209169); + +-- ---------------------------- +-- Table structure for sch_dic_majors +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_majors`; +CREATE TABLE `sch_dic_majors` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '专业 ', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `sort` int(0) NULL DEFAULT NULL COMMENT '序号', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_majors +-- ---------------------------- +INSERT INTO `sch_dic_majors` VALUES (1, '哲学', 3260, 7, '2026-06-16 16:23:06', '2026-06-16 16:25:13', 209169, 209169); +INSERT INTO `sch_dic_majors` VALUES (2, '逻辑学', 3260, 6, '2026-06-16 16:23:31', '2026-06-16 16:25:13', 209169, 209169); +INSERT INTO `sch_dic_majors` VALUES (3, '宗教学', 3260, 5, '2026-06-16 16:23:44', '2026-06-16 16:25:13', 209169, 209169); +INSERT INTO `sch_dic_majors` VALUES (4, '经济学', 3260, 4, '2026-06-16 16:23:59', '2026-06-16 16:25:13', 209169, 209169); +INSERT INTO `sch_dic_majors` VALUES (5, '经济统计学', 3260, 3, '2026-06-16 16:24:12', '2026-06-16 16:25:13', 209169, 209169); +INSERT INTO `sch_dic_majors` VALUES (6, '法学', 3260, 2, '2026-06-16 16:24:24', '2026-06-16 16:25:13', 209169, 209169); +INSERT INTO `sch_dic_majors` VALUES (7, '新闻学', 3260, 1, '2026-06-16 16:24:38', '2026-06-16 16:25:13', 209169, 209169); + +-- ---------------------------- +-- Table structure for sch_dic_subject +-- ---------------------------- +DROP TABLE IF EXISTS `sch_dic_subject`; +CREATE TABLE `sch_dic_subject` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '编码', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '学科', + `enable` bit(1) NULL DEFAULT NULL COMMENT '是否启用', + `sort` int(0) NULL DEFAULT NULL COMMENT '序号', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建日期', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改日期', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + `source` int(0) NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 42 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sch_dic_subject +-- ---------------------------- +INSERT INTO `sch_dic_subject` VALUES (5, 'SUB1001', '机器人', b'1', 1, 3260, '2026-06-15 18:00:05', '2026-06-15 22:23:27', 209169, 209169, 1); +INSERT INTO `sch_dic_subject` VALUES (6, 'SUB1002', 'AI', b'1', 2, 3260, '2026-06-15 18:50:10', '2026-06-15 22:22:41', 209169, 209169, 1); +INSERT INTO `sch_dic_subject` VALUES (7, 'SUB01', '语文', b'0', 3, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (26, 'SUB02', '数学', b'0', 4, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (27, 'SUB03', '英语', b'0', 5, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (28, 'SUB04', '物理', b'0', 6, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (29, 'SUB05', '化学', b'0', 7, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (30, 'SUB06', '生物', b'0', 8, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (31, 'SUB07', '历史', b'0', 9, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (32, 'SUB08', '地理', b'0', 10, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (33, 'SUB09', '政治', b'0', 11, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (34, 'SUB10', '艺术', b'0', 12, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (35, 'SUB11', '体育', b'0', 13, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (36, 'SUB12', '心理', b'0', 14, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (37, 'SUB13', '信息', b'0', 15, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (38, 'SUB14', '劳技', b'0', 16, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (39, 'SUB15', '跨学科', b'0', 17, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (40, 'SUB16', '美术', b'0', 18, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); +INSERT INTO `sch_dic_subject` VALUES (41, 'SUB17', '音乐', b'0', 19, 3260, '2026-06-15 22:04:42', '2026-06-15 22:22:41', 209169, 209169, 0); + +-- ---------------------------- +-- Table structure for sch_student +-- ---------------------------- +DROP TABLE IF EXISTS `sch_student`; +CREATE TABLE `sch_student` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '账户', + `group_id` int(0) NULL DEFAULT NULL COMMENT '组id', + `class_id` int(0) NULL DEFAULT NULL COMMENT '班级id', + `stu_id` int(0) NOT NULL COMMENT '学生id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生', + `gender` int(0) NULL DEFAULT NULL COMMENT '性别', + `status` int(0) NULL DEFAULT NULL COMMENT '状态', + `abnormal_status` int(0) NULL DEFAULT NULL COMMENT '异常状态', + `invitation_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邀请码', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sch_teacher +-- ---------------------------- +DROP TABLE IF EXISTS `sch_teacher`; +CREATE TABLE `sch_teacher` ( + `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '账户', + `group_id` int(0) NULL DEFAULT NULL COMMENT '组id', + `tea_id` int(0) NOT NULL COMMENT '教师id', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '教师', + `tel` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系电话', + `gender` int(0) NULL DEFAULT NULL COMMENT '性别 0女 1男', + `status` int(0) NULL DEFAULT NULL COMMENT '状态 (0 禁用 1正常)', + `sch_id` int(0) NULL DEFAULT NULL COMMENT '学校id', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', + `create_user_id` int(0) NULL DEFAULT NULL COMMENT '创建用户', + `update_user_id` int(0) NULL DEFAULT NULL COMMENT '修改用户', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/sqlscript/创建时间用户字段.sql b/sqlscript/创建时间用户字段.sql new file mode 100644 index 0000000..73ba732 --- /dev/null +++ b/sqlscript/创建时间用户字段.sql @@ -0,0 +1,5 @@ +ALTER TABLE `dbschoolclass`.`sch_dic_campus` +ADD COLUMN `create_date` datetime(0) NULL COMMENT '创建时间' AFTER `sch_id`, +ADD COLUMN `update_date` datetime(0) NULL COMMENT '修改时间' AFTER `create_date`, +ADD COLUMN `create_user_id` int(0) NULL COMMENT '创建用户' AFTER `update_date`, +ADD COLUMN `update_user_id` int(0) NULL COMMENT '修改用户' AFTER `create_user_id`; \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java b/src/main/java/com/bestsch/bschclassmanage/ClassicalchineseApplication.java similarity index 72% rename from src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java rename to src/main/java/com/bestsch/bschclassmanage/ClassicalchineseApplication.java index f9e902d..9964bd2 100644 --- a/src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java +++ b/src/main/java/com/bestsch/bschclassmanage/ClassicalchineseApplication.java @@ -1,17 +1,15 @@ -package com.bestsch.classicalchinese; +package com.bestsch.bschclassmanage; -import com.bestsch.bschapistd.config.EnableBschApiStd; -import com.bestsch.bschsso.EnableBschSso; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication @EnableTransactionManagement @EnableAsync -@EnableBschSso //用户中心接口 -@EnableBschApiStd +@EnableScheduling public class ClassicalchineseApplication { public static void main(String[] args) { diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/BaseDicGradeRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseDicGradeRepository.java new file mode 100644 index 0000000..0eee868 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseDicGradeRepository.java @@ -0,0 +1,11 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface BaseDicGradeRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/BaseDicSubjectRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseDicSubjectRepository.java new file mode 100644 index 0000000..e6bc2c6 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseDicSubjectRepository.java @@ -0,0 +1,11 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.BaseDicSubject; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface BaseDicSubjectRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/BaseSchsystemGradeRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseSchsystemGradeRepository.java new file mode 100644 index 0000000..5766237 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseSchsystemGradeRepository.java @@ -0,0 +1,17 @@ +package com.bestsch.bschclassmanage.Repository; + + +import com.bestsch.bschclassmanage.entity.BaseSchsystemGrade; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface BaseSchsystemGradeRepository extends JpaRepository, JpaSpecificationExecutor { + + List findBySchSystemId(Integer schSystemId); + + List findBySchSystemIdIn(List schSystemIds); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/BaseSchsystemRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseSchsystemRepository.java new file mode 100644 index 0000000..0598b0a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseSchsystemRepository.java @@ -0,0 +1,11 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.BaseSchsystem; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface BaseSchsystemRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/BaseYearTermRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseYearTermRepository.java new file mode 100644 index 0000000..2529295 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/BaseYearTermRepository.java @@ -0,0 +1,11 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.BaseYearTerm; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface BaseYearTermRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/OperationLogRecordRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/OperationLogRecordRepository.java new file mode 100644 index 0000000..75c046d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/OperationLogRecordRepository.java @@ -0,0 +1,14 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface OperationLogRecordRepository extends JpaRepository, JpaSpecificationExecutor { + Page findByModule(String module, Pageable pageable); + Page findAllByOrderByOperateTimeDesc(Pageable pageable); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchBinSchsystemRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchBinSchsystemRepository.java new file mode 100644 index 0000000..dd297f5 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchBinSchsystemRepository.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.Repository; + + +import com.bestsch.bschclassmanage.entity.BaseSchsystemGrade; +import com.bestsch.bschclassmanage.entity.SchBinSchsystem; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface SchBinSchsystemRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassHistoryRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassHistoryRepository.java new file mode 100644 index 0000000..5c6cd84 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassHistoryRepository.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchClassHistory; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchClassHistoryRepository extends JpaRepository, JpaSpecificationExecutor { + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassRepository.java new file mode 100644 index 0000000..42fa755 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassRepository.java @@ -0,0 +1,69 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchClass; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchClassRepository extends JpaRepository, JpaSpecificationExecutor { + + Optional findByIdAndSchId(Integer Id, Integer schId); + + Optional findByClassIdAndSchId(Integer classId, Integer schId); + + @Query(value = "SELECT MAX(sort) FROM sch_class WHERE grade_id = :gradeId AND sch_id = :schId AND graduate = 0", nativeQuery = true) + Integer findMaxCodeNumber(@Param("gradeId") Integer gradeId, @Param("schId") Integer schId); + + @Query("SELECT c FROM SchClass c " + + "WHERE c.schId = :schId " + + "AND (:campusId IS NULL OR c.campusId = :campusId) " + + "AND (:divisionId IS NULL OR c.divisionId = :divisionId) " + + "AND (:majorsId IS NULL OR c.majorsId = :majorsId) " + + "AND (:years IS NULL OR c.enrollYear IN :years)"+ + "AND c.enrollYear = c.gradeId AND c.graduate = 0") + Page findClassesByConditions(@Param("schId") Integer schId, + @Param("campusId") Integer campusId, + @Param("divisionId") Integer divisionId, + @Param("majorsId") Integer majorsId, + @Param("years") List years, + Pageable pageable); + + boolean existsBySchIdAndGroupIdAndName(Integer schId, Integer groupId, String name); + + boolean existsBySchIdAndGroupIdAndNameAndIdNot(Integer schId, Integer groupId, String name, Integer id); + + long countByFirstTeacherIdOrSecondTeacherId(Integer firstTeacherId, Integer secondTeacherId); + + long countByCampusId(Integer campusId); + + long countByDivisionId(Integer divisionId); + + long countByMajorsId(Integer majorsId); + + List findBySchIdAndEnrollYear(Integer schId, Integer enrollYear); + + boolean existsBySchIdAndClassId(Integer schId, Integer classId); + + @Query("SELECT COUNT(c) FROM SchClass c WHERE (c.firstTeacherId IN (:ids) OR c.secondTeacherId IN (:ids)) AND c.schId = :schId AND c.graduate = 0") + long countByFirstTeacherIdInOrSecondTeacherIdInAndSchId( + @Param("ids") List ids, + @Param("schId") Integer schId + ); + + /** + * 根据学校ID和年级ID列表,查询最小的注册年份 + * @param schId 学校ID + * @param gradeIds 年级ID列表(可为空) + * @return 最小注册年份,如果没有匹配记录则返回 null + */ + @Query("SELECT MIN(c.enrollYear) FROM SchClass c WHERE c.schId = :schId AND c.gradeId IN :gradeIds") + Integer findMinEnrollYear(@Param("schId") Integer schId, @Param("gradeIds") List gradeIds); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassTeachHistoryRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassTeachHistoryRepository.java new file mode 100644 index 0000000..d2d6512 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassTeachHistoryRepository.java @@ -0,0 +1,12 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.entity.SchClassTeachHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface SchClassTeachHistoryRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassTeachRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassTeachRepository.java new file mode 100644 index 0000000..f080e11 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchClassTeachRepository.java @@ -0,0 +1,23 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchClassTeachRepository extends JpaRepository, JpaSpecificationExecutor { + + + List findBySchIdAndClassIdIn(Integer schId, List classIds); + + Optional findBySchIdAndClassIdAndSubId(Integer schId, Integer classId, String subId); + + Optional findBySchIdAndId(Integer schId, Integer id); + + List findBySchIdAndClassId(Integer schId, Integer classId); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCampusRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCampusRepository.java new file mode 100644 index 0000000..3cecc71 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCampusRepository.java @@ -0,0 +1,23 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchDicCampus; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchDicCampusRepository extends JpaRepository, JpaSpecificationExecutor { + + boolean existsBySchIdAndName(Integer schId, String name); + + boolean existsBySchIdAndNameAndIdNot(Integer schId, String name, Integer id); + + Optional findByIdAndSchId(Integer Id, Integer schId); + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseDivisionRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseDivisionRepository.java new file mode 100644 index 0000000..1a47856 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseDivisionRepository.java @@ -0,0 +1,27 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchDicCourseDivision; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchDicCourseDivisionRepository extends JpaRepository, JpaSpecificationExecutor { + + List findByCourseIdAndSchId(Integer courseId, Integer schId); + + /** + * 根据课程 ID 列表和学校 ID 批量查询关联的学部关系 + * @param courseIds 课程 ID 列表 + * @param schId 学校 ID + * @return 匹配的关联关系列表 + */ + List findByCourseIdInAndSchId(List courseIds, Integer schId); + + void deleteByCourseIdAndSchId(Integer courseId, Integer schId); + + Optional findByIdAndSchId(Integer Id, Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseMajorsRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseMajorsRepository.java new file mode 100644 index 0000000..1b7da74 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseMajorsRepository.java @@ -0,0 +1,27 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchDicCourseMajors; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchDicCourseMajorsRepository extends JpaRepository, JpaSpecificationExecutor { + + List findByCourseIdAndSchId(Integer courseId, Integer schId); + + /** + * 根据课程 ID 列表和学校 ID 批量查询关联的学部关系 + * @param courseIds 课程 ID 列表 + * @param schId 学校 ID + * @return 匹配的关联关系列表 + */ + List findByCourseIdInAndSchId(List courseIds, Integer schId); + + void deleteByCourseIdAndSchId(Integer courseId, Integer schId); + + Optional findByIdAndSchId(Integer Id, Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseRepository.java new file mode 100644 index 0000000..fcabe0a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicCourseRepository.java @@ -0,0 +1,45 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchDicCampus; +import com.bestsch.bschclassmanage.entity.SchDicCourse; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchDicCourseRepository extends JpaRepository, JpaSpecificationExecutor { + boolean existsBySchIdAndName(Integer schId, String name); + boolean existsBySchIdAndNameAndIdNot(Integer schId, String name, Integer id); + Optional findByIdAndSchId(Integer Id, Integer schId); + @Query(value = "SELECT c FROM SchDicCourse c " + + "WHERE c.schId = :schId " + + "AND (:type IS NULL OR c.type = :type) " + + "AND (:keyword IS NULL OR (c.name LIKE CONCAT('%', :keyword, '%') " + + " OR c.nickname LIKE CONCAT('%', :keyword, '%') " + + " OR c.code LIKE CONCAT('%', :keyword, '%'))) " + + "AND (:divisionId IS NULL OR EXISTS (SELECT 1 FROM SchDicCourseDivision d WHERE d.courseId = c.id AND d.divisionId = :divisionId)) " + + "AND (:majorsId IS NULL OR EXISTS (SELECT 1 FROM SchDicCourseMajors m WHERE m.courseId = c.id AND m.majorsId = :majorsId))", + countQuery = "SELECT COUNT(c) FROM SchDicCourse c " + + "WHERE c.schId = :schId " + + "AND (:type IS NULL OR c.type = :type) " + + "AND (:keyword IS NULL OR (c.name LIKE CONCAT('%', :keyword, '%') " + + " OR c.nickname LIKE CONCAT('%', :keyword, '%') " + + " OR c.code LIKE CONCAT('%', :keyword, '%'))) " + + "AND (:divisionId IS NULL OR EXISTS (SELECT 1 FROM SchDicCourseDivision d WHERE d.courseId = c.id AND d.divisionId = :divisionId)) " + + "AND (:majorsId IS NULL OR EXISTS (SELECT 1 FROM SchDicCourseMajors m WHERE m.courseId = c.id AND m.majorsId = :majorsId))") + Page findCoursesByConditions(@Param("schId") Integer schId, + @Param("type") Integer type, + @Param("keyword") String keyword, + @Param("divisionId") Integer divisionId, + @Param("majorsId") Integer majorsId, + Pageable pageable); + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicDivisionRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicDivisionRepository.java new file mode 100644 index 0000000..bdcd56f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicDivisionRepository.java @@ -0,0 +1,15 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchDicDivision; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchDicDivisionRepository extends JpaRepository, JpaSpecificationExecutor { + boolean existsBySchIdAndName(Integer schId, String name); + boolean existsBySchIdAndNameAndIdNot(Integer schId, String name, Integer id); + Optional findByIdAndSchId(Integer Id, Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicMajorsRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicMajorsRepository.java new file mode 100644 index 0000000..d5395ed --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicMajorsRepository.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchDicMajors; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchDicMajorsRepository extends JpaRepository, JpaSpecificationExecutor { + boolean existsBySchIdAndName(Integer schId, String name); + boolean existsBySchIdAndNameAndIdNot(Integer schId, String name, Integer id); + Optional findByIdAndSchId(Integer Id, Integer schId); + + @Query("SELECT MAX(m.schsystemLeng) FROM SchDicMajors m WHERE m.schId = :schId") + Optional findMaxSchsystemLengBySchId(Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicSubjectRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicSubjectRepository.java new file mode 100644 index 0000000..f5504f9 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchDicSubjectRepository.java @@ -0,0 +1,23 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.entity.SchDicSubject; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchDicSubjectRepository extends JpaRepository, JpaSpecificationExecutor { + + @Query(value = "SELECT MAX(CAST(SUBSTRING(code, 4) AS UNSIGNED)) FROM sch_dic_subject WHERE code LIKE 'SUB%' AND sch_id = ?1", nativeQuery = true) + Integer findMaxSubjectCodeNumber(Integer schId); + + Optional findByIdAndSchId(Integer Id, Integer schId); + + boolean existsBySchIdAndSchSystemIdAndName(Integer schId, Integer schSystemId, String name); + + boolean existsBySchIdAndSchSystemIdAndNameAndIdNot(Integer schId, Integer schSystemId, String name, Integer id); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchInfoRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchInfoRepository.java new file mode 100644 index 0000000..40ae3c2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchInfoRepository.java @@ -0,0 +1,16 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchInfo; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchInfoRepository extends JpaRepository, JpaSpecificationExecutor { + + Optional findBySchId(Integer schId); + + Optional findBySchSerId(String schSerId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchStudentHistoryRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchStudentHistoryRepository.java new file mode 100644 index 0000000..a4df77d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchStudentHistoryRepository.java @@ -0,0 +1,12 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchClassTeachHistory; +import com.bestsch.bschclassmanage.entity.SchStudentHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface SchStudentHistoryRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchStudentRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchStudentRepository.java new file mode 100644 index 0000000..7c2986a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchStudentRepository.java @@ -0,0 +1,114 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchStudent; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchStudentRepository extends JpaRepository, JpaSpecificationExecutor { + + Optional findByStuId(Integer stuId); + + List findByStuIdIn(List stuIds); + + boolean existsByAccount(String account); + + Optional findByAccount(String account); + + Optional findByIdAndSchId(Integer Id, Integer schId); + + @Query("SELECT s FROM SchStudent s WHERE s.schId = :schId AND s.classId = :classId AND s.abnormalStatus = 1 AND s.transferStatus=1 AND s.status = 1") + List findBySchIdAndClassId(@Param("schId") Integer schId, @Param("classId") Integer classId); + + List findAllByIdInAndSchId(List ids, Integer schId); + + + + boolean existsBySchIdAndClassIdAndName(Integer schId,Integer classId, String name); + + boolean existsBySchIdAndClassIdAndNameAndIdNot(Integer schId,Integer classId, String name, Integer id); + + @Modifying(clearAutomatically = true) + @Query("UPDATE SchStudent s SET s.classId = :newClassId, s.groupId = :newClassId, s.updateDate = :updateDate, s.updateUserId = :updateUserId WHERE s.id IN (:ids) AND s.schId = :schId") + int batchUpdateClassId(@Param("ids") List ids, + @Param("newClassId") Integer newClassId, + @Param("schId") Integer schId, + @Param("updateDate") Date updateDate, + @Param("updateUserId") Integer updateUserId); + + @Modifying + @Query("UPDATE SchStudent s SET s.schId = :schId, s.classId = :newClassId,s.groupId = :newClassId, s.updateDate = :updateDate, s.updateUserId = :updateUserId , s.transferStatus =1 WHERE s.id IN :ids") + int batchUpdateSchIdAndClassId(@Param("ids") List ids, + @Param("schId") Integer schId, // 目标学校ID + @Param("newClassId") Integer newClassId, + @Param("updateDate") Date updateDate, + @Param("updateUserId") Integer updateUserId); + + + /** + * 批量更新学生异常状态,同时记录异常发生时间和修改时间(两者相同) + * + * @param ids 学生ID列表 + * @param abnormalStatus 异常状态值 + * @param schId 学校ID(安全过滤) + * @param commonDate 异常时间 / 修改时间 + * @param updateUserId 操作用户ID + * @return 实际更新的行数 + */ + @Modifying(clearAutomatically = true) + @Query("UPDATE SchStudent s SET " + + "s.abnormalStatus = :abnormalStatus, " + + "s.abnormalDate = :commonDate, " + + "s.updateDate = :commonDate, " + + "s.updateUserId = :updateUserId " + + "WHERE s.id IN (:ids) AND s.schId = :schId") + int batchUpdateAbnormalStatus(@Param("ids") List ids, + @Param("abnormalStatus") Integer abnormalStatus, + @Param("schId") Integer schId, + @Param("commonDate") Date commonDate, + @Param("updateUserId") Integer updateUserId); + + + /** + * 批量更新学生异常状态,同时记录异常发生时间和修改时间(两者相同) + * + * @param ids 学生ID列表 + * @param transferStatus 转出状态值 + * @param schId 学校ID(安全过滤) + * @param commonDate 异常时间 / 修改时间 + * @param updateUserId 操作用户ID + * @return 实际更新的行数 + */ + @Modifying(clearAutomatically = true) + @Query("UPDATE SchStudent s SET " + + "s.transferStatus = :transferStatus, " + + "s.abnormalDate = :commonDate, " + + "s.updateDate = :commonDate, " + + "s.updateUserId = :updateUserId, " + + "s.stuClassNo = null " + + "WHERE s.id IN (:ids) AND s.schId = :schId") + int batchUpdateTransferStatus(@Param("ids") List ids, + @Param("transferStatus") Integer transferStatus, + @Param("schId") Integer schId, + @Param("commonDate") Date commonDate, + @Param("updateUserId") Integer updateUserId); + + + /** + * 获取所有转出学生的学校ID(去重) + * 转出条件:transfer_status = 0 + * 关联:s.class_id = c.group_class_id + */ + @Query(value = "SELECT DISTINCT c.sch_id FROM sch_student s " + + "INNER JOIN sch_class c ON s.class_id = c.group_class_id " + + "WHERE s.transfer_status = 0 AND s.sch_id = c.sch_id AND s.status=1 ", nativeQuery = true) + List findDistinctSchIdsByTransferOut(); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInGradeRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInGradeRepository.java new file mode 100644 index 0000000..9d5af95 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInGradeRepository.java @@ -0,0 +1,15 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchTeacherCustomGroupInGrade; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface SchTeacherCustomGroupInGradeRepository extends JpaRepository, JpaSpecificationExecutor { + List findByCgGroupIdIn(List groupIds); + + void deleteByCgGroupId(Integer groupId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInSubjectRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInSubjectRepository.java new file mode 100644 index 0000000..84c9f48 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInSubjectRepository.java @@ -0,0 +1,15 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchTeacherCustomGroupInSubject; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface SchTeacherCustomGroupInSubjectRepository extends JpaRepository, JpaSpecificationExecutor { + List findByCgGroupIdIn(List groupIds); + + void deleteByCgGroupId(Integer groupId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInTeacherRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInTeacherRepository.java new file mode 100644 index 0000000..dc987ae --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupInTeacherRepository.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchTeacherCustomGroup; +import com.bestsch.bschclassmanage.entity.SchTeacherCustomGroupInTeacher; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface SchTeacherCustomGroupInTeacherRepository extends JpaRepository, JpaSpecificationExecutor { + /** + * 根据组ID列表查询所有教师关联 + * @param groupIds 组ID列表 + * @return 教师关联列表 + */ + List findByCgGroupIdIn(List groupIds); + + List findByCgGroupId(Integer groupId); + + List findByCgGroupIdAndGroupType(Integer groupId, Integer groupType); + + void deleteByCgGroupIdAndGroupType(Integer groupId, Integer groupType); + + void deleteByCgGroupIdAndTeaIdInAndGroupType(Integer groupId, List teaIds, Integer groupType); + + void deleteByCgGroupId(Integer groupId); + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupRepository.java new file mode 100644 index 0000000..83928c1 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherCustomGroupRepository.java @@ -0,0 +1,21 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchTeacherCustomGroup; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface SchTeacherCustomGroupRepository extends JpaRepository, JpaSpecificationExecutor { + + List findBySchId(Integer schId); + + List findBySchIdAndGroupType(Integer schId, Integer groupType); + + List findBySchIdAndGroupTypeAndGroupName(Integer schId, Integer groupType, String groupName); + + boolean existsBySchIdAndGroupTypeAndGroupName(Integer schId, Integer groupType, String groupName); + boolean existsBySchIdAndGroupTypeAndGroupNameAndIdNot(Integer schId, Integer groupType, String groupName, Integer id); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherGroupRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherGroupRepository.java new file mode 100644 index 0000000..5f4ae25 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherGroupRepository.java @@ -0,0 +1,97 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import java.util.List; + +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface SchTeacherGroupRepository extends JpaRepository, JpaSpecificationExecutor { + + + /** + * 根据 teaId 列表查询所有组关联(不限学校) + * 适用场景:全局查询(如跨校操作前校验) + */ + List findByTeaIdIn(List teaIds); + + + List findByGroupIdAndSchId(Integer groupId, Integer schId); + + + List findByTeaIdAndSchId(Integer teaId, Integer schId); + + /** + * 根据 teaId 列表和学校 ID 查询组关联 + * 适用场景:查询某教师在指定学校的组归属 + */ + List findByTeaIdInAndSchId(List teaIds, Integer schId); + + /** + * 根据 teaId 列表、学校 ID 和转入状态查询组关联 + * 适用场景:只查询转入状态的记录(transferStatus = 1) + */ + List findByTeaIdInAndSchIdAndTransferStatus(List teaIds, Integer schId, Integer transferStatus); + + /** + * 根据学校 ID 查询该学校所有教师的 teaId(去重) + * 适用场景:获取该校所有教师列表 + */ + @Query("SELECT DISTINCT t.teaId FROM SchTeacherGroup t WHERE t.schId = :schId") + List findTeaIdsBySchId(@Param("schId") Integer schId); + + /** + * 校验某教师是否属于某学校(根据 teaId 和 schId) + */ + boolean existsByTeaIdAndSchId(Integer teaId, Integer schId); + + // ==================== 删除方法 ==================== + + /** + * 根据 teaId 列表删除所有学校的关联(谨慎使用) + * 适用场景:全局删除(如教师彻底注销) + */ + @Modifying + @Query("DELETE FROM SchTeacherGroup g WHERE g.teaId IN :teaIds") + int deleteByTeaIdIn(@Param("teaIds") List teaIds); + + /** + * 根据 teaId 列表和学校 ID 删除关联(推荐) + * 适用场景:转出/删除时只移除该教师在当前学校的组归属 + */ + @Modifying + @Query("DELETE FROM SchTeacherGroup g WHERE g.teaId IN :teaIds AND g.schId = :schId") + int deleteByTeaIdInAndSchId(@Param("teaIds") List teaIds, @Param("schId") Integer schId); + + // ==================== 批量更新方法 ==================== + + /** + * 批量更新某学校下教师的转入状态 + * 适用场景:批量转出/转入 + */ + @Modifying + @Query("UPDATE SchTeacherGroup g SET g.transferStatus = :status WHERE g.teaId IN :teaIds AND g.schId = :schId") + int batchUpdateTransferStatus(@Param("teaIds") List teaIds, + @Param("schId") Integer schId, + @Param("status") Integer status); + + // 根据学校ID和组ID查询教师 teaId 列表 + @Query("SELECT DISTINCT t.teaId FROM SchTeacherGroup t WHERE t.schId = :schId AND t.groupId = :groupId") + List findTeaIdsBySchIdAndGroupId(@Param("schId") Integer schId, @Param("groupId") Integer groupId); + + // 查询某学校下所有不同的组ID + @Query("SELECT DISTINCT t.groupId FROM SchTeacherGroup t WHERE t.schId = :schId") + List findGroupIdsBySchId(@Param("schId") Integer schId); + + /** + * 根据状态获取学校ID(去重) + */ + @Query("SELECT DISTINCT g.schId FROM SchTeacherGroup g WHERE g.transferStatus = 0") + List findSchoolIdsByTransferOut(); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherRepository.java new file mode 100644 index 0000000..8c76544 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/SchTeacherRepository.java @@ -0,0 +1,79 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.model.vo.TeacherSchVO; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +@Repository +public interface SchTeacherRepository extends JpaRepository, JpaSpecificationExecutor { + + List findByTeaIdIn(List teaIds); + + Optional findByTeaId(Integer teaId); + + + @Query(value = "SELECT DISTINCT t.* FROM sch_teacher t " + + "INNER JOIN sch_teacher_group g ON t.tea_id = g.tea_id " + + "WHERE g.sch_id = :schId " + + "AND g.transfer_status = 1 " + // 只查转入状态的教师 + "AND (:groupId IS NULL OR g.group_id = :groupId) " + + "AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%')) " , + countQuery = "SELECT COUNT(DISTINCT t.id) FROM sch_teacher t " + + "INNER JOIN sch_teacher_group g ON t.tea_id = g.tea_id " + + "WHERE g.sch_id = :schId " + + "AND g.transfer_status = 1 " + + "AND (:groupId IS NULL OR g.group_id = :groupId) " + + "AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%'))", + nativeQuery = true) + Page searchTeachersBySchIdAndGroupId(@Param("schId") Integer schId, + @Param("groupId") Integer groupId, + @Param("keyword") String keyword, + Pageable pageable); + + + @Query(value = "SELECT DISTINCT g.tea_id AS teaId, g.sch_id AS schId, t.name AS teaName, t.id_card AS idCard " + + "FROM sch_teacher_group g " + + "INNER JOIN sch_teacher t ON t.tea_id = g.tea_id " + + "WHERE g.transfer_status = 0 " + + "AND t.status = 1 " + + "AND (:schId IS NULL OR g.sch_id = :schId) " + + "AND (:groupId IS NULL OR g.group_id = :groupId) " + + "AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%')) " + + "ORDER BY t.name", //只按教师姓名排序,避免引用未选择列 + countQuery = "SELECT COUNT(DISTINCT CONCAT(g.tea_id, '_', g.sch_id)) " + + "FROM sch_teacher_group g " + + "INNER JOIN sch_teacher t ON t.tea_id = g.tea_id " + + "WHERE g.transfer_status = 0 " + + "AND t.status = 1 " + + "AND (:schId IS NULL OR g.sch_id = :schId) " + + "AND (:groupId IS NULL OR g.group_id = :groupId) " + + "AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%'))", + nativeQuery = true) + Page searchTransferredOutTeachers(@Param("schId") Integer schId, + @Param("groupId") Integer groupId, + @Param("keyword") String keyword, + Pageable pageable); + + + @Modifying + @Query("UPDATE SchTeacher t SET t.status = :status, t.updateDate = :updateDate, t.updateUserId = :updateUserId WHERE t.id IN :ids") + int batchUpdateStatus(@Param("ids") List ids, + @Param("status") Integer status, + @Param("updateDate") Date updateDate, + @Param("updateUserId") Integer updateUserId); + + + List findByAccountIn(List accountList); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/UpgradeLogRepository.java b/src/main/java/com/bestsch/bschclassmanage/Repository/UpgradeLogRepository.java new file mode 100644 index 0000000..45be971 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/UpgradeLogRepository.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.Repository; + +import com.bestsch.bschclassmanage.entity.UpgradeLog; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface UpgradeLogRepository extends JpaRepository, JpaSpecificationExecutor { + boolean existsBySchIdAndSysIdAndYearAndStatus( + Integer schId, Integer sysId, Integer year,Boolean status + ); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/specification/OperationLogSpecifications.java b/src/main/java/com/bestsch/bschclassmanage/Repository/specification/OperationLogSpecifications.java new file mode 100644 index 0000000..3de80c3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/specification/OperationLogSpecifications.java @@ -0,0 +1,42 @@ +package com.bestsch.bschclassmanage.Repository.specification; + +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.StringUtils; + +import javax.persistence.criteria.Predicate; + +public class OperationLogSpecifications { + + public static Specification schIdEquals(Integer schId) { + return (root, query, cb) -> { + if (schId == null || schId <= 0) { + return cb.conjunction(); + } + return cb.equal(root.get("schId"), schId); + }; + } + + public static Specification IsSystem(boolean IsSystem) { + return (root, query, cb) -> { + if (IsSystem) { + return cb.equal(root.get("module"), "系统管理"); + }else{ + return cb.notEqual(root.get("module"), "系统管理"); + } + }; + } + + public static Specification keywordLike(String keyword) { + return (root, query, cb) -> { + if (!StringUtils.hasText(keyword)) { + return cb.conjunction(); + } + String likePattern = "%" + keyword.trim() + "%"; + Predicate p1 = cb.like(root.get("operator"), likePattern); + Predicate p2 = cb.like(root.get("module"), likePattern); + Predicate p3 = cb.like(root.get("content"), likePattern); + return cb.or(p1, p2, p3); + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/specification/SchClassSpecifications.java b/src/main/java/com/bestsch/bschclassmanage/Repository/specification/SchClassSpecifications.java new file mode 100644 index 0000000..26c6625 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/specification/SchClassSpecifications.java @@ -0,0 +1,138 @@ +package com.bestsch.bschclassmanage.Repository.specification; + +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.StringUtils; + +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.Predicate; +import java.util.ArrayList; +import java.util.List; + +public class SchClassSpecifications { + + /** + * 按学校 ID 查询(班级表中直接存储了 schId) + */ + public static Specification schIdEquals(Integer schId) { + return (root, query, cb) -> { + if (schId == null || schId <= 0) { + return cb.conjunction(); + } + return cb.equal(root.get("schId"), schId); + }; + } + + /** + * 按年级 ID 查询 + */ + public static Specification gradeIdEquals(Integer gradeId) { + return (root, query, cb) -> { + if (gradeId == null || gradeId <= 0) { + return cb.conjunction(); + } + return cb.equal(root.get("gradeId"), gradeId); + }; + } + + /** + * 按班级名称模糊查询 + */ + public static Specification classNameLike(String className) { + return (root, query, cb) -> { + if (!StringUtils.hasText(className)) { + return cb.conjunction(); + } + return cb.like(root.get("className"), "%" + className + "%"); + }; + } + + /** + * 按班主任教师 ID 查询(firstTeacherId) + */ + public static Specification firstTeacherIdEquals(Integer teacherId) { + return (root, query, cb) -> { + if (teacherId == null || teacherId <= 0) { + return cb.conjunction(); + } + return cb.equal(root.get("firstTeacherId"), teacherId); + }; + } + + /** + * 按副班主任教师 ID 查询(secondTeacherId) + */ + public static Specification secondTeacherIdEquals(Integer teacherId) { + return (root, query, cb) -> { + if (teacherId == null || teacherId <= 0) { + return cb.conjunction(); + } + return cb.equal(root.get("secondTeacherId"), teacherId); + }; + } + + /** + * 按班主任或副班主任教师 ID 查询(任意一个匹配) + */ + public static Specification teacherIsHeadOrAssistant(Integer teacherId) { + return (root, query, cb) -> { + if (teacherId == null || teacherId <= 0) { + return cb.conjunction(); + } + Predicate p1 = cb.equal(root.get("firstTeacherId"), teacherId); + Predicate p2 = cb.equal(root.get("secondTeacherId"), teacherId); + return cb.or(p1, p2); + }; + } + + /** + * 按年级名称模糊查询(需关联年级表,假设有 @ManyToOne 关系) + * 注意:SchClass 实体中需有 grade 关联字段,例如:@ManyToOne @JoinColumn(name = "grade_id") private SchGrade grade; + */ + public static Specification gradeNameLike(String gradeName) { + return (root, query, cb) -> { + if (!StringUtils.hasText(gradeName)) { + return cb.conjunction(); + } + Join gradeJoin = root.join("grade", JoinType.INNER); + return cb.like(gradeJoin.get("name"), "%" + gradeName + "%"); + }; + } + + /** + * 动态组合查询(多条件),便于一次性传入多个参数 + */ + public static Specification dynamicQuery(Integer schId, Integer gradeId, String keyword, + Integer teacherId, Boolean isHeadTeacher) { + return (root, query, cb) -> { + List predicates = new ArrayList<>(); + + if (schId != null && schId > 0) { + predicates.add(cb.equal(root.get("schId"), schId)); + } + if (gradeId != null && gradeId > 0) { + predicates.add(cb.equal(root.get("gradeId"), gradeId)); + } + if (StringUtils.hasText(keyword)) { + predicates.add(cb.like(root.get("className"), "%" + keyword + "%")); + } + if (teacherId != null && teacherId > 0) { + if (isHeadTeacher != null && isHeadTeacher) { + predicates.add(cb.equal(root.get("firstTeacherId"), teacherId)); + } else if (isHeadTeacher != null && !isHeadTeacher) { + predicates.add(cb.equal(root.get("secondTeacherId"), teacherId)); + } else { + // 没有指定角色,默认查班主任或副班主任任意一个 + Predicate p1 = cb.equal(root.get("firstTeacherId"), teacherId); + Predicate p2 = cb.equal(root.get("secondTeacherId"), teacherId); + predicates.add(cb.or(p1, p2)); + } + } + + query.distinct(true); + return cb.and(predicates.toArray(new Predicate[0])); + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/Repository/specification/SchTeacherSpecifications.java b/src/main/java/com/bestsch/bschclassmanage/Repository/specification/SchTeacherSpecifications.java new file mode 100644 index 0000000..282a06a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/Repository/specification/SchTeacherSpecifications.java @@ -0,0 +1,94 @@ +package com.bestsch.bschclassmanage.Repository.specification; + +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.StringUtils; + +import javax.persistence.criteria.Join; +import javax.persistence.criteria.JoinType; +import javax.persistence.criteria.Predicate; +import java.util.ArrayList; +import java.util.List; + +public class SchTeacherSpecifications { + + /** + * 按姓名模糊查询 + */ + public static Specification nameLike(String keyword) { + return (root, query, cb) -> { + if (!StringUtils.hasText(keyword)) { + return cb.conjunction(); + } + return cb.like(root.get("name"), "%" + keyword + "%"); + }; + } + + /** + * 按状态精确查询(0-正常, 1-禁用等) + */ + public static Specification statusEquals(Integer status) { + return (root, query, cb) -> { + if (status == null || status < 0) { + return cb.conjunction(); + } + return cb.equal(root.get("status"), status); + }; + } + + /** + * 按学校 ID 查询(通过关联表 SchTeacherGroup) + */ + public static Specification belongsToSchool(Integer schId) { + return (root, query, cb) -> { + if (schId == null || schId <= 0) { + return cb.conjunction(); + } + Join groupJoin = root.join("schTeacherGroups", JoinType.INNER); + query.distinct(true); // 避免因关联导致重复记录 + return cb.equal(groupJoin.get("schId"), schId); + }; + } + + /** + * 按组 ID 查询(通过关联表) + */ + public static Specification belongsToGroup(Integer groupId) { + return (root, query, cb) -> { + if (groupId == null || groupId <= 0) { + return cb.conjunction(); + } + Join groupJoin = root.join("schTeacherGroups", JoinType.INNER); + query.distinct(true); + return cb.equal(groupJoin.get("groupId"), groupId); + }; + } + + /** + * 组合查询:支持多条件动态组合(用于复杂搜索) + */ + public static Specification dynamicQuery(Integer schId, Integer groupId, String keyword, Integer status) { + return (root, query, cb) -> { + List predicates = new ArrayList<>(); + + if (schId != null && schId > 0) { + Join groupJoin = root.join("schTeacherGroups", JoinType.INNER); + predicates.add(cb.equal(groupJoin.get("schId"), schId)); + } + if (groupId != null && groupId > 0) { + Join groupJoin = root.join("schTeacherGroups", JoinType.INNER); + predicates.add(cb.equal(groupJoin.get("groupId"), groupId)); + } + if (StringUtils.hasText(keyword)) { + predicates.add(cb.like(root.get("name"), "%" + keyword + "%")); + } + if (status != null && status >= 0) { + predicates.add(cb.equal(root.get("status"), status)); + } + + query.distinct(true); + return cb.and(predicates.toArray(new Predicate[0])); + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/annotation/OperationLog.java b/src/main/java/com/bestsch/bschclassmanage/annotation/OperationLog.java new file mode 100644 index 0000000..36cba96 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/annotation/OperationLog.java @@ -0,0 +1,21 @@ +package com.bestsch.bschclassmanage.annotation; + +import java.lang.annotation.*; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OperationLog { + + /** + * 操作所属模块,如 "教师信息管理" + */ + String module() default ""; + + /** + * 日志内容模板,支持 SpEL 表达式 + * 例如:"将教师 #{#teacherName} 的姓名从 #{#oldName} 改为 #{#newName}" + * 方法参数可以通过 #参数名 引用,返回值通过 #result 引用 + */ + String description() default ""; +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/aspect/ControllerUserContextAspect.java b/src/main/java/com/bestsch/bschclassmanage/aspect/ControllerUserContextAspect.java new file mode 100644 index 0000000..32093b4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/aspect/ControllerUserContextAspect.java @@ -0,0 +1,76 @@ +package com.bestsch.bschclassmanage.aspect; + +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +@Aspect +@Component +@Order(1) +public class ControllerUserContextAspect { + + private static final Logger log = LoggerFactory.getLogger(ControllerUserContextAspect.class); + + @Around("execution(* com.bestsch.bschclassmanage.controller..*.*(..))") + public Object setUserContext(ProceedingJoinPoint joinPoint) throws Throwable { + // 1. 从方法参数中提取 BoaUser 和 UserSysRole + Object[] args = joinPoint.getArgs(); + BoaUser boaUser = null; + UserSysRole userSysRole = null; + + for (Object arg : args) { + if (arg instanceof BoaUser) { + boaUser = (BoaUser) arg; + } else if (arg instanceof UserSysRole) { + userSysRole = (UserSysRole) arg; + } + } + + // 2. 填充 UserContext + populateUserContext(boaUser, userSysRole); + + try { + return joinPoint.proceed(); + } finally { + UserContext.clear(); + log.debug("UserContext cleared for {}", joinPoint.getSignature().toShortString()); + } + } + + private HttpServletRequest getCurrentHttpRequest() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + return attributes != null ? attributes.getRequest() : null; + } + + private void populateUserContext(BoaUser boaUser, UserSysRole userSysRole) { + if (boaUser != null) { + UserContext.setUserId(boaUser.getId()); + UserContext.setUserName(boaUser.getName() != null ? boaUser.getName() : "unknown"); + log.debug("UserContext set from parameter/session: id={}, name={}", boaUser.getId(), boaUser.getName()); + } else { + UserContext.setUserName("anonymous"); + log.warn("No BoaUser found, using anonymous"); + } + + if (userSysRole != null) { + UserContext.setRoleId(userSysRole.getRoleId()); + UserContext.setSchId(userSysRole.getSchId()); + log.debug("UserContext set roleId={}, schId={}", userSysRole.getRoleId(), userSysRole.getSchId()); + } + + String clientIp = OtherUtil.getClientIp(); + UserContext.setIp(clientIp); + log.debug("Client IP set: {}", clientIp); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/aspect/OperationLogAspect.java b/src/main/java/com/bestsch/bschclassmanage/aspect/OperationLogAspect.java new file mode 100644 index 0000000..7086493 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/aspect/OperationLogAspect.java @@ -0,0 +1,131 @@ +package com.bestsch.bschclassmanage.aspect; + +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.service.ILogService; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.DefaultParameterNameDiscoverer; +import org.springframework.core.annotation.Order; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.time.LocalDateTime; + +@Aspect +@Component +@Order(2) +public class OperationLogAspect { + + @Autowired + private ILogService logService; + + private final ExpressionParser parser = new SpelExpressionParser(); + private final DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer(); + + @Around("@annotation(operationLog)") + public Object logAround(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + Object[] args = joinPoint.getArgs(); + + // 从 UserContext 获取用户信息(由 ControllerAspect 设置) + String ip = UserContext.getIp(); + String operator = UserContext.getUserName(); + Integer userId = UserContext.getUserId(); + Integer schId = UserContext.getSchId(); + + Object result = null; + String content = null; + + try { + // 1. 先执行业务方法(内部会调用 LogContextHolder.setDescription) + result = joinPoint.proceed(); + + // 2. 业务方法执行后,尝试获取动态描述 + String dynamicDesc = LogContextHolder.getDescription(); + if (StringUtils.hasText(dynamicDesc)) { + content = dynamicDesc; + } else { + // 无动态描述,则解析 SpEL 模板(此时 result 可用于 #result) + content = resolveDescription(operationLog.description(), method, args, result); + } + return result; + + } finally { + // 3. 清理 ThreadLocal(在业务方法执行后) + LogContextHolder.clear(); + + // 4. 保存日志(确保 content 非空) + if (content != null) { + saveLogAsync(ip, operator, userId, schId, operationLog.module(), content); + } + + } + } + + /** + * 解析日志描述:优先从 ThreadLocal 获取动态描述,否则解析 SpEL 模板 + */ + private String resolveDescription(String template, Method method, Object[] args, Object result) { + // 优先从 ThreadLocal 获取动态描述 + String dynamicDesc = LogContextHolder.getDescription(); + if (StringUtils.hasText(dynamicDesc)) { + return dynamicDesc; + } + + // 没有动态描述,则解析 SpEL + if (!StringUtils.hasText(template)) { + return ""; + } + + EvaluationContext context = new StandardEvaluationContext(); + String[] paramNames = discoverer.getParameterNames(method); + if (paramNames != null) { + for (int i = 0; i < paramNames.length; i++) { + context.setVariable(paramNames[i], args[i]); + } + } + if (result != null) { + context.setVariable("result", result); + } + + org.springframework.expression.common.TemplateParserContext parserContext = + new org.springframework.expression.common.TemplateParserContext("#{", "}"); + Expression exp = parser.parseExpression(template, parserContext); + return exp.getValue(context, String.class); + } + + + @Async + public void saveLogAsync(String ip,String operator,Integer operatorId,Integer schId, String module, String content) { + try { OperationLogRecord log = new OperationLogRecord(); + log.setOperator(operator); + log.setOperatorId(operatorId); + log.setIp(ip); + log.setSchId(schId); + log.setModule(module); + log.setContent(content); + log.setOperateTime(LocalDateTime.now()); + logService.save(log); + } catch (Exception e) { + e.printStackTrace(); // 生产环境建议用日志输出 + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/config/AsyncConfig.java b/src/main/java/com/bestsch/bschclassmanage/config/AsyncConfig.java new file mode 100644 index 0000000..feba031 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/config/AsyncConfig.java @@ -0,0 +1,24 @@ +package com.bestsch.bschclassmanage.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@Configuration +@EnableAsync // 启用异步处理 +public class AsyncConfig { + + @Bean(name = "logExecutor") + public Executor logExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2); // 核心线程数 + executor.setMaxPoolSize(5); // 最大线程数 + executor.setQueueCapacity(100); // 任务队列容量 + executor.setThreadNamePrefix("log-"); // 线程名称前缀 + executor.initialize(); // 初始化 + return executor; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/config/Config.java b/src/main/java/com/bestsch/bschclassmanage/config/Config.java similarity index 68% rename from src/main/java/com/bestsch/classicalchinese/config/Config.java rename to src/main/java/com/bestsch/bschclassmanage/config/Config.java index a06ade1..e74bedb 100644 --- a/src/main/java/com/bestsch/classicalchinese/config/Config.java +++ b/src/main/java/com/bestsch/bschclassmanage/config/Config.java @@ -1,9 +1,8 @@ -package com.bestsch.classicalchinese.config; +package com.bestsch.bschclassmanage.config; -import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Value; import java.util.ResourceBundle; @@ -12,9 +11,9 @@ public enum Config { Inst; - public static final String API_PATH = "/api/"; - public static final String MOBILEAPI_PATH = "/mobiapi/"; - public static final String OAPI = "/oapi/"; + public static final String API_PATH = "/api"; + public static final String MOBILEAPI_PATH = "/mobiapi"; + public static final String OAPI = "/oapi"; @Value("${FILE_WEB_PATH}") public String FILE_WEB_PATH; diff --git a/src/main/java/com/bestsch/bschclassmanage/config/DWebMvcConfig.java b/src/main/java/com/bestsch/bschclassmanage/config/DWebMvcConfig.java new file mode 100644 index 0000000..11d7231 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/config/DWebMvcConfig.java @@ -0,0 +1,17 @@ +package com.bestsch.bschclassmanage.config; + +import com.bestsch.bschclassmanage.controller.Handler.UserSysRoleArgumentResolver; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +public class DWebMvcConfig implements WebMvcConfigurer { + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new UserSysRoleArgumentResolver()); // 无参构造 + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/config/FileConfig.java b/src/main/java/com/bestsch/bschclassmanage/config/FileConfig.java similarity index 89% rename from src/main/java/com/bestsch/classicalchinese/config/FileConfig.java rename to src/main/java/com/bestsch/bschclassmanage/config/FileConfig.java index 9e0bd02..b4fbdf0 100644 --- a/src/main/java/com/bestsch/classicalchinese/config/FileConfig.java +++ b/src/main/java/com/bestsch/bschclassmanage/config/FileConfig.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.config; +package com.bestsch.bschclassmanage.config; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java b/src/main/java/com/bestsch/bschclassmanage/config/RedisConfig.java similarity index 84% rename from src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java rename to src/main/java/com/bestsch/bschclassmanage/config/RedisConfig.java index 754389b..4f936b2 100644 --- a/src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java +++ b/src/main/java/com/bestsch/bschclassmanage/config/RedisConfig.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.config; +package com.bestsch.bschclassmanage.config; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; @@ -54,15 +54,19 @@ public class RedisConfig extends CachingConfigurerSupport { public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); - Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + // 使用 FastJsonRedisSerializer(会自动存储 @type 字段) + FastJsonRedisSerializer fastJsonSerializer = new FastJsonRedisSerializer<>(Object.class); + // 允许反序列化 com.bestsch 包下的类(安全) + ParserConfig.getGlobalInstance().addAccept("com.bestsch"); - template.setValueSerializer(jackson2JsonRedisSerializer); - template.setHashValueSerializer(jackson2JsonRedisSerializer); - ParserConfig.getGlobalInstance().addAccept("com.bestsch.modules.system.service.dto"); - // key的序列化采用StringRedisSerializer + template.setValueSerializer(fastJsonSerializer); + template.setHashValueSerializer(fastJsonSerializer); + // key 使用 String 序列化 template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); + + log.info("RedisTemplate value serializer: {}", fastJsonSerializer.getClass()); return template; } diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/BaseController.java b/src/main/java/com/bestsch/bschclassmanage/controller/BaseController.java new file mode 100644 index 0000000..213a975 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/BaseController.java @@ -0,0 +1,70 @@ +package com.bestsch.bschclassmanage.controller; + + +import com.bestsch.bschclassmanage.model.vo.PageVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + + +@Slf4j +public class BaseController { + /** + * 根据请求参数构建PageVO对象,设置当前页和每页大小,并提供默认值。 + * @param page 页码字符串(从1开始) + * @param pageSize 每页大小字符串 + * @return PageVO对象 + */ + protected PageVO getPageVO(String page, String pageSize) { + int defaultPage = 1; + int defaultSize = 10; + int maxSize = 100; // 可配置 + + int current = defaultPage; + int size = defaultSize; + + if (StringUtils.isNumeric(page)) { + try { + current = Integer.parseInt(page); + if (current < 1) { + current = defaultPage; + } + } catch (NumberFormatException ignored) { + // 保持默认 + } + } + if (StringUtils.isNumeric(pageSize)) { + try { + size = Integer.parseInt(pageSize); + if (size < 1) { + size = defaultSize; + } else if (size > maxSize) { + size = maxSize; + } + } catch (NumberFormatException ignored) { + // 保持默认 + } + } + + PageVO pageVO = new PageVO(); + pageVO.setCurrent(current); + pageVO.setPageSize(size); + return pageVO; + } + + /** + * 安全地将字符串转换为Integer,若转换失败返回null。 + * @param str 待转换字符串 + * @return Integer值或null + */ + public static Integer getIntByString(String str) { + if (str == null || str.trim().isEmpty() || "null".equalsIgnoreCase(str.trim())) { + return null; + } + try { + return Integer.parseInt(str.trim()); + } catch (NumberFormatException e) { + return null; // 静默失败,不抛异常 + } + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/Handler/UserSysRoleArgumentResolver.java b/src/main/java/com/bestsch/bschclassmanage/controller/Handler/UserSysRoleArgumentResolver.java new file mode 100644 index 0000000..17fcf3d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/Handler/UserSysRoleArgumentResolver.java @@ -0,0 +1,43 @@ +package com.bestsch.bschclassmanage.controller.Handler; + +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.core.MethodParameter; // ✅ 正确包 +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + +@RestControllerAdvice +public class UserSysRoleArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(UserSysRole.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + // 优先从 Header 中获取 currentrole(生产环境由网关/门户注入) + String raw = webRequest.getHeader("currentrole"); + boolean fromQuery = false; + if (raw == null) { + // 回退:支持以 URL 查询参数 currentrole 传入(便于调试/测试) + raw = webRequest.getParameter("currentrole"); + fromQuery = true; + } + if (raw == null) { + return null; // 或抛异常 + } + // Header 中的值通常是 URL 编码的,需要解码;URL 查询参数已被容器自动解码,无需再解 + String decoded = fromQuery ? raw : URLDecoder.decode(raw, StandardCharsets.UTF_8.name()); + // 反序列化 JSON → UserSysRole + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(decoded, UserSysRole.class); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/Handler/ValidationExceptionHandler.java b/src/main/java/com/bestsch/bschclassmanage/controller/Handler/ValidationExceptionHandler.java new file mode 100644 index 0000000..3c25665 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/Handler/ValidationExceptionHandler.java @@ -0,0 +1,33 @@ +package com.bestsch.bschclassmanage.controller.Handler; + +import com.yunhai.platform.utils.exception.ErrorCode; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; + +@RestControllerAdvice +public class ValidationExceptionHandler { + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions(MethodArgumentNotValidException ex) { + List msgList = new ArrayList<>(); + ex.getBindingResult().getAllErrors().forEach(error -> { + String errorMessage = error.getDefaultMessage(); + msgList.add(errorMessage); + }); + + Map response = new LinkedHashMap<>(); + response.put("code", ErrorCode.ERROR.getCode()); + response.put("msg", String.join(";", msgList)); + response.put("data", null); + response.put("timeNow", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + return new ResponseEntity(response, HttpStatus.BAD_REQUEST); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/LogController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/LogController.java new file mode 100644 index 0000000..699a28f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/LogController.java @@ -0,0 +1,35 @@ +package com.bestsch.bschclassmanage.controller.api; + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.controller.BaseController; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.service.ILogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(Config.API_PATH+"/log/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class LogController extends BaseController { + + @Autowired + private ILogService logService; // 使用接口 + + @GetMapping("systemSearch") + public PageVO systemSearch(UserSysRole curRole, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return logService.search(curRole.getSchId(),keyword,true,pageable); + } + + @GetMapping("search") + public PageVO search(UserSysRole curRole, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return logService.search(curRole.getSchId(),keyword,false,pageable); + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/LoginUserController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/LoginUserController.java similarity index 67% rename from src/main/java/com/bestsch/classicalchinese/controller/api/LoginUserController.java rename to src/main/java/com/bestsch/bschclassmanage/controller/api/LoginUserController.java index 3140621..923f667 100644 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/LoginUserController.java +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/LoginUserController.java @@ -1,12 +1,11 @@ -package com.bestsch.classicalchinese.controller.api; +package com.bestsch.bschclassmanage.controller.api; -import com.bestsch.openapi.BoaModule; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import org.springframework.beans.factory.annotation.Autowired; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.config.Config; +import com.yunhai.platform.openapi.client.YschBaseOpenApi; +import com.yunhai.platform.utils.model.BoaModule; +import com.yunhai.platform.utils.model.BoaUser; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -20,15 +19,13 @@ import java.util.List; @RestController @RequestMapping(Config.API_PATH) -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") public class LoginUserController { - @Autowired - private BschBaseOpenApi bschBaseOpenApi; @GetMapping("GetUserMod") public List getUserMod(BoaUser authUserWithDept, UserSysRole curRole) { - return bschBaseOpenApi.getUserModule(curRole.getUserId(),curRole.getSchId()); + return YschBaseOpenApi.getUserModule(authUserWithDept.getId(),curRole.getSchId()); } @GetMapping("GetUserInfo") diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchClassController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchClassController.java new file mode 100644 index 0000000..3d05086 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchClassController.java @@ -0,0 +1,285 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.model.excel.ImportRuleExcelColumn; +import com.bestsch.bschclassmanage.model.excel.SchClassExcelColumn; +import com.bestsch.bschclassmanage.model.excel.SchHeightClassExcelColumn; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.BaseSchClassVO; +import com.bestsch.bschclassmanage.model.vo.HigherSchClassVO; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.EasyPoiUtils; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@RestController +@RequestMapping(Config.API_PATH+"/schclass/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchClassController { + + @Autowired + private ISchClassService schClassService; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchTeacherService schTeacherService; + + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchDicDivisionService schDicDivisionService; + + @Autowired + private ISchDicMajorsService schDicMajorsService; + + + @GetMapping("searcBaseSchClass") + public List searcBaseSchClass(UserSysRole curRole, + @RequestParam(required = false) Integer schsystemId, + @RequestParam(required = false) Integer gradeId) { + return schClassService.searcBaseSchClass(curRole.getSchId(),schsystemId,gradeId,null); + } + + @PostMapping("addBaseSchClass") + public void addBaseSchClass(BoaUser authUserWithDept, UserSysRole curRole, Integer gradeId, Integer number) { + schClassService.addBaseSchClass(UserContext.getCurrentUserInfo(),gradeId,number); + } + + + @PostMapping("editClassName") + public void editClassName(BoaUser authUserWithDept, UserSysRole curRole,Integer id,String cname) { + schClassService.editClassName(UserContext.getCurrentUserInfo(),id,cname); + } + + @PostMapping("editClassFirstTeacher") + public void editClassfirstTeacher(BoaUser authUserWithDept, UserSysRole curRole,Integer id,Integer firstTeacherId) { + schClassService.editClassFirstTeacher(UserContext.getCurrentUserInfo(),id,firstTeacherId); + } + + @PostMapping("editClassSecondTeacher") + public void editClassSecondTeacher(BoaUser authUserWithDept, UserSysRole curRole,Integer id,Integer secondTeacherId) { + schClassService.editClassSecondTeacher(UserContext.getCurrentUserInfo(),id,secondTeacherId); + } + + @PostMapping("editClassCampus") + public void editClassCampus(BoaUser authUserWithDept, UserSysRole curRole,Integer id,Integer campusId) { + schClassService.editClassCampus(UserContext.getCurrentUserInfo(),id,campusId); + } + + + + @GetMapping("searcHigherSchClass") + public PageVO searcHigherSchClass(UserSysRole curRole, + @RequestParam(required = false) Integer year, + @RequestParam(required = false) Integer campusId, + @RequestParam(required = false) Integer divisionId, + @RequestParam(required = false) Integer majorsId, + Pageable pageable) { + return schClassService.searcHigherSchClass(curRole.getSchId(),year,campusId,divisionId,majorsId,pageable); + } + + @PostMapping("saveHigherSchClass") + public void addHigherSchClass(BoaUser authUserWithDept, UserSysRole curRole,@RequestBody SchClass model) { + schClassService.saveHigherSchClass(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("delete/{id}") + public void deleteSchClass(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable Integer id) { + schClassService.deleteSchClass(UserContext.getCurrentUserInfo(),id,curRole.getSchId()); + } + + + @GetMapping("select") + public List getClassSelect(UserSysRole curRole, @RequestParam Integer gradeId) { + return schClassService.getClassSelect(curRole.getSchId(),gradeId); + } + + @GetMapping("selectBySchIdAndGradeId") + public List getClassSelect(@RequestParam Integer schId, @RequestParam Integer gradeId) { + return schClassService.getClassSelect(schId,gradeId); + } + + + @GetMapping("downloadTemplate") + public void downloadTemplate(HttpServletResponse response,Integer schId) { + String fileName="班级导入模板"; + List> sheets = new ArrayList<>(); + + List classList=new ArrayList<>(); + { + SchClassExcelColumn column=new SchClassExcelColumn(); + column.setGradeName("示例:初一"); + column.setClazzName("示例:1班"); + column.setClazzCName("示例:一班"); + column.setBzr("示例:张三"); + classList.add(column); + } + + List gradeNames=baseSchsystemGradeService.getGradeSelect(schId,null,null) + .stream().map(s->s.getName()).collect(Collectors.toList()); + + List teaNames=schTeacherService.getSchTeacherList(schId).stream().map(s->s.getName()).collect(Collectors.toList()); + + List ruleList = new ArrayList<>(); + + ImportRuleExcelColumn rule1 = new ImportRuleExcelColumn(); + rule1.setRuleItem("年级"); + rule1.setDescription("必填"); + rule1.setContent(String.join("、",gradeNames)); + ruleList.add(rule1); + + ImportRuleExcelColumn rule2 = new ImportRuleExcelColumn(); + rule2.setRuleItem("班级"); + rule2.setDescription("必填"); + rule2.setContent("1班、2班、3班~n班"); + ruleList.add(rule2); + + ImportRuleExcelColumn rule3 = new ImportRuleExcelColumn(); + rule3.setRuleItem("班主任、副班主任"); + rule3.setDescription("选填"); + rule3.setContent(String.join("、",teaNames)); + ruleList.add(rule3); + + ExportParams params1 = new ExportParams("班级导入",comSchTreeService.getSchoolName(schId)); + Map sheet1 = new HashMap<>(); + sheet1.put("title",params1); + sheet1.put("entity", SchClassExcelColumn.class); + sheet1.put("data", classList); + sheets.add(sheet1); + + ExportParams params2 = new ExportParams("导入规则", "导入规则"); + + Map sheet2 = new HashMap<>(); + sheet2.put("title", params2); + sheet2.put("entity", ImportRuleExcelColumn.class); + sheet2.put("data", ruleList); + sheets.add(sheet2); + + Workbook workbook = ExcelExportUtil.exportExcel(sheets, ExcelType.HSSF); + EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook); + } + + @PostMapping("importClasses") + public void importClasses(BoaUser authUserWithDept, UserSysRole curRole, @RequestPart("file") MultipartFile file) { + schClassService.importClasses(UserContext.getCurrentUserInfo(),file); + } + + + @GetMapping("downloadHeightTemplate") + public void downloadHeightTemplate(HttpServletResponse response,Integer schId) { + String fileName="班级导入模板"; + List> sheets = new ArrayList<>(); + + List classList=new ArrayList<>(); + { + SchHeightClassExcelColumn column=new SchHeightClassExcelColumn(); + column.setGradeName("示例:2026级"); + column.setClazzCode(""); + column.setClazzName("示例:南校1班"); + column.setClazzCName(""); + column.setCampus("示例:南校区"); + column.setDivistion("示例:信息工程"); + column.setDivistion("示例:软件开发"); + column.setBzr("示例:张三"); + classList.add(column); + } + + + List campusNames=schDicCampusService.getSchDicCampusCacheList(schId).stream().map(s->s.getName()).collect(Collectors.toList()); + + List divisionNames=schDicDivisionService.getSchDicDivisionCacheList(schId).stream().map(s->s.getName()).collect(Collectors.toList()); + + List majorsNames=schDicMajorsService.getSchDicMajorsCacheList(schId).stream().map(s->s.getName()).collect(Collectors.toList()); + + + List teaNames=schTeacherService.getSchTeacherList(schId).stream().map(s->s.getName()).collect(Collectors.toList()); + + List ruleList = new ArrayList<>(); + + ImportRuleExcelColumn rule1 = new ImportRuleExcelColumn(); + rule1.setRuleItem("校区"); + rule1.setDescription("选填"); + rule1.setContent(String.join("、",campusNames)); + ruleList.add(rule1); + + ImportRuleExcelColumn rule2 = new ImportRuleExcelColumn(); + rule2.setRuleItem("系部"); + rule2.setDescription("必填"); + rule2.setContent(String.join("、",divisionNames)); + ruleList.add(rule2); + + ImportRuleExcelColumn rule3 = new ImportRuleExcelColumn(); + rule3.setRuleItem("专业"); + rule3.setDescription("必填"); + rule3.setContent(String.join("、",majorsNames)); + ruleList.add(rule3); + + ImportRuleExcelColumn rule4 = new ImportRuleExcelColumn(); + rule4.setRuleItem("班主任"); + rule4.setDescription("选填"); + rule4.setContent(String.join("、",teaNames)); + ruleList.add(rule4); + + ExportParams params1 = new ExportParams("班级导入",comSchTreeService.getSchoolName(schId)); + Map sheet1 = new HashMap<>(); + sheet1.put("title",params1); + sheet1.put("entity", SchHeightClassExcelColumn.class); + sheet1.put("data", classList); + sheets.add(sheet1); + + ExportParams params2 = new ExportParams("导入规则", "导入规则"); + + Map sheet2 = new HashMap<>(); + sheet2.put("title", params2); + sheet2.put("entity", ImportRuleExcelColumn.class); + sheet2.put("data", ruleList); + sheets.add(sheet2); + + Workbook workbook = ExcelExportUtil.exportExcel(sheets, ExcelType.HSSF); + EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook); + } + + @PostMapping("importHeightClasses") + public void importHeightClasses(BoaUser authUserWithDept, UserSysRole curRole, @RequestPart("file") MultipartFile file) { + schClassService.importHeightClasses(UserContext.getCurrentUserInfo(),file); + } + + @GetMapping("backupAllSnapshot") + public void backupAllSnapshot() { + schClassService.backupAllSnapshot(); + } + + @GetMapping("upgradeAllClasses") + public void upgradeAllClasses() { + schClassService.upgradeAllClasses(); + } + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchCustomGroupController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchCustomGroupController.java new file mode 100644 index 0000000..9be6708 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchCustomGroupController.java @@ -0,0 +1,161 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.enums.CustomGroupType; +import com.bestsch.bschclassmanage.model.dto.AddMemberDTO; +import com.bestsch.bschclassmanage.model.dto.SchCustomGroupDTO; +import com.bestsch.bschclassmanage.model.dto.SetLeaderDTO; +import com.bestsch.bschclassmanage.model.excel.CustomGroupExcelColumn; +import com.bestsch.bschclassmanage.model.excel.ImportRuleExcelColumn; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SchCustomGroupVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.EasyPoiUtils; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@RestController +@RequestMapping(Config.API_PATH+"/group/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchCustomGroupController { + + @Autowired + private ISchCustomGroupService schCustomGroupService; // 使用接口 + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchDicSubjectService schDicSubjectService; //使用接口 + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private ISchTeacherService schTeacherService; + + @GetMapping("getSchCustomGroup") + public List getSchCustomGroup(UserSysRole curRole, @RequestParam Integer type) { + return schCustomGroupService.getSchCustomGroup(curRole.getSchId(),type); + } + + @PostMapping("saveSchCustomGroup") + public void saveSchCustomGroup(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody SchCustomGroupDTO dto) { + schCustomGroupService.saveSchCustomGroup(UserContext.getCurrentUserInfo(),dto); + } + + @PostMapping("saveMembers") + public void saveMembers(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody AddMemberDTO dto) { + schCustomGroupService.saveMembers(UserContext.getCurrentUserInfo(),dto); + } + + @PostMapping("setLeaders") + public void setLeaders(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody SetLeaderDTO dto) { + schCustomGroupService.setLeaders(UserContext.getCurrentUserInfo(),dto); + } + + @PostMapping("deleteSchCustomGroup") + public void deleteSchCustomGroup(UserSysRole curRole,@RequestParam Integer groupId) { + schCustomGroupService.deleteSchCustomGroup(UserContext.getCurrentUserInfo(),groupId); + } + + + @GetMapping("downloadTemplate") + public void downloadTemplate(HttpServletResponse response, Integer schId) { + String fileName = "教师分组导入模板"; + List> sheets = new ArrayList<>(); + + + + + List list = new ArrayList<>(); + { + CustomGroupExcelColumn column = new CustomGroupExcelColumn(); + column.setGroupName("示例:语文组"); + column.setGroupType("示例:年级组"); + column.setGradeBin("示例:高一年级"); + column.setGradeBin("示例:语文,数学"); + column.setLeaderName("示例:张三"); + column.setMemberName("示例:张三"); + list.add(column); + } + + List teaNames=schTeacherService.getSchTeacherList(schId).stream().map(s->s.getName()).collect(Collectors.toList()); + + List gradeNames=baseSchsystemGradeService.getGradeSelect(schId,null,null) + .stream().map(s->s.getName()).collect(Collectors.toList()); + + List subjectNames=schDicSubjectService.getSchSubList(schId,null) + .stream().map(s->s.getName()).collect(Collectors.toList()); + + List groupNames=CustomGroupType.list().stream() + .map(s->s.getName()).collect(Collectors.toList()); + + ExportParams params1 = new ExportParams("自定义组导入",comSchTreeService.getSchoolName(schId)); + Map sheet1 = new HashMap<>(); + sheet1.put("title",params1); + sheet1.put("entity", CustomGroupExcelColumn.class); + sheet1.put("data", list); + sheets.add(sheet1); + + List ruleList = new ArrayList<>(); + + ImportRuleExcelColumn rule1 = new ImportRuleExcelColumn(); + rule1.setRuleItem("组长/组员"); + rule1.setDescription("多选"); + rule1.setContent(String.join(",",teaNames)); + ruleList.add(rule1); + + ImportRuleExcelColumn rule2 = new ImportRuleExcelColumn(); + rule2.setRuleItem("年级"); + rule2.setDescription("多选"); + rule2.setContent(String.join(",",gradeNames)); + ruleList.add(rule2); + + ImportRuleExcelColumn rule3 = new ImportRuleExcelColumn(); + rule3.setRuleItem("学科"); + rule3.setDescription("多选"); + rule3.setContent(String.join(",",subjectNames)); + ruleList.add(rule3); + + ImportRuleExcelColumn rule4 = new ImportRuleExcelColumn(); + rule4.setRuleItem("组类型"); + rule4.setDescription("单选"); + rule4.setContent(String.join(",",groupNames)); + ruleList.add(rule4); + + ExportParams params2 = new ExportParams("导入规则", "导入规则"); + + Map sheet2 = new HashMap<>(); + sheet2.put("title", params2); + sheet2.put("entity", ImportRuleExcelColumn.class); + sheet2.put("data", ruleList); + sheets.add(sheet2); + + Workbook workbook = ExcelExportUtil.exportExcel(sheets, ExcelType.HSSF); + EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook); + } + + + @PostMapping("importCustomGroup") + public void importCustomGroup(BoaUser authUserWithDept, UserSysRole curRole, @RequestPart("file") MultipartFile file) { + schCustomGroupService.importCustomGroup(UserContext.getCurrentUserInfo(),file); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicCampusController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicCampusController.java new file mode 100644 index 0000000..350d5bc --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicCampusController.java @@ -0,0 +1,50 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchDicCampus; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicCampusService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/campus/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchDicCampusController { + + @Autowired + private ISchDicCampusService schDicCampusService; // 使用接口 + + @GetMapping("list") + public List getSchDicCampusCacheList(UserSysRole curRole) { + return schDicCampusService.getSchDicCampusCacheList(curRole.getSchId()); + } + + @PostMapping("save") + public void saveSchCampus(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody SchDicCampus model) { + schDicCampusService.saveSchCampus(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("sort") + public void sortSchCampus(BoaUser authUserWithDept, UserSysRole curRole, @RequestBody List ids) { + schDicCampusService.sortSchCampus(UserContext.getCurrentUserInfo(),ids); + } + + @PostMapping("delete/{id}") + public void delete(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable Integer id) { + schDicCampusService.delete(UserContext.getCurrentUserInfo(),id); + } + + @GetMapping("select") + public List select(UserSysRole curRole) { + return schDicCampusService.select(curRole.getSchId()); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicCourseController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicCourseController.java new file mode 100644 index 0000000..f1afc8f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicCourseController.java @@ -0,0 +1,59 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.controller.BaseController; +import com.bestsch.bschclassmanage.enums.CourseType; +import com.bestsch.bschclassmanage.model.dto.SchDicCourseDTO; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchDicCourseVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicCourseService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/course/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchDicCourseController extends BaseController { + + @Autowired + private ISchDicCourseService schDicCourseService; // 使用接口 + + @GetMapping("search") + public PageVO search(UserSysRole curRole, + @RequestParam(required = false) Integer type, + @RequestParam(required = false) String keyword, + @RequestParam(required = false) Integer divisionId, + @RequestParam(required = false) Integer majorsId, + Pageable pageable) { + return schDicCourseService.search(curRole.getSchId(),type,keyword,divisionId,majorsId,pageable); + } + + @PostMapping("save") + public void saveSchMajors(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody SchDicCourseDTO dto) { + schDicCourseService.saveSchCourse(UserContext.getCurrentUserInfo(),dto); + } + + + @PostMapping("delete/{id}") + public void delete(BoaUser authUserWithDept, UserSysRole curRole, @PathVariable Integer id) { + schDicCourseService.delete(UserContext.getCurrentUserInfo(),id); + } + + + @GetMapping("typeSelect") + public List typeSelect() { + return CourseType.select(); + } + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicDivisionController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicDivisionController.java new file mode 100644 index 0000000..e31ee7b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicDivisionController.java @@ -0,0 +1,50 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchDicDivision; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicDivisionService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/division/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchDicDivisionController { + + @Autowired + private ISchDicDivisionService schDicDivisionService; // 使用接口 + + @GetMapping("list") + public List getSchDicDivisionCacheList(UserSysRole curRole) { + return schDicDivisionService.getSchDicDivisionCacheList(curRole.getSchId()); + } + + @PostMapping("save") + public void saveSchDivision(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody SchDicDivision model) { + schDicDivisionService.saveSchDivision(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("sort") + public void sortSchDivision(BoaUser authUserWithDept, UserSysRole curRole,@RequestBody List ids) { + schDicDivisionService.sortSchDivision(UserContext.getCurrentUserInfo(),ids); + } + + @PostMapping("delete/{id}") + public void delete(BoaUser authUserWithDept, UserSysRole curRole, @PathVariable Integer id) { + schDicDivisionService.delete(UserContext.getCurrentUserInfo(),id); + } + + @GetMapping("select") + public List select(UserSysRole curRole) { + return schDicDivisionService.select(curRole.getSchId()); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicMajorsController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicMajorsController.java new file mode 100644 index 0000000..db7a2dc --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchDicMajorsController.java @@ -0,0 +1,52 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchDicMajors; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicMajorsService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/majors/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchDicMajorsController { + + @Autowired + private ISchDicMajorsService schDicMajorsService; // 使用接口 + + @GetMapping("list") + public List getSchDicMajorsList(UserSysRole curRole, + @RequestParam(required = false)String keyword) { + return schDicMajorsService.getSchDicMajorsList(curRole.getSchId(),keyword); + } + + @PostMapping("save") + public void saveSchMajors(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody SchDicMajors model) { + schDicMajorsService.saveSchMajors(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("sort") + public void sortSchMajors(BoaUser authUserWithDept, UserSysRole curRole, @RequestBody List ids) { + schDicMajorsService.sortSchMajors(UserContext.getCurrentUserInfo(),ids); + } + + @PostMapping("delete/{id}") + public void delete(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable Integer id) { + schDicMajorsService.delete(UserContext.getCurrentUserInfo(),id); + } + + @GetMapping("select") + public List select(UserSysRole curRole) { + return schDicMajorsService.select(curRole.getSchId()); + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchGradeController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchGradeController.java new file mode 100644 index 0000000..33336e3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchGradeController.java @@ -0,0 +1,43 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/grade/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchGradeController { + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; // 使用接口 + + @GetMapping("select") + public List getGradeSelect(UserSysRole curRole) { + return baseSchsystemGradeService.getGradeSelect(curRole.getSchId(),null,null); + } + + @GetMapping("selectBySchsystemId") + public List getGradeSelect(UserSysRole curRole,@RequestParam Integer schsystemId) { + return baseSchsystemGradeService.getGradeSelect(curRole.getSchId(),schsystemId,null); + } + + @GetMapping("selectBySchId") + public List getGradeSelect(@RequestParam Integer schId) { + return baseSchsystemGradeService.getGradeSelect(schId,null,null); + } + + @GetMapping("selectByMajorsId") + public List getGradeByMajorsId(UserSysRole curRole,@RequestParam Integer majorsId) { + return baseSchsystemGradeService.getGradeByMajorsId(curRole.getSchId(),majorsId); + } + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchStudentController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchStudentController.java new file mode 100644 index 0000000..14ad039 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchStudentController.java @@ -0,0 +1,233 @@ +package com.bestsch.bschclassmanage.controller.api; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.controller.BaseController; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.enums.StuAbnormalStatus; +import com.bestsch.bschclassmanage.model.dto.StuAbnormalStatusDTO; +import com.bestsch.bschclassmanage.model.dto.StuTransferClassDTO; +import com.bestsch.bschclassmanage.model.excel.ImportRuleExcelColumn; +import com.bestsch.bschclassmanage.model.excel.StudentExcelColumn; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchStudentVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.service.ISchStudentService; +import com.bestsch.bschclassmanage.utils.EasyPoiUtils; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@RestController +@RequestMapping(Config.API_PATH+"/student/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchStudentController extends BaseController { + + @Autowired + private ISchStudentService schStudentService; // 使用接口 + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private IComSchTreeService comSchTreeService; // 使用接口 + + @GetMapping("baseSchSearch") + public PageVO searchBaseSchStudentVO(UserSysRole curRole, + @RequestParam(required = false) Integer schsystemId, + @RequestParam(required = false) Integer gradeId, + @RequestParam(required = false) Integer classId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schStudentService.searchBaseSchStudentVO(curRole.getSchId(),schsystemId,gradeId,classId,keyword,true,pageable); + } + + @GetMapping("higherSchSearch") + public PageVO searchHigherSchStudentVO(UserSysRole curRole, + @RequestParam(required = false) Integer year, + @RequestParam(required = false) Integer classId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schStudentService.searchHigherSchStudentVO(curRole.getSchId(),year,classId,keyword,true,pageable); + } + + @GetMapping("baseSchAbnormalSearch") + public PageVO baseSchAbnormalSearch(UserSysRole curRole, + @RequestParam(required = false) Integer schsystemId, + @RequestParam(required = false) Integer gradeId, + @RequestParam(required = false) Integer classId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schStudentService.searchBaseSchStudentVO(curRole.getSchId(),schsystemId,gradeId,classId,keyword,false,pageable); + } + + @GetMapping("higherSchAbnormalSearch") + public PageVO higherSchAbnormalSearch(UserSysRole curRole, + @RequestParam(required = false) Integer year, + @RequestParam(required = false) Integer classId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schStudentService.searchHigherSchStudentVO(curRole.getSchId(),year,classId,keyword,false,pageable); + } + + @GetMapping("searchSchClassStudent") + public List searchSchClassStudentVO(UserSysRole curRole, + @RequestParam Integer gradeId, + @RequestParam Integer classId) { + return schStudentService.searchSchClassStudentVO(curRole.getSchId(),gradeId,classId,true); + } + + + @PostMapping("save") + public void saveStudent(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody SchStudentVO model) { + schStudentService.saveStudent(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("delete/{ids}") + public void deleteStudent(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable String ids) { + schStudentService.deleteStudent(UserContext.getCurrentUserInfo(),ids); + } + + @GetMapping("abnormal") + public List abnormal() { + return StuAbnormalStatus.select(); + } + + + @PostMapping("transferClass") + public void transferClass(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody StuTransferClassDTO model) { + schStudentService.transferClass(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("setAbnormalStatus") + public void setAbnormalStatus(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody StuAbnormalStatusDTO model) { + schStudentService.setAbnormalStatus(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("setTransferOut/{ids}") + public void setTransferOut(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable String ids){ + schStudentService.setTransferOut(UserContext.getCurrentUserInfo(),ids); + } + + @PostMapping("setTransferIn") + public void setTransferIn(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody StuTransferClassDTO model) { + schStudentService.setTransferIn(UserContext.getCurrentUserInfo(),model); + } + + @GetMapping("transferOutSchSelect") + public List transferOutSchSelect(){ + return schStudentService.transferOutSchSelect(); + } + + @GetMapping("searchTransferOut") + public PageVO searchTransferOutStudent(@RequestParam(required = false) Integer schId, + @RequestParam(required = false) Integer gradeId, + @RequestParam(required = false) Integer classId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schStudentService.searchTransferOutStudent(schId,gradeId,classId,keyword,pageable); + } + + + @GetMapping("downloadTemplate") + public void downloadTemplate(HttpServletResponse response,Integer schId) { + String fileName="学生导入模板"; + List> sheets = new ArrayList<>(); + + List stuList=new ArrayList<>(); + { + StudentExcelColumn column=new StudentExcelColumn(); + column.setGradeName("示例:初一"); + column.setClazzName("示例:1班"); + column.setStuName("示例:小明"); + column.setAccount ("示例:430********4321"); + column.setPassword ("示例:p123456@"); + column.setIdCard("示例:430********4321"); + column.setClazzNo("示例:01"); + column.setGender("示例:男"); + stuList.add(column); + } + + List gradeList=baseSchsystemGradeService.getGradeSelect(schId,null,null) + .stream().collect(Collectors.toList()); + + List schClassList=schClassService.getSchClassCacheList(schId); + + List ruleList = new ArrayList<>(); + + + for(SelectIntVO grade:gradeList){ + ImportRuleExcelColumn rule = new ImportRuleExcelColumn(); + rule.setRuleItem(grade.getName()); + rule.setDescription("选择班级:"); + List clazzNames=schClassList.stream() + .filter(s->s.getGradeId().equals(grade.getId())) + .map(s->s.getName()) + .collect(Collectors.toList()); + rule.setContent(clazzNames.isEmpty() ? "暂无班级":String.join("、",clazzNames)); + ruleList.add(rule); + } + + ExportParams params1 = new ExportParams("学生导入",comSchTreeService.getSchoolName(schId)); + + Map sheet1 = new HashMap<>(); + sheet1.put("title",params1); + sheet1.put("entity", StudentExcelColumn.class); + sheet1.put("data", stuList); + sheets.add(sheet1); + + ExportParams params2 = new ExportParams("导入规则", "导入规则"); + + Map sheet2 = new HashMap<>(); + sheet2.put("title", params2); + sheet2.put("entity", ImportRuleExcelColumn.class); + sheet2.put("data", ruleList); + sheets.add(sheet2); + + Workbook workbook = ExcelExportUtil.exportExcel(sheets, ExcelType.HSSF); + EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook); + } + + @GetMapping("studentClassNoTemplate") + public void studentClassNoTemplate(HttpServletResponse response, Integer schId, + @RequestParam(required = false) Integer schsystemId, + @RequestParam(required = false) Integer gradeId, + @RequestParam(required = false) Integer classId){ + schStudentService.studentClassNoTemplate(response,schId,schsystemId,gradeId,classId); + } + + @PostMapping("importStudents") + public void importStudents(BoaUser authUserWithDept, UserSysRole curRole, @RequestPart("file") MultipartFile file) { + schStudentService.importStudents(UserContext.getCurrentUserInfo(),file); + } + + @PostMapping("importStudentClassNo") + public void importStudentClassNo(BoaUser authUserWithDept, UserSysRole curRole, @RequestPart("file") MultipartFile file, + @RequestParam(required = false) Integer schsystemId, + @RequestParam(required = false) Integer gradeId, + @RequestParam(required = false) Integer classId) { + schStudentService.importStudentClassNo(UserContext.getCurrentUserInfo(),file,schsystemId,gradeId,classId); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchSubjectController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchSubjectController.java new file mode 100644 index 0000000..4142bcf --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchSubjectController.java @@ -0,0 +1,51 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchDicSubject; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.service.ISchDicSubjectService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import javax.validation.Valid; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/subject/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchSubjectController { + + @Autowired + private ISchDicSubjectService schDicSubjectService; // 使用接口 + + @GetMapping("list") + public List getSchSubList(UserSysRole curRole, Integer schSystemId) { + return schDicSubjectService.getSchSubList(curRole.getSchId(),schSystemId); + } + + @PostMapping("save") + public void saveSchSub(BoaUser authUserWithDept,UserSysRole curRole,@Valid @RequestBody SchDicSubject model) { + schDicSubjectService.saveSchSub(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("sort") + public void schSubSort(BoaUser authUserWithDept, UserSysRole curRole, Integer schSystemId, @RequestBody List subIds) { + schDicSubjectService.schSubSort(UserContext.getCurrentUserInfo(),subIds,schSystemId); + } + + @PostMapping("delete/{id}") + public void delSchSub(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable Integer id) { + UserContext.UserInfo user=UserContext.getCurrentUserInfo(); + schDicSubjectService.delSchSub(user,id); + } + + @GetMapping("select") + public List select(UserSysRole curRole,@RequestParam(required = false) Integer schSystemId) { + return schDicSubjectService.select(curRole.getSchId(),schSystemId); + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTeachController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTeachController.java new file mode 100644 index 0000000..3df3107 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTeachController.java @@ -0,0 +1,181 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.controller.BaseController; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.*; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.*; + + +@RestController +@RequestMapping(Config.API_PATH+"/teachs/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchTeachController extends BaseController { + + @Autowired + private ISchClassTeachService schClassTeachService; //使用接口 + + @Autowired + private ISchDicSubjectService schDicSubjectService; //使用接口 + + @Autowired + private ISchClassService schClassService; //使用接口 + + @Autowired + private ISchTeacherService schTeacherService; //使用接口 + + @GetMapping("search") + public SchTeachMapVO getSchTeachMapVO(UserSysRole curRole, + @RequestParam(required = true) Integer schsystemId, + @RequestParam(required = false) Integer gradeId) { + return schClassTeachService.getSchTeachMapVO(curRole.getSchId(),schsystemId,gradeId); + } + + @GetMapping("getSchClassTeach") + public List getSchClassTeachMapVO(UserSysRole curRole, @RequestParam Integer gradeId,@RequestParam Integer classId) { + return schClassTeachService.getSchClassTeachMapVO(curRole.getSchId(),gradeId,classId); + } + + @PostMapping("save") + public void saveTeach(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody SchClassTeach model) { + schClassTeachService.saveTeach(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("delete/{id}") + public void delTeachById(BoaUser authUserWithDept, UserSysRole curRole, @PathVariable Integer id) { + schClassTeachService.delTeachById(UserContext.getCurrentUserInfo(),id); + } + + @PostMapping("delClassTeach") + public void delClassTeach(BoaUser authUserWithDept, UserSysRole curRole,@RequestParam Integer classId) { + schClassTeachService.delClassTeach(UserContext.getCurrentUserInfo(),classId); + } + + @PostMapping("delBatch") + public void delBatch(BoaUser authUserWithDept, UserSysRole curRole,@RequestParam Integer schsystemId, @RequestParam(required = false) Integer gradeId) { + schClassTeachService.delBatch(UserContext.getCurrentUserInfo(),schsystemId,gradeId); + } + + + + + @GetMapping("downloadTemplate") + public void downloadTemplate(HttpServletResponse response,@RequestParam Integer schId,@RequestParam Integer schsystemId, @RequestParam(required = false) Integer gradeId) throws IOException { + + // 2. 获取科目和班级 + List subList = schDicSubjectService.select(schId, schsystemId); + if (subList == null) subList = Collections.emptyList(); + List schClassList = schClassService.searcBaseSchClass(schId, schsystemId, gradeId,null); + if (schClassList == null) schClassList = Collections.emptyList(); + + // 3. 创建工作簿 + Workbook workbook = new HSSFWorkbook(); // 或 XSSFWorkbook + Sheet sheet = workbook.createSheet("教师任教导入"); + + // 4. 构建表头 + Row headerRow = sheet.createRow(0); + int colIdx = 0; + headerRow.createCell(colIdx++).setCellValue("年级"); + headerRow.createCell(colIdx++).setCellValue("班级"); + for (SelectStrVO sub : subList) { + headerRow.createCell(colIdx++).setCellValue(sub.getName()); + } + + // 5. 填充数据行 + int rowIdx = 1; + for (BaseSchClassVO clzz : schClassList) { + Row row = sheet.createRow(rowIdx++); + colIdx = 0; + row.createCell(colIdx++).setCellValue(clzz.getGradeName()); + row.createCell(colIdx++).setCellValue(clzz.getName()); + for (int i = 0; i < subList.size(); i++) { + row.createCell(colIdx++).setCellValue(""); + } + } + + // 6. 自动调整列宽(可选) + for (int i = 0; i < 2 + subList.size(); i++) { + sheet.autoSizeColumn(i); + } + + // 7. 下载 + String fileName = "教师任教导入模板.xls"; + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + workbook.write(response.getOutputStream()); + workbook.close(); + } + + @GetMapping("export") + public void export(HttpServletResponse response,@RequestParam Integer schId,@RequestParam Integer schsystemId, @RequestParam(required = false) Integer gradeId) throws IOException { + + // 2. 获取科目和班级 + List subList = schDicSubjectService.select(schId, schsystemId); + if (subList == null) subList = Collections.emptyList(); + List schClassList = schClassService.searcBaseSchClass(schId, schsystemId, gradeId,null); + if (schClassList == null) schClassList = Collections.emptyList(); + Map schTeacherMap=schTeacherService.toIdAndNameMap(schId); + List schClassTeachList=schClassTeachService.getSchClassTeachCacheList(schId,gradeId,null); + + // 3. 创建工作簿 + Workbook workbook = new HSSFWorkbook(); // 或 XSSFWorkbook + Sheet sheet = workbook.createSheet("教师任教导出"); + + // 4. 构建表头 + Row headerRow = sheet.createRow(0); + int colIdx = 0; + headerRow.createCell(colIdx++).setCellValue("年级"); + headerRow.createCell(colIdx++).setCellValue("班级"); + for (SelectStrVO sub : subList) { + headerRow.createCell(colIdx++).setCellValue(sub.getName()); + } + + // 5. 填充数据行 + int rowIdx = 1; + for (BaseSchClassVO clzz : schClassList) { + Row row = sheet.createRow(rowIdx++); + colIdx = 0; + row.createCell(colIdx++).setCellValue(clzz.getGradeName()); + row.createCell(colIdx++).setCellValue(clzz.getName()); + for (SelectStrVO sub:subList) { + Optional classTeachOpt= schClassTeachList.stream().filter(s->s.getClassId().equals(clzz.getClassId())&&s.getSubId().equals(sub.getId())).findFirst(); + row.createCell(colIdx++).setCellValue(classTeachOpt.isPresent()?schTeacherMap.get(classTeachOpt.get().getTeaId()):""); + } + } + + // 6. 自动调整列宽(可选) + for (int i = 0; i < 2 + subList.size(); i++) { + sheet.autoSizeColumn(i); + } + + // 7. 下载 + String fileName = "教师任教导出.xls"; + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + workbook.write(response.getOutputStream()); + workbook.close(); + } + + @PostMapping("importTeach") + public void importTeach(BoaUser authUserWithDept, UserSysRole curRole, @RequestPart("file") MultipartFile file,@RequestParam Integer schsystemId, @RequestParam(required = false) Integer gradeId) { + schClassTeachService.importTeach(UserContext.getCurrentUserInfo(),file,schsystemId,gradeId); + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTeacherController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTeacherController.java new file mode 100644 index 0000000..d83eb5d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTeacherController.java @@ -0,0 +1,143 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.controller.BaseController; +import com.bestsch.bschclassmanage.model.dto.SchTeacherDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferGroupDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferInGroupDTO; +import com.bestsch.bschclassmanage.model.excel.TeacherExcelColumn; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchTeacherTOutVO; +import com.bestsch.bschclassmanage.model.vo.SchTeacherVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.utils.EasyPoiUtils; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/teacher/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchTeacherController extends BaseController { + + @Autowired + private ISchTeacherService schTeacherService; // 使用接口 + + @Autowired + private IComSchTreeService comSchTreeService; // 使用接口 + + @GetMapping("search") + public PageVO searchSchTeacher(UserSysRole curRole, + @RequestParam(required = false) Integer groupId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schTeacherService.searchSchTeacher(curRole.getSchId(),groupId,keyword,pageable); + } + + @GetMapping("searchTransferOut") + public PageVO searchTransferOutTeacher(@RequestParam(required = false) Integer schId, + @RequestParam(required = false) Integer groupId, + @RequestParam(required = false) String keyword, + Pageable pageable) { + return schTeacherService.searchTransferOutTeacher(schId,groupId,keyword,pageable); + } + + @PostMapping("save") + public void saveTeacher(BoaUser authUserWithDept, UserSysRole curRole, @Valid @RequestBody SchTeacherDTO model) { + schTeacherService.saveTeacher(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("delete/{ids}") + public void deleteTeacher(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable String ids ) { + schTeacherService.deleteTeacher(UserContext.getCurrentUserInfo(),ids); + } + + + @PostMapping("moveGroup") + public void moveGroup(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody TeaTransferGroupDTO model) { + schTeacherService.moveGroup(UserContext.getCurrentUserInfo(),model); + } + + @PostMapping("setStatus") + public void setTeacherStatus(BoaUser authUserWithDept, UserSysRole curRole, String ids,Integer status){ + schTeacherService.setTeacherStatus(UserContext.getCurrentUserInfo(),ids,status); + } + + @GetMapping("groupSelect") // 当前用户 + public List toTeacherGroupSelect(UserSysRole curRole) { + return schTeacherService.toTeacherGroupSelect(curRole.getSchId()); + } + + @GetMapping("groupSelectBySchId") + public List toTeacherGroupSelect(@RequestParam Integer schId) { + return schTeacherService.toTeacherGroupSelect(schId); + } + + @GetMapping("select") + public List toIdAndNameSelect(UserSysRole curRole,@RequestParam(required = false) Integer groupId) { + return schTeacherService.toIdAndNameSelect(groupId,curRole.getSchId()); + } + + @GetMapping("transferOutSchSelect") + public List transferOutSchSelect() { + return schTeacherService.transferOutSchSelect(); + } + + + @PostMapping("setTransferOut/{ids}") + public void setTransferOut(BoaUser authUserWithDept, UserSysRole curRole,@PathVariable String ids){ + schTeacherService.setTransferOut(UserContext.getCurrentUserInfo(),ids); + } + + @PostMapping("setTransferIn") + public void setTransferIn(BoaUser authUserWithDept, UserSysRole curRole,@Valid @RequestBody TeaTransferInGroupDTO model) { + schTeacherService.setTransferIn(UserContext.getCurrentUserInfo(),model); + } + + @GetMapping("downloadTemplate") + public void downloadTemplate(UserSysRole curRole,HttpServletResponse response) { + List list=new ArrayList<>(); + String fileName="教师导入模板"; + String titleName ="教师信息导入" ; + ExportParams exportParams = new ExportParams(titleName, ""); + List teaGroupNameList = comSchTreeService.getTeaGroupNameList(curRole.getSchId(),null); + for (SelectIntVO group:teaGroupNameList) + { + TeacherExcelColumn column=new TeacherExcelColumn(); + column.setGroupName(group.getName()); + column.setAccount(""); + column.setPassword(""); + column.setTeaName(""); + column.setIdCard(""); + column.setTel(""); + column.setGender(""); + list.add(column); + } + Workbook workbook2 = ExcelExportUtil.exportExcel(exportParams, TeacherExcelColumn.class, list); + EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook2); + } + + @PostMapping("importTeachers") + public void importTeachers(BoaUser authUserWithDept, UserSysRole curRole,@RequestPart("file") MultipartFile file) { + schTeacherService.importTeachers(UserContext.getCurrentUserInfo(),file); + } + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTreeController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTreeController.java new file mode 100644 index 0000000..bedf319 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchTreeController.java @@ -0,0 +1,84 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.tool.BaseTree; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.SchSystemTreeVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/tree/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchTreeController { + + @Autowired + private IComSchTreeService comSchTreeService; + + + @GetMapping("getGroupTree") + public List getGroupTree() + { + return comSchTreeService.getGroupTree(); + } + + @GetMapping("getTeacherTree") + public BaseTree getTeacherTree(UserSysRole curRole) + { + return comSchTreeService.getTeacherTree(curRole.getSchId()); + } + + + @GetMapping("getSchoolList") + public List getSchoolList() + { + return comSchTreeService.getSchoolList(); + } + + @GetMapping("getGradeTree") + public SchSystemTreeVO getGradeTree(UserSysRole curRole) + { + return comSchTreeService.getGradeTree(curRole.getSchId()); + } + + @GetMapping("getClassTree") + public SchSystemTreeVO getClassTree(UserSysRole curRole) + { + return comSchTreeService.getClassTree(curRole.getSchId()); + } + + @GetMapping("getClassHistoryTree") + public SchSystemTreeVO getClassHistoryTree(UserSysRole curRole) + { + return comSchTreeService.getClassHistoryTree(curRole.getSchId()); + } + + + @GetMapping("getHigherSchGradeTree") + public SchSystemTreeVO getHigherSchGradeTree(UserSysRole curRole) + { + return comSchTreeService.getHigherSchGradeTree(curRole.getSchId()); + } + + @GetMapping("getHigherSchClassTree") + public SchSystemTreeVO getHigherSchClassTree(UserSysRole curRole) + { + return comSchTreeService.getHigherSchClassTree(curRole.getSchId()); + } + + + @GetMapping("getTeaTree") + public BaseTree getTeaTree(UserSysRole curRole) + { + return comSchTreeService.getTeaTree(curRole.getSchId()); + } + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SchsystemController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchsystemController.java new file mode 100644 index 0000000..dad5244 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SchsystemController.java @@ -0,0 +1,134 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchBinSchsystem; +import com.bestsch.bschclassmanage.enums.UserRole; +import com.bestsch.bschclassmanage.enums.UserType; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.AcademicStageSchsystemVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchBinSchsystemService; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.*; +import java.util.stream.Collectors; + + +@RestController +@RequestMapping(Config.API_PATH+"/schsystem/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchsystemController { + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; // 使用接口 + + @Autowired + private IComSchTreeService comSchTreeService; // 使用接口 + /** + * 获取学段枚举 + 学制列表 + * @return 学段分组后的学制列表 + */ + @GetMapping("list") + public List getAcademicStageSchsystemList(BoaUser authUserWithDept, UserSysRole curRole, + @RequestParam(required = false) Integer schId) { + + int roleId = curRole.getRoleId(); + boolean isSuperAdmin = UserType.SUPER_ADMINISTRATOR.getId().equals(authUserWithDept.getType()); + boolean isAreaAdmin = UserRole.AREAADMIN.getValue().equals(roleId); + + if (!isSuperAdmin && !isAreaAdmin) { + throw new NullPointerException("无权操作,仅超级管理员或学校管理员可设置学制"); + } + + // 3. 确定最终操作的学校ID,并校验 + Integer targetSchId; + if (isAreaAdmin) { + // 区域管理员:强制使用自己所属的学校,忽略前端传入的schId + targetSchId = curRole.getSchId(); + if (targetSchId == null || targetSchId <= 0) { + throw new NullPointerException("当前学校管理员未关联有效的学校"); + } + } else { // 超管 + if (schId == null || schId <= 0) { + throw new NullPointerException("学校ID不能为空且必须为正整数"); + } + targetSchId = schId; + } + + + return schBinSchsystemService.getAcademicStageSchsystemList(targetSchId); + } + + @GetMapping("getType") + public Integer getSchType(UserSysRole curRole) { + return schBinSchsystemService.getSchType(curRole.getSchId()); + } + + /** + * 学校选择学制 + * @return 学段分组后的学制列表 + */ + @PostMapping("save") + @OperationLog(module = "绑定学制") + public void saveSchBinSchsystem(BoaUser authUserWithDept, UserSysRole curRole, + @RequestParam(required = false) Integer schId, + @RequestParam("schsystemIds") String schsystemIdsStr) { + + UserContext.UserInfo user= UserContext.getCurrentUserInfo(); + // 2. 角色权限校验 + int roleId = user.getRoleId(); + boolean isSuperAdmin = UserType.SUPER_ADMINISTRATOR.getId().equals(authUserWithDept.getType()); + boolean isAreaAdmin = UserRole.AREAADMIN.getValue().equals(roleId); + + if (!isSuperAdmin && !isAreaAdmin) { + throw new NullPointerException("无权操作,仅超级管理员或学校管理员可设置学制"); + } + + // 3. 确定最终操作的学校ID,并校验 + Integer targetSchId; + if (isAreaAdmin) { + // 区域管理员:强制使用自己所属的学校,忽略前端传入的schId + targetSchId = curRole.getSchId(); + if (targetSchId == null || targetSchId <= 0) { + throw new NullPointerException("当前学校管理员未关联有效的学校"); + } + } else { // 超管 + if (schId == null || schId <= 0) { + throw new NullPointerException("学校ID不能为空且必须为正整数"); + } + targetSchId = schId; + } + String schName= comSchTreeService.getSchoolName(targetSchId); + // 4. 转换学制ID数组 + Integer[] schsystemIds = OtherUtil.convertToArray(schsystemIdsStr); + + List schsystemNames= schBinSchsystemService.selectSchBinSchsystem(targetSchId) + .stream().filter(s-> Arrays.asList(schsystemIds).contains(s.getId())) + .map(s->s.getName()).collect(Collectors.toList()); + + LogContextHolder.setDescription(String.format("为学校 %d 绑定学制:%s", schName,String.join(",",schsystemNames) )); + if (schsystemIds == null || schsystemIds.length == 0) { + throw new NullPointerException("学制ID列表无效"); + } + SchBinSchsystem entity=new SchBinSchsystem(); + OtherUtil.setBaseEntityValue(user, entity); + entity.setSchId(targetSchId); + // 5. 调用服务 + schBinSchsystemService.saveSchBinSchsystem(entity, schsystemIds); + } + + @GetMapping("select") + public List selectSchBinSchsystem(UserSysRole curRole) { + return schBinSchsystemService.selectSchBinSchsystem(curRole.getSchId()); + } + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/api/SystemYearTermController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/SystemYearTermController.java new file mode 100644 index 0000000..8206e8e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/SystemYearTermController.java @@ -0,0 +1,54 @@ +package com.bestsch.bschclassmanage.controller.api; + + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.BaseYearTerm; +import com.bestsch.bschclassmanage.model.dto.BaseYearTermDTO; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.bestsch.bschclassmanage.model.vo.BaseYearTermVO; +import com.bestsch.bschclassmanage.service.IBaseYearTermService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.model.BoaUser; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.Date; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH+"/yearterm/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SystemYearTermController { + + @Autowired + private IBaseYearTermService baseYearTermService; // 使用接口 + + @GetMapping("list") + public List getAllYearTerm() { + return baseYearTermService.getAllYearTermVO(); + } + + @PostMapping("add") + public void createYearTerm(BoaUser authUserWithDept, UserSysRole curRole, + @Valid @RequestBody BaseYearTermDTO dto) { + BaseYearTerm entity = new BaseYearTerm(); + entity.setCreateDate(new Date()); + entity.setCreateUserId(authUserWithDept.getId()); + BeanUtils.copyProperties(dto, entity); + baseYearTermService.createNowYearTerm(UserContext.getCurrentUserInfo(),entity); + } + + @PostMapping("edit") + public void updateYearTerm(BoaUser authUserWithDept, UserSysRole curRole, + @Valid @RequestBody BaseYearTermDTO dto) { + BaseYearTerm entity = new BaseYearTerm(); + entity.setUpdateDate(new Date()); + entity.setUpdateUserId(authUserWithDept.getId()); + BeanUtils.copyProperties(dto, entity); + baseYearTermService.updateYearTerm(UserContext.getCurrentUserInfo(),entity); + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/UserController.java b/src/main/java/com/bestsch/bschclassmanage/controller/api/UserController.java similarity index 64% rename from src/main/java/com/bestsch/classicalchinese/controller/api/UserController.java rename to src/main/java/com/bestsch/bschclassmanage/controller/api/UserController.java index 7e1471c..f289c73 100644 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/UserController.java +++ b/src/main/java/com/bestsch/bschclassmanage/controller/api/UserController.java @@ -1,11 +1,11 @@ -package com.bestsch.classicalchinese.controller.api; +package com.bestsch.bschclassmanage.controller.api; -import com.bestsch.openapi.BoaModule; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.classicalchinese.config.Config; -import org.springframework.beans.factory.annotation.Autowired; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.tool.UserSysRole; +import com.yunhai.platform.openapi.client.YschBaseOpenApi; +import com.yunhai.platform.utils.model.BoaModule; +import com.yunhai.platform.utils.model.BoaUser; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -18,15 +18,13 @@ import java.util.List; @RestController @RequestMapping(Config.API_PATH +"/base/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") public class UserController { - @Autowired - private BschBaseOpenApi bschBaseOpenApi; @GetMapping("getUserMod") - public List getUserMod(BoaUser authUserWithDept) { - return bschBaseOpenApi.getUserModule(authUserWithDept.getId()); + public List getUserMod(BoaUser authUserWithDept, UserSysRole curRole) { + return YschBaseOpenApi.getUserModule(authUserWithDept.getId(),curRole.getSchId()); } @GetMapping("getUserInfo") diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/SchGroupController.java b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/SchGroupController.java new file mode 100644 index 0000000..ade19f9 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/SchGroupController.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.controller.oapi.oa; + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.vo.oa.SchInfoVO; +import com.bestsch.bschclassmanage.service.ISchInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping(Config.OAPI+"/SchGroup/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchGroupController { + + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/SchInfoController.java b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/SchInfoController.java new file mode 100644 index 0000000..f6ab5a3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/SchInfoController.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.controller.oapi.oa; + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.vo.oa.SchInfoVO; +import com.bestsch.bschclassmanage.service.ISchInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping(Config.OAPI+"/SchInfo/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SchInfoController { + + @Autowired + private ISchInfoService schInfoService; + + @GetMapping("GetSchlist") + public ResponseEntity> GetSchlist(@RequestParam(required = false)String SchIDArr) { + return ResponseEntity.ok(schInfoService.getSchVOList(SchIDArr)); + } + + @GetMapping("GetSchFirst") + public ResponseEntity GetSchFirst(@RequestParam String SchID) { + return ResponseEntity.ok(schInfoService.GetSchFirst(SchID)); + } + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/TeainfoController.java b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/TeainfoController.java new file mode 100644 index 0000000..32ea5d9 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/TeainfoController.java @@ -0,0 +1,139 @@ +package com.bestsch.bschclassmanage.controller.oapi.oa; + +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.UserGender; +import com.bestsch.bschclassmanage.enums.UserRole; +import com.bestsch.bschclassmanage.model.oa.TeaInfoVO; +import com.bestsch.bschclassmanage.model.vo.oa.SchInfoVO; +import com.bestsch.bschclassmanage.service.ISchInfoService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@RestController +@RequestMapping(Config.OAPI+"/OATea/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class TeainfoController { + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private ISchInfoService schInfoService; + + @GetMapping("GetTeainfo") + public ResponseEntity getTeainfo(@RequestParam Integer uid) { + // 1. 参数校验 + if (uid == null) { + return ResponseEntity.badRequest().build(); + } + + // 2. 直接使用 uid 查询 + return schTeacherRepository.findByTeaId(uid) // 假设 findByTeaId 返回 Optional + .map(this::convertToTeaInfoVO) // 将 SchTeacher 转为 TeaInfoVO + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + private TeaInfoVO convertToTeaInfoVO(SchTeacher teacher) { + if (teacher == null) { + return null; + } + TeaInfoVO vo = new TeaInfoVO(); + + // 直接映射 + vo.setAccount(teacher.getAccount()); + vo.setName(teacher.getName()); + vo.setTeaIDCard(teacher.getIdCard()); + vo.setTel(teacher.getTel()); + vo.setTeaNo(teacher.getSort()); + vo.setRole(UserRole.TEACHER_USER.getValue()); + + if (teacher.getGender() != null) { + String sex = UserGender.nameById(teacher.getGender()); + vo.setTeaSex(sex); + } + + // TeaSerID 使用 teaId(转为字符串)或 id + if (teacher.getTeaId() != null) { + vo.setTeaSerID(teacher.getTeaId().toString()); + } else { + vo.setTeaSerID(teacher.getId().toString()); + } + + List groupList=teacher.getGroupList(); + if(groupList==null||groupList.isEmpty()) + return null; + + // 其他字段默认 null(或根据业务设置默认值) + SchInfoVO schInfoVO= schInfoService.GetSchFirst(groupList.stream().findFirst().get().getSchId()); + + vo.setSchSerID(schInfoVO==null?null:schInfoVO.getSchSerId()); + vo.setGroupID(groupList.stream().findFirst().get().getGroupId()); + vo.setSchSerIDs(schInfoVO==null?null:schInfoVO.getSchSerId()); + return vo; + } + + @PostMapping("GetArrTeainfo") + public ResponseEntity> getArrTeainfo(@RequestBody String userIds) { + // 1. 参数校验 + if (userIds == null) { + return ResponseEntity.badRequest().build(); + } + + List uids= Arrays.asList(OtherUtil.convertToArray(userIds)); + + List teachers = schTeacherRepository.findByTeaIdIn(uids); + List voList = teachers.stream() + .map(this::convertToTeaInfoVO) + .collect(Collectors.toList()); + + return voList.isEmpty() ? ResponseEntity.noContent().build() : ResponseEntity.ok(voList); + } + + @GetMapping("GetSchTeainfo") + public ResponseEntity> getSchTeainfo(@RequestParam String SchSerID) { + // 1. 参数校验 + if (SchSerID == null) { + return ResponseEntity.badRequest().build(); + } + + SchInfoVO schInfoVO= schInfoService.GetSchFirst(SchSerID); + if(schInfoVO==null) + { + return ResponseEntity.badRequest().build(); + } + Integer schId=schInfoVO.getUserSchSerId(); + + List teachers = schTeacherService.getSchTeacherList(schId); + + List voList = teachers.stream() + .map(this::convertToTeaInfoVO) + .collect(Collectors.toList()); + + return voList.isEmpty() ? ResponseEntity.noContent().build() : ResponseEntity.ok(voList); + } + + @GetMapping("GetSchTeaList") + public ResponseEntity> getSchTeaList(@RequestParam String SchSerID) { + return getSchTeainfo(SchSerID); + } + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/UserInfoController.java b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/UserInfoController.java new file mode 100644 index 0000000..b0d6a87 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/oa/UserInfoController.java @@ -0,0 +1,177 @@ +package com.bestsch.bschclassmanage.controller.oapi.oa; + +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.UserRole; +import com.bestsch.bschclassmanage.enums.UserType; +import com.bestsch.bschclassmanage.model.oa.UserInfoVO; +import com.bestsch.bschclassmanage.model.vo.oa.SchInfoVO; +import com.bestsch.bschclassmanage.service.ISchInfoService; +import com.bestsch.bschclassmanage.service.ISchStudentService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@RestController +@RequestMapping(Config.OAPI + "/UserInfo/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class UserInfoController { + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private ISchStudentService schStudentService; + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private ISchInfoService schInfoService; + + @GetMapping("GetUserList") + public ResponseEntity> getUserList(@RequestParam String SchSerID) { + // 1. 参数校验 + if (SchSerID == null || SchSerID.trim().isEmpty()) { + return ResponseEntity.badRequest().build(); + } + + SchInfoVO schInfoVO = schInfoService.GetSchFirst(SchSerID); + if (schInfoVO == null) { + return ResponseEntity.badRequest().build(); + } + Integer schId = schInfoVO.getUserSchSerId(); + + // 2. 获取教师和学生列表(判空) + List teachers = schTeacherService.getSchTeacherCacheList(schId); + List students = schStudentService.getSchGradeClassStudentCacheList(schId, null, null, null); + + // 3. 转换为 UserInfoVO + List voList = new ArrayList<>(); + if (teachers != null) { + voList.addAll(teachers.stream() + .map(this::convertToUserInfoVO) + .filter(vo -> vo != null) // 过滤转换失败的 + .collect(Collectors.toList())); + } + if (students != null) { + voList.addAll(students.stream() + .map(this::convertToUserInfoVO) + .filter(vo -> vo != null) + .collect(Collectors.toList())); + } + + // 4. 返回结果 + return voList.isEmpty() ? ResponseEntity.noContent().build() : ResponseEntity.ok(voList); + } + + // ===== 转换教师 ===== + private UserInfoVO convertToUserInfoVO(SchTeacher teacher) { + if (teacher == null) { + return null; + } + + UserInfoVO vo = new UserInfoVO(); + // 基础字段 + vo.setUids(teacher.getAccount()); + vo.setName(teacher.getName()); + vo.setIDCard(teacher.getIdCard()); + vo.setTel(teacher.getTel()); + vo.setNo(teacher.getSort()); + vo.setSex(teacher.getGender()); + vo.setUserID(teacher.getTeaId()); // 教师用户ID + vo.setUsertype(1); // 假设教师类型为1 + + // 获取学校ID和组ID + List groupList = teacher.getGroupList(); + if (groupList != null && !groupList.isEmpty()) { + SchTeacherGroup firstGroup = groupList.get(0); + vo.setGroupID(firstGroup.getGroupId()); + // 通过组获取学校信息 + SchInfoVO schInfo = schInfoService.GetSchFirst(firstGroup.getSchId()); + // 若没有直接按组查学校的方法,可改为通过组的schId查 + if (schInfo != null) { + vo.setSchSerID(schInfo.getSchSerId()); + } + } else { + // 无分组,可能是管理员或特殊用户,可设置默认或 null + vo.setGroupID(null); + vo.setSchSerID(null); + } + + // 其他字段(如 Photo, SerID 等)如果 SchTeacher 没有,可置 null 或从别处获取 + vo.setPhoto(null); // 可根据 teacher 的某字段补充 + vo.setSerID(null); + return vo; + } + + // ===== 转换学生 ===== + private UserInfoVO convertToUserInfoVO(SchStudent student) { + if (student == null) { + return null; + } + + UserInfoVO vo = new UserInfoVO(); + vo.setUids(student.getAccount()); + vo.setName(student.getName()); + vo.setIDCard(student.getIdCard()); + vo.setTel(null); // 学生表可能无电话,如有则补充 + vo.setNo(null); // 学生表没有 No 字段,可置 null 或从 stuClassNo 转换 + vo.setSex(student.getGender()); + vo.setUserID(student.getStuId()); // 学生用户ID + vo.setUsertype(UserRole.STU_USER.getValue()); // 假设学生类型为2 + + vo.setGroupID(student.getGroupId()); + + SchInfoVO schInfo = schInfoService.GetSchFirst(student.getSchId()); + // 若没有直接按组查学校的方法,可改为通过组的schId查 + if (schInfo != null) { + vo.setSchSerID(schInfo.getSchSerId()); + } + + vo.setPhoto(null); + vo.setSerID(null); + return vo; + } + + @GetMapping("getUserIdList") + public ResponseEntity> getUserIdList(@RequestParam Integer userid) { + if (userid == null) { + return ResponseEntity.badRequest().build(); + } + + Optional teacherOpt = schTeacherRepository.findByTeaId(userid); + if (teacherOpt.isPresent()) { + UserInfoVO vo = convertToUserInfoVO(teacherOpt.get()); + if (vo != null) { + return ResponseEntity.ok(Collections.singletonList(vo)); + } + } + + Optional studentOpt = schStudentRepository.findByStuId(userid); + if (studentOpt.isPresent()) { + UserInfoVO vo = convertToUserInfoVO(studentOpt.get()); + if (vo != null) { + return ResponseEntity.ok(Collections.singletonList(vo)); + } + } + + return ResponseEntity.notFound().build(); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/oapi/sync/SyncGroupController.java b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/sync/SyncGroupController.java new file mode 100644 index 0000000..354b4fc --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/sync/SyncGroupController.java @@ -0,0 +1,38 @@ +package com.bestsch.bschclassmanage.controller.oapi.sync; + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.tool.BaseGroup; +import com.bestsch.bschclassmanage.service.ISyncGroupService; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping(Config.OAPI+"/group/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SyncGroupController { + + @Autowired + private ISyncGroupService syncGroupService; + + @PostMapping("AddGroup") + public void AddGroup(@RequestBody String jsonString) { + + //判断 2,"学校组" 4, "班级组" + BaseGroup group = OtherUtil.jsonParseObject(jsonString, BaseGroup.class); + syncGroupService.syncAddOrUpdate(group); + } + + @PostMapping("UpdateGroup") + public void UpdateGroup(@RequestBody String jsonString) { + BaseGroup group = OtherUtil.jsonParseObject(jsonString, BaseGroup.class); + syncGroupService.syncAddOrUpdate(group); + } + + @PostMapping("DeleteGroup") + public void DeleteGroup(@RequestBody String jsonString) { + + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/controller/oapi/sync/SyncUserController.java b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/sync/SyncUserController.java new file mode 100644 index 0000000..063c10a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/controller/oapi/sync/SyncUserController.java @@ -0,0 +1,41 @@ +package com.bestsch.bschclassmanage.controller.oapi.sync; + +import com.bestsch.bschclassmanage.config.Config; +import com.bestsch.bschclassmanage.model.tool.BaseGroup; +import com.bestsch.bschclassmanage.model.tool.BaseUser; +import com.bestsch.bschclassmanage.model.tool.DeleteUser; +import com.bestsch.bschclassmanage.service.ISyncUserService; +import com.bestsch.bschclassmanage.service.impl.sync.SyncGroupService; +import com.bestsch.bschclassmanage.service.impl.sync.SyncUserService; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping(Config.OAPI+"/user/") +@CrossOrigin(originPatterns = {"*"}, allowCredentials = "true") +public class SyncUserController { + + @Autowired + private ISyncUserService syncUserService; + + @PostMapping("AddUser") + public void AddUser(@RequestBody String jsonString) { + List userlist = OtherUtil.jsonParseList(jsonString, BaseUser.class); + syncUserService.syncAddOrUpdate(userlist); + } + + @PostMapping("UpdateUser") + public void UpdateUser(@RequestBody String jsonString) { + List userList = OtherUtil.jsonParseList(jsonString, BaseUser.class); + syncUserService.syncAddOrUpdate(userList); + } + + @PostMapping("DeleteUser") + public void DeleteUser(@RequestBody String jsonString) { + List deleteUserList= OtherUtil.jsonParseList(jsonString, DeleteUser.class); + syncUserService.deleteUser(deleteUserList); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/BaseDicGrade.java b/src/main/java/com/bestsch/bschclassmanage/entity/BaseDicGrade.java new file mode 100644 index 0000000..228564e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/BaseDicGrade.java @@ -0,0 +1,42 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +/** + * 基础-字典-年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "base_dic_grade") +public class BaseDicGrade { + /** + * 主键(更新时必须提供) + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class) + private Integer id; + + /** + * 年级名称 + */ + @Column(name = "name", length = 255) + private String name; + + /** + * 年级编码 + */ + @Column(name = "code") + private Integer code; + + /** + * 更新校验分组(内部接口) + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/BaseDicSubject.java b/src/main/java/com/bestsch/bschclassmanage/entity/BaseDicSubject.java new file mode 100644 index 0000000..54fb569 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/BaseDicSubject.java @@ -0,0 +1,55 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.*; +import java.io.Serializable; + +/** + * 基础-字典-学科表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "base_dic_subject") +public class BaseDicSubject { + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 学科名称(不能为空,长度不超过255) + */ + @NotBlank(message = "学科名称不能为空") + @Size(max = 255, message = "学科名称长度不能超过255") + @Column(name = "name", length = 255, nullable = false) + private String name; + + /** + * 学科编码(可为空,长度不超过255) + */ + @Size(max = 255, message = "学科编码长度不能超过255") + @Column(name = "code", length = 255) + private String code; + + /** + * 序号(无符号两位整数,范围 0~99,可为空) + */ + @Min(value = 0, message = "序号最小为0") + @Max(value = 99, message = "序号最大为99") + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/BaseEntity.java b/src/main/java/com/bestsch/bschclassmanage/entity/BaseEntity.java new file mode 100644 index 0000000..58893f4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/BaseEntity.java @@ -0,0 +1,53 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.DbFieldNames; +import lombok.Data; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.util.Date; + + +@Data +@MappedSuperclass +public abstract class BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = BaseSchsystem.Update.class, message = "更新时ID不能为空") + private Integer id; + + + /** + * 学校id + */ + @Column(name = DbFieldNames.schId) + private Integer schId; + + + /** + * 创建时间 + */ + @Column(name = DbFieldNames.create_date) + private Date createDate; + + /** + * 修改时间 + */ + @Column(name = DbFieldNames.update_date) + private Date updateDate; + + /** + * 创建用户 + */ + @Column(name = DbFieldNames.create_user_id) + private Integer createUserId; + + /** + * 修改用户 + */ + @Column(name = DbFieldNames.update_user_id) + private Integer updateUserId; + + public @interface Update {} +} diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/BaseSchsystem.java b/src/main/java/com/bestsch/bschclassmanage/entity/BaseSchsystem.java new file mode 100644 index 0000000..0f328c3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/BaseSchsystem.java @@ -0,0 +1,75 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.*; +import java.io.Serializable; + +/** + * 基础-学校学制表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "base_sch_system") +public class BaseSchsystem { + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 学制名称(长度不超过255) + */ + @Size(max = 255, message = "学制名称长度不能超过255") + @Column(name = "name", length = 255) + private String name; + + /** + * 学段编码(0学前 1小学 2初中 3高中 4高等) + */ + @Min(value = 0, message = "学段编码最小为0") + @Max(value = 4, message = "学段编码最大为4") + @Column(name = "academic_stage") + private Integer academicStage; + + /** + * 开始年级编码 + */ + @Column(name = "start_grade_code") + private Integer startGradeCode; + + /** + * 结束年级编码 + */ + @Column(name = "end_grade_code") + private Integer endGradeCode; + + /** + * 毕业年长度 + */ + @Min(value = 0, message = "毕业年长度不能为负数") + @Column(name = "graduation_leng") + private Integer graduationLeng; + + /** + * 教育类型(1基础教育 2职业教育) + */ + @Min(value = 1, message = "教育类型最小为1") + @Max(value = 2, message = "教育类型最大为2") + @Column(name = "type") + private Integer type; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/BaseSchsystemGrade.java b/src/main/java/com/bestsch/bschclassmanage/entity/BaseSchsystemGrade.java new file mode 100644 index 0000000..743e59a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/BaseSchsystemGrade.java @@ -0,0 +1,54 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; + +/** + * 基础-学制年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "base_sch_system_grade") +public class BaseSchsystemGrade { + + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 学制id + */ + @Column(name = "sch_system_id") + private Integer schSystemId; + + /** + * 年级id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 年级别称(长度不超过255) + */ + @Size(max = 255, message = "年级别称长度不能超过255") + @Column(name = "grade_nickname", length = 255) + private String gradeNickname; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/BaseYearTerm.java b/src/main/java/com/bestsch/bschclassmanage/entity/BaseYearTerm.java new file mode 100644 index 0000000..f8cc17c --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/BaseYearTerm.java @@ -0,0 +1,117 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * 学年学期表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "base_year_term") +public class BaseYearTerm { + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + @Column(name = "id") + private Integer id; + + /** + * 学年 + */ + @Column(name = "year") + private Integer year; + + /** + * 学年开始日期 + */ + @Column(name = "year_start_date") + private Date yearStartDate; + + /** + * 学年结束日期 + */ + @Column(name = "year_end_date") + private Date yearEndDate; + + /** + * 第一学期开始日期 + */ + @Column(name = "first_term_start_date") + private Date firstTermStartDate; + + /** + * 第一学期结束日期 + */ + @Column(name = "first_term_end_date") + private Date firstTermEndDate; + + /** + * 第二学期开始日期 + */ + @Column(name = "second_term_Start_date") + private Date secondTermStartDate; + + /** + * 第二学期结束日期 + */ + @Column(name = "second_term_end_date") + private Date secondTermEndDate; + + /** + * 升级日期 + */ + @Column(name = "upgrade_date") + private Date upgradeDate; + + /** + * 创建时间 + */ + @Column(name = "create_date") + private Date createDate; + + /** + * 修改时间 + */ + @Column(name = "update_date") + private Date updateDate; + + /** + * 创建用户 + */ + @Column(name = "create_user_id") + private Integer createUserId; + + /** + * 修改用户 + */ + @Column(name = "update_user_id") + private Integer updateUserId; + + /** + * 更新校验分组 + */ + public @interface Update {} + + @Repository + public static interface SchStuentRepository extends JpaRepository, JpaSpecificationExecutor { + + boolean existsBySchIdAndName(Integer schId, String name); + + boolean existsBySchIdAndNameAndIdNot(Integer schId, String name, Integer id); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/OperationLogRecord.java b/src/main/java/com/bestsch/bschclassmanage/entity/OperationLogRecord.java new file mode 100644 index 0000000..f303837 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/OperationLogRecord.java @@ -0,0 +1,53 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 基础-字典-年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "operation_log") +public class OperationLogRecord { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private Integer operatorId; + + @Column(nullable = false) + private LocalDateTime operateTime; // 操作时间 + + + @Column(nullable = false) + private String operator; // 操作人 + + + @Column(nullable = false) + private String ip; // 客户端IP + + @Column(nullable = false) + private String module; // 模块名称 + + @Column(nullable = false, length = 3000) + private String content; // 操作内容 + + @Column(nullable = false) + private Integer schId; + + + /** + * 更新校验分组(内部接口) + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchBinSchsystem.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchBinSchsystem.java new file mode 100644 index 0000000..53a6ed2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchBinSchsystem.java @@ -0,0 +1,32 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 学校绑定学制表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_bin_sch_system") +public class SchBinSchsystem extends BaseEntity { + + /** + * 学制id(不能为空) + */ + @NotNull(message = "学制id不能为空") + @Column(name = "sch_system_id", nullable = false) + private Integer schSystemId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchClass.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchClass.java new file mode 100644 index 0000000..ec1a134 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchClass.java @@ -0,0 +1,123 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.Date; + +/** + * 学校班级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_class") +public class SchClass extends BaseEntity { + + /** + * 班级编码 + */ + @Size(max = 255, message = "班级编码长度不能超过255") + @Column(name = "code", length = 255) + private String code; + + /** + * 组id(不能为空)年级组 or 年届组 + */ + @NotNull(message = "年级组id不能为空") + @Column(name = "group_grade_id", nullable = false) + private Integer groupId; + + /** + * 组id(不能为空) + */ + @NotNull(message = "班级组id不能为空") + @Column(name = "group_class_id", nullable = false) + private Integer classId; + + + /** + * 班级名称(不能为空) + */ + @NotBlank(message = "班级名称不能为空") + @Size(max = 255, message = "班级名称长度不能超过255") + @Column(name = "name", length = 255, nullable = false) + private String name; + + /** + * 班级别称 + */ + @Size(max = 255, message = "班级别称长度不能超过255") + @Column(name = "cname", length = 255) + private String cname; + + /** + * 班主任 + */ + @Column(name = "first_teacher_id") + private Integer firstTeacherId; + + /** + * 副班主任 + */ + @Column(name = "second_teacher_id") + private Integer secondTeacherId; + + + + /** + * 年级id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 校区id + */ + @Column(name = "campus_id") + private Integer campusId; + + /** + * 系部id + */ + @Column(name = "division_id") + private Integer divisionId; + + /** + * 专业id + */ + @Column(name = "majors_id") + private Integer majorsId; + + /** + * 注册年份 + */ + @Column(name = "enroll_year") + private Integer enrollYear; + + + + /** + * 是否毕业(默认0) + */ + @Column(name = "graduate") + private Boolean graduate; + + /** + * 序号 K12班 根据 sort 定位 职业 班 sort 排序 + */ + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchClassHistory.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchClassHistory.java new file mode 100644 index 0000000..e209c82 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchClassHistory.java @@ -0,0 +1,135 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * 学校班级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_class_history") +public class SchClassHistory extends BaseEntity { + + /** + * 学年 + */ + @Column(name = "year", nullable = false) + private Integer year; + + /** + * 学期:1-第一学期,2-第二学期 + */ + @Column(name = "term", nullable = false) + private Integer term; + + /** + * 班级编码 + */ + @Size(max = 255, message = "班级编码长度不能超过255") + @Column(name = "code", length = 255) + private String code; + + /** + * 组id(不能为空)年级组 or 年届组 + */ + @NotNull(message = "年级组id不能为空") + @Column(name = "group_grade_id", nullable = false) + private Integer groupId; + + /** + * 组id(不能为空) + */ + @NotNull(message = "班级组id不能为空") + @Column(name = "group_class_id", nullable = false) + private Integer classId; + + + /** + * 班级名称(不能为空) + */ + @NotBlank(message = "班级名称不能为空") + @Size(max = 255, message = "班级名称长度不能超过255") + @Column(name = "name", length = 255, nullable = false) + private String name; + + /** + * 班级别称 + */ + @Size(max = 255, message = "班级别称长度不能超过255") + @Column(name = "cname", length = 255) + private String cname; + + /** + * 班主任 + */ + @Column(name = "first_teacher_id") + private Integer firstTeacherId; + + /** + * 副班主任 + */ + @Column(name = "second_teacher_id") + private Integer secondTeacherId; + + + + /** + * 年级id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 校区id + */ + @Column(name = "campus_id") + private Integer campusId; + + /** + * 系部id + */ + @Column(name = "division_id") + private Integer divisionId; + + /** + * 专业id + */ + @Column(name = "majors_id") + private Integer majorsId; + + /** + * 注册年份 + */ + @Column(name = "enroll_year") + private Integer enrollYear; + + + + /** + * 是否毕业(默认0) + */ + @Column(name = "graduate") + private Boolean graduate; + + /** + * 序号 K12班 根据 sort 定位 职业 班 sort 排序 + */ + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchClassTeach.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchClassTeach.java new file mode 100644 index 0000000..1b8c1ff --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchClassTeach.java @@ -0,0 +1,53 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.Date; + +/** + * 学校班级任教表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_class_teach") +public class SchClassTeach extends BaseEntity { + + /** + * 年级id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 学科id(长度不超过255) + */ + @Size(max = 255, message = "学科id长度不能超过255") + @Column(name = "sub_id", length = 255) + private String subId; + + /** + * 班级id + */ + @Column(name = "class_id") + private Integer classId; + + /** + * 教师id + */ + @Column(name = "tea_id") + private Integer teaId; + + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchClassTeachHistory.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchClassTeachHistory.java new file mode 100644 index 0000000..9d6afcb --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchClassTeachHistory.java @@ -0,0 +1,64 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.validation.constraints.Size; + +/** + * 学校班级任教表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_class_teach_history") +public class SchClassTeachHistory extends BaseEntity { + + /** + * 学年 + */ + @Column(name = "year", nullable = false) + private Integer year; + + /** + * 学期:1-第一学期,2-第二学期 + */ + @Column(name = "term", nullable = false) + private Integer term; + + /** + * 年级id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 学科id(长度不超过255) + */ + @Size(max = 255, message = "学科id长度不能超过255") + @Column(name = "sub_id", length = 255) + private String subId; + + /** + * 班级id + */ + @Column(name = "class_id") + private Integer classId; + + /** + * 教师id + */ + @Column(name = "tea_id") + private Integer teaId; + + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCampus.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCampus.java new file mode 100644 index 0000000..aa77ef1 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCampus.java @@ -0,0 +1,44 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +/** + * 学校-字典-校区表 + */ +@JsonIgnoreProperties({EntityFieldNames.schId , EntityFieldNames.createDate, EntityFieldNames.updateDate, EntityFieldNames.createUserId, EntityFieldNames.updateUserId }) +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_campus") +public class SchDicCampus extends BaseEntity{ + + /** + * 校区名称(不能为空) + */ + @NotBlank(message = "校区名称不能为空") + @Size(max = 255, message = "校区名称长度不能超过255") + @Column(name = "name", length = 255, nullable = false) + private String name; + + /** + * 序号(无符号整数,最小0) + */ + @Min(value = 0, message = "序号不能为负数") + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourse.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourse.java new file mode 100644 index 0000000..6e1ad21 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourse.java @@ -0,0 +1,58 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.*; +import java.io.Serializable; +import java.util.Date; + +/** + * 学校-字典-课程表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_course") +public class SchDicCourse extends BaseEntity { + + + /** + * 课程名称(不能为空) + */ + @NotBlank(message = "课程名称不能为空") + @Size(max = 255, message = "课程名称长度不能超过255") + @Column(name = "name", length = 255, nullable = false) + private String name; + + /** + * 课程别称 + */ + @Size(max = 255, message = "课程别称长度不能超过255") + @Column(name = "nickname", length = 255) + private String nickname; + + /** + * 课程编码 + */ + @Size(max = 255, message = "课程编码长度不能超过255") + @Column(name = "code", length = 255) + private String code; + + /** + * 课程类型(1公共课 2选修课 3专业课) + */ + @NotNull(message = "课程类型不能为空") + @Min(value = 1, message = "课程类型最小为1") + @Max(value = 3, message = "课程类型最大为3") + @Column(name = "type") + private Integer type; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourseDivision.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourseDivision.java new file mode 100644 index 0000000..683a7f0 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourseDivision.java @@ -0,0 +1,51 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 课程关联系部表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_course_division") +public class SchDicCourseDivision{ + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 课程id + */ + @Column(name = "course_id") + private Integer courseId; + + /** + * 系部id + */ + @Column(name = "division_id") + private Integer divisionId; + + /** + * 学校id + */ + @Column(name = "sch_id") + private Integer schId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourseMajors.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourseMajors.java new file mode 100644 index 0000000..0086877 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicCourseMajors.java @@ -0,0 +1,52 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 课程关联专业表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_course_majors") +public class SchDicCourseMajors { + + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 课程id + */ + @Column(name = "course_id") + private Integer courseId; + + /** + * 专业id + */ + @Column(name = "majors_id") + private Integer majorsId; + + /** + * 学校id + */ + @Column(name = "sch_id") + private Integer schId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicDivision.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicDivision.java new file mode 100644 index 0000000..95f83dc --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicDivision.java @@ -0,0 +1,42 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; + +/** + * 学校-字典-系部表 + */ +@JsonIgnoreProperties({EntityFieldNames.schId , EntityFieldNames.createDate, EntityFieldNames.updateDate, EntityFieldNames.createUserId, EntityFieldNames.updateUserId }) +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_division") +public class SchDicDivision extends BaseEntity { + + /** + * 系部名称 + */ + @Size(max = 255, message = "系部名称长度不能超过255") + @Column(name = "name", length = 255) + private String name; + + /** + * 序号(无符号整数,最小0) + */ + @Min(value = 0, message = "序号不能为负数") + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicMajors.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicMajors.java new file mode 100644 index 0000000..22349af --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicMajors.java @@ -0,0 +1,56 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; + +/** + * 学校-字典-专业表 + */ +@JsonIgnoreProperties({EntityFieldNames.schId , EntityFieldNames.createDate, EntityFieldNames.updateDate, EntityFieldNames.createUserId, EntityFieldNames.updateUserId }) +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_majors") +public class SchDicMajors extends BaseEntity { + + /** + * 代码 + */ + @Size(max = 100, message = "专业名称长度不能超过50") + @Column(name = "code") + private String code; + + /** + * 专业名称(原表注释误写为“校区名称”,此处纠正) + */ + @Size(max = 255, message = "专业名称长度不能超过255") + @Column(name = "name", length = 255) + private String name; + + /** + * 学制(无符号整数,最小0) + */ + @Min(value = 1, message = "学制长度大于0") + @Column(name = "schsystem_leng") + private Integer schsystemLeng; + + /** + * 序号(无符号整数,最小0) + */ + @Min(value = 0, message = "序号不能为负数") + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchDicSubject.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicSubject.java new file mode 100644 index 0000000..d0b2862 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchDicSubject.java @@ -0,0 +1,75 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.*; + +/** + * 学校-字典-学科表 + */ +@JsonIgnoreProperties({EntityFieldNames.schId , EntityFieldNames.createDate, EntityFieldNames.updateDate, EntityFieldNames.createUserId, EntityFieldNames.updateUserId }) +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_dic_subject") +public class SchDicSubject extends BaseEntity { + + /** + * 学制id(不能为空) + */ + @NotNull(message = "学制id不能为空") + @Column(name = "sch_system_id", nullable = false) + private Integer schSystemId; + + /** + * 学科名称(不能为空) + */ + @NotBlank(message = "学科名称不能为空") + @Size(max = 255, message = "学科名称长度不能超过255") + @Column(name = "name", length = 255, nullable = false) + private String name; + + /** + * 学科编码 + */ + @Size(max = 255, message = "学科编码长度不能超过255") + @Column(name = "code", length = 255) + private String code; + + /** + * 是否启用(默认启用) + */ + @Column(name = "enable") + private Boolean enable = true; + + /** + * 学校id + */ + @Column(name = "sch_id") + private Integer schId; + + /** + *数据来源 0 系统 1学校 + */ + @Min(value = 0, message = "数据来源不能为负数") + @Column(name = "source") + private Integer source; + + /** + * 序号(无符号整数,最小0) + */ + @Min(value = 0, message = "序号不能为负数") + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchInfo.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchInfo.java new file mode 100644 index 0000000..084b28a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchInfo.java @@ -0,0 +1,40 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * 学校班级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_info") +public class SchInfo { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = BaseSchsystem.Update.class, message = "更新时ID不能为空") + private Integer id; + + @Column(name = "sch_id", nullable = false) + private Integer schId; + + @Column(name = "name", length = 255, nullable = false) + private String name; + + @Column(name = "sch_serid", length = 50) + private String schSerId; + + @Column(name = "sort") + private Integer sort; + + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchStudent.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchStudent.java new file mode 100644 index 0000000..272a818 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchStudent.java @@ -0,0 +1,109 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.Date; + +/** + * 学生表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_student") +public class SchStudent extends BaseEntity { + + /** + * 用户id(不能为空) + */ + @Column(name = "stu_id") + private Integer stuId; + + /** + * 学生账户 + */ + @Size(max = 255, message = "学生账户长度不能超过255") + @Column(name = "account", length = 255) + private String account; + + /** + * 学生 + */ + @Size(max = 255, message = "学生班级学号长度不能超过255") + @Column(name = "stu_class_no", length = 255) + private String stuClassNo; + + + /** + * 学生姓名 + */ + @Size(max = 255, message = "学生姓名长度不能超过255") + @Column(name = "name", length = 255) + private String name; + + /** + * 性别(0未知 1男 2女等,根据业务定义) + */ + @Column(name = "gender") + private Integer gender; + + @Size(max = 255, message = "身份证长度不能超过18") + @Column(name = "id_card", length = 18) + private String idCard; + + /** + * 组id(班级) + */ + @Column(name = "group_id") + private Integer groupId; + + /** + * 班级id + */ + @Column(name = "class_id") + private Integer classId; + + /** + * 状态(0禁用 1正常) + */ + @Column(name = "status") + private Integer status; + + /** + * 异常状态(正常、休学、出国、留学、复学、停学、自愿退学、自愿留级、自愿降级、其他) + */ + @Column(name = "abnormal_status") + private Integer abnormalStatus; + + @Column(name = "abnormal_date") + private Date abnormalDate; + + /** + * 转入状态(转出0,转入1) + */ + @Column(name = "transfer_status") + private Integer transferStatus; + + + /** + * 邀请码 + */ + @Size(max = 255, message = "邀请码长度不能超过255") + @Column(name = "invitation_code", length = 255) + private String invitationCode; + + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchStudentHistory.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchStudentHistory.java new file mode 100644 index 0000000..3870860 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchStudentHistory.java @@ -0,0 +1,128 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.validation.constraints.Size; +import java.util.Date; + +/** + * 学生表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_student_history") +public class SchStudentHistory extends BaseEntity { + + /** + * 学年 + */ + @Column(name = "year", nullable = false) + private Integer year; + + /** + * 学期:1-第一学期,2-第二学期 + */ + @Column(name = "term", nullable = false) + private Integer term; + + + + /** + * 用户id(不能为空) + */ + @Column(name = "stu_id") + private Integer stuId; + + /** + * 学生账户 + */ + @Size(max = 255, message = "学生账户长度不能超过255") + @Column(name = "account", length = 255) + private String account; + + /** + * 学生 + */ + @Size(max = 255, message = "学生班级学号长度不能超过255") + @Column(name = "stu_class_no", length = 255) + private String stuClassNo; + + + /** + * 学生姓名 + */ + @Size(max = 255, message = "学生姓名长度不能超过255") + @Column(name = "name", length = 255) + private String name; + + /** + * 性别(0未知 1男 2女等,根据业务定义) + */ + @Column(name = "gender") + private Integer gender; + + @Size(max = 255, message = "身份证长度不能超过18") + @Column(name = "id_card", length = 18) + private String idCard; + + /** + * 组id(班级) + */ + @Column(name = "group_id") + private Integer groupId; + + /** + * 年级Id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 班级id + */ + @Column(name = "class_id") + private Integer classId; + + /** + * 状态(0禁用 1正常) + */ + @Column(name = "status") + private Integer status; + + /** + * 异常状态(正常、休学、出国、留学、复学、停学、自愿退学、自愿留级、自愿降级、其他) + */ + @Column(name = "abnormal_status") + private Integer abnormalStatus; + + @Column(name = "abnormal_date") + private Date abnormalDate; + + /** + * 转入状态(转出0,转入1) + */ + @Column(name = "transfer_status") + private Integer transferStatus; + + /** + * 邀请码 + */ + @Size(max = 255, message = "邀请码长度不能超过255") + @Column(name = "invitation_code", length = 255) + private String invitationCode; + + @Column(name = "sort") + private Integer sort; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacher.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacher.java new file mode 100644 index 0000000..c27128b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacher.java @@ -0,0 +1,111 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.DbFieldNames; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.Date; +import java.util.List; + +/** + * 教师表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_teacher") +public class SchTeacher { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = BaseSchsystem.Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 用户id(不能为空) + */ + @Column(name = "tea_id") + private Integer teaId; + + /** + * 教师账户 + */ + @Size(max = 255, message = "教师账户长度不能超过255") + @Column(name = "account", length = 255) + private String account; + + /** + * 教师姓名 + */ + @Size(max = 255, message = "教师姓名长度不能超过255") + @Column(name = "name", length = 255) + private String name; + + /** + * 性别(0未知 1男 2女等,根据业务定义) + */ + @Column(name = "gender") + private Integer gender; + + @Pattern(regexp = "^$|^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", + message = "身份证号码格式不正确(若填写必须为18位有效格式)") + @Column(name = "id_card", length = 18) + private String idCard; + + /** + * 联系电话 + */ + @Size(max = 255, message = "联系电话长度不能超过255") + @Column(name = "tel", length = 255) + private String tel; + + + /** + * 状态(0禁用 1正常) + */ + @Column(name = "status") + private int status; + + + @Column(name = "sort") + private Integer sort; + + /** + * 创建时间 + */ + @Column(name = DbFieldNames.create_date) + private Date createDate; + + /** + * 修改时间 + */ + @Column(name = DbFieldNames.update_date) + private Date updateDate; + + /** + * 创建用户 + */ + @Column(name = DbFieldNames.create_user_id) + private Integer createUserId; + + /** + * 修改用户 + */ + @Column(name = DbFieldNames.update_user_id) + private Integer updateUserId; + + + @Transient + private List groupList; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroup.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroup.java new file mode 100644 index 0000000..52af5e5 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroup.java @@ -0,0 +1,52 @@ +package com.bestsch.bschclassmanage.entity; + +import com.bestsch.bschclassmanage.model.entityField.DbFieldNames; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.Date; +import java.util.List; + +/** + * 教师 年级学科组 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_teacher_custom_group") +public class SchTeacherCustomGroup extends BaseEntity { + + /** + * 组名 + */ + @Size(max = 255, message = "组名长度不能超过255") + @Column(name = "group_name", length = 255) + private String groupName; + + /** + * 类型 1年级组 2教研组 3备课组 + */ + @Column(name = "group_type", nullable = false) + private Integer groupType; + + /** + * 组长 + */ + @Column(name = "leader_id") + private Integer leaderId; + + + @Column(name = "sort") + private Integer sort; + + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInGrade.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInGrade.java new file mode 100644 index 0000000..fbbb41b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInGrade.java @@ -0,0 +1,46 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * 基础-学制年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_teacher_custom_group_in_grade") +public class SchTeacherCustomGroupInGrade { + + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 年级学科组ID + */ + @Column(name = "cg_group_id") + private Integer cgGroupId; + + /** + * 年级id + */ + @Column(name = "grade_id") + private Integer gradeId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInSubject.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInSubject.java new file mode 100644 index 0000000..e692e97 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInSubject.java @@ -0,0 +1,45 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +/** + * 基础-学制年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_teacher_custom_group_in_subject") +public class SchTeacherCustomGroupInSubject { + + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 年级学科组ID + */ + @Column(name = "cg_group_id") + private Integer cgGroupId; + + /** + * 学科ID + */ + @Column(name = "sub_id") + private String subId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInTeacher.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInTeacher.java new file mode 100644 index 0000000..f684c42 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherCustomGroupInTeacher.java @@ -0,0 +1,51 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +/** + * 基础-学制年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_teacher_custom_group_in_teacher") +public class SchTeacherCustomGroupInTeacher { + + + /** + * 主键 + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 年级 教研 备课组ID + */ + @Column(name = "cg_group_id") + private Integer cgGroupId; + + /** + * 1 组长 2组员 + */ + @Column(name = "group_type") + private Integer groupType; + + /** + * 教师ID + */ + @Column(name = "tea_id") + private Integer teaId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherGroup.java b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherGroup.java new file mode 100644 index 0000000..ee654a3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/SchTeacherGroup.java @@ -0,0 +1,58 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +/** + * 教师组 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "sch_teacher_group") +public class SchTeacherGroup { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @NotNull(groups = BaseSchsystem.Update.class, message = "更新时ID不能为空") + private Integer id; + + /** + * 用户id(不能为空) + */ + @NotNull(message = "教师id不能为空") + @Column(name = "tea_id", nullable = false) + private Integer teaId; + + + /** + * 组id + */ + @NotNull(message = "组id不能为空") + @Column(name = "group_id") + private Integer groupId; + + + /** + * 转入状态(转出0,转入1) + */ + @Column(name = "transfer_status") + private Integer transferStatus; + + /** + * 组id + */ + @NotNull(message = "学校id不能为空") + @Column(name = "schId") + private Integer schId; + + /** + * 更新校验分组 + */ + public @interface Update {} +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/entity/UpgradeLog.java b/src/main/java/com/bestsch/bschclassmanage/entity/UpgradeLog.java new file mode 100644 index 0000000..91f43e6 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/entity/UpgradeLog.java @@ -0,0 +1,49 @@ +package com.bestsch.bschclassmanage.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 基础-字典-年级表 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@Entity +@Table(name = "upgrade_log") +public class UpgradeLog { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "sch_id", nullable = false) + private Integer schId; + + @Column(name = "sys_id", nullable = false) + private Integer sysId; + + @Column(nullable = false) + private Integer year; + + @Column(name = "upgrade_time", nullable = false) + private Date upgradeTime; + + @Column(name = "status", nullable = false) + private Boolean status; + + // 建议提供一个便捷构造方法 + public UpgradeLog(Integer schId, Integer sysId, Integer year, Date upgradeTime,Boolean status) { + this.schId = schId; + this.sysId = sysId; + this.year = year; + this.upgradeTime = upgradeTime; + this.status=status; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/AcademicStage.java b/src/main/java/com/bestsch/bschclassmanage/enums/AcademicStage.java new file mode 100644 index 0000000..f0e915a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/AcademicStage.java @@ -0,0 +1,29 @@ +package com.bestsch.bschclassmanage.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum AcademicStage +{ + PRESCHOOL(0, "学前"), + PRIMARY(1, "小学"), + JUNIOR(2, "初中"),//106 + SENIOR(3, "高中"),//108 + HIGHER_EDUCATION(4, "高等"); + + private Integer key; + private String value; + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(AcademicStage.class)); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/CourseType.java b/src/main/java/com/bestsch/bschclassmanage/enums/CourseType.java new file mode 100644 index 0000000..60cc7a6 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/CourseType.java @@ -0,0 +1,88 @@ +package com.bestsch.bschclassmanage.enums; + +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CourseType +{ + PUBLIC_COURSE(1, "公共课"), + ELECTIVE_COURSE(2, "选修课"), + PROFESSIONAL_COURSE(3, "专业课"); + + private Integer id; + private String name; + + CourseType(int id, String name) + { + this.id = id; + this.name = name; + } + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(CourseType.class)); + } + + public static String nameById(int id) { + for (CourseType type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (CourseType type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static CourseType getById(int id) + { + for (CourseType na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } + + public static List select() { + List list= CourseType.list().stream() + .map(type -> new SelectIntVO(type.getId(), type.getName())) + .collect(Collectors.toList()); + return new ArrayList<>(list); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/CustomGroupType.java b/src/main/java/com/bestsch/bschclassmanage/enums/CustomGroupType.java new file mode 100644 index 0000000..befc8bd --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/CustomGroupType.java @@ -0,0 +1,88 @@ +package com.bestsch.bschclassmanage.enums; + +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum CustomGroupType +{ + PUBLIC_COURSE(1, "年级组"), + ELECTIVE_COURSE(2, "教研组"), + PROFESSIONAL_COURSE(3, "备课组"); + + private Integer id; + private String name; + + CustomGroupType(int id, String name) + { + this.id = id; + this.name = name; + } + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(CustomGroupType.class)); + } + + public static String nameById(int id) { + for (CustomGroupType type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (CustomGroupType type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static CustomGroupType getById(int id) + { + for (CustomGroupType na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } + + public static List select() { + List list= CustomGroupType.list().stream() + .map(type -> new SelectIntVO(type.getId(), type.getName())) + .collect(Collectors.toList()); + return new ArrayList<>(list); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/FileType.java b/src/main/java/com/bestsch/bschclassmanage/enums/FileType.java similarity index 92% rename from src/main/java/com/bestsch/classicalchinese/enums/FileType.java rename to src/main/java/com/bestsch/bschclassmanage/enums/FileType.java index d32075a..adf1d00 100644 --- a/src/main/java/com/bestsch/classicalchinese/enums/FileType.java +++ b/src/main/java/com/bestsch/bschclassmanage/enums/FileType.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.enums; +package com.bestsch.bschclassmanage.enums; public enum FileType { diff --git a/src/main/java/com/bestsch/classicalchinese/enums/DifficultLevel.java b/src/main/java/com/bestsch/bschclassmanage/enums/NodeType.java similarity index 52% rename from src/main/java/com/bestsch/classicalchinese/enums/DifficultLevel.java rename to src/main/java/com/bestsch/bschclassmanage/enums/NodeType.java index 6b9d524..ca62d2e 100644 --- a/src/main/java/com/bestsch/classicalchinese/enums/DifficultLevel.java +++ b/src/main/java/com/bestsch/bschclassmanage/enums/NodeType.java @@ -1,21 +1,26 @@ -package com.bestsch.classicalchinese.enums; +package com.bestsch.bschclassmanage.enums; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; -public enum DifficultLevel -{ - I(1, "容易"), - II(2, "中等"), - III(3, "困难"), - IV(4, "不限制难度"), - ; + +public enum NodeType { + NORMAL(1, "普通组"), + SCHOOL(2, "学校组"), + GRADE(3, "年级组"), + CLASS(4, "班级组"), + REGION(5, "区域组"), + SECTION(6, "学段组"), + TEACHER(7, "教师组"), + STUDENT(8, "学生组"); private int id; private String name; - DifficultLevel(int id, String name) + NodeType(int id, String name) { this.id = id; this.name = name; @@ -41,41 +46,31 @@ public enum DifficultLevel this.name = name; } + public static List list() + { + return new ArrayList<>(EnumSet.allOf(NodeType.class)); + } + + public static Map map() + { + return list().stream().collect(Collectors.toMap(NodeType::getId, QuestionType->QuestionType)); + } + public static String nameById(int id) { - for (DifficultLevel type : list()) { + for (NodeType type : list()) { if (type.getId() == id) return type.getName(); } return null; } - public static Integer getIdByName(String name) { - for (DifficultLevel type : list()) { + for (NodeType type : list()) { if (type.getName().equals(name)) return type.getId(); } return null; } - - private static List list; - - public static List list() + public static NodeType getById(int id) { - if (list != null) - return list; - - list = new ArrayList<>(); - - EnumSet statusSet = EnumSet.allOf(DifficultLevel.class); - for (DifficultLevel status : statusSet) - list.add(status); - - return list; - } - - public static DifficultLevel getById(int id) - { - if (list == null) - list(); - for (DifficultLevel na : list) + for (NodeType na : list()) { if (na.getId() == id) { diff --git a/src/main/java/com/bestsch/classicalchinese/enums/QuestionType.java b/src/main/java/com/bestsch/bschclassmanage/enums/Question.java similarity index 71% rename from src/main/java/com/bestsch/classicalchinese/enums/QuestionType.java rename to src/main/java/com/bestsch/bschclassmanage/enums/Question.java index cf370b6..0dc78f7 100644 --- a/src/main/java/com/bestsch/classicalchinese/enums/QuestionType.java +++ b/src/main/java/com/bestsch/bschclassmanage/enums/Question.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.enums; +package com.bestsch.bschclassmanage.enums; import java.util.ArrayList; import java.util.EnumSet; @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -public enum QuestionType +public enum Question { I(1, "单选题"), II(2, "多选题"), @@ -19,7 +19,7 @@ public enum QuestionType private int id; private String name; - QuestionType(int id, String name) + Question(int id, String name) { this.id = id; this.name = name; @@ -45,31 +45,31 @@ public enum QuestionType this.name = name; } - public static List list() + public static List list() { - return new ArrayList<>(EnumSet.allOf(QuestionType.class)); + return new ArrayList<>(EnumSet.allOf(Question.class)); } - public static Map map() + public static Map map() { - return list().stream().collect(Collectors.toMap(QuestionType::getId, QuestionType->QuestionType)); + return list().stream().collect(Collectors.toMap(Question::getId, QuestionType->QuestionType)); } public static String nameById(int id) { - for (QuestionType type : list()) { + for (Question type : list()) { if (type.getId() == id) return type.getName(); } return null; } public static Integer getIdByName(String name) { - for (QuestionType type : list()) { + for (Question type : list()) { if (type.getName().equals(name)) return type.getId(); } return null; } - public static QuestionType getById(int id) + public static Question getById(int id) { - for (QuestionType na : list()) + for (Question na : list()) { if (na.getId() == id) { diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/SchType.java b/src/main/java/com/bestsch/bschclassmanage/enums/SchType.java new file mode 100644 index 0000000..516f7f7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/SchType.java @@ -0,0 +1,26 @@ +package com.bestsch.bschclassmanage.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum SchType +{ + BASICEDUCATION(1, "基础教育"), + VOCATIONALEDUCATION(2, "职业教育"); + + private Integer key; + private String value; + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(SchType.class)); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/Source.java b/src/main/java/com/bestsch/bschclassmanage/enums/Source.java new file mode 100644 index 0000000..a1b121c --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/Source.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Arrays; +import java.util.Optional; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public enum Source { + + UNKNOWN(null,"未知"), + SYSTEM(0,"系统级"), + SCHOOL(1,"校级"); + + private Integer id; + private String name; + + public static Source getById(String name) { + String nameKey = name.toUpperCase(); + Source[] enums = Source.values(); + Optional opt = Arrays.stream(enums).filter(item -> item.getId().equals(nameKey.toUpperCase())).findAny(); + if(opt.isPresent()){ + return opt.get(); + } + return UNKNOWN; + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/StuAbnormalStatus.java b/src/main/java/com/bestsch/bschclassmanage/enums/StuAbnormalStatus.java new file mode 100644 index 0000000..8d699eb --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/StuAbnormalStatus.java @@ -0,0 +1,99 @@ +package com.bestsch.bschclassmanage.enums; + +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +public enum StuAbnormalStatus +{ + NORMAL(1,"正常"), + SUSPEND_SCHOOLING(2,"休学"), + GO_ABROAD(3,"出国"), + STUDY_ABROAD(4,"留学"), + RESUME_SCHOOLING(5,"复学"), + STOP_SCHOOLING(6,"停学"), + VOLUNTARY_RETREAT_SCHOOLING(7,"自愿退学"), + VOLUNTARY_REPEAT_GRADE(8,"自愿留级"), + VOLUNTARY_DROP_GRADE(9,"自愿降级"), + ELSE(99,"其他"); + + + private int id; + private String name; + + StuAbnormalStatus(int id, String name) + { + this.id = id; + this.name = name; + } + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(StuAbnormalStatus.class)); + } + + public static List select() { + List list= list().stream() + .map(type -> new SelectIntVO(type.getId(), type.getName())) + .collect(Collectors.toList()); + return new ArrayList<>(list); + } + + public static Map map() + { + return list().stream().collect(Collectors.toMap(StuAbnormalStatus::getId, QuestionType->QuestionType)); + } + + public static String nameById(int id) { + for (StuAbnormalStatus type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (StuAbnormalStatus type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static StuAbnormalStatus getById(int id) + { + for (StuAbnormalStatus na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/TransferStatus.java b/src/main/java/com/bestsch/bschclassmanage/enums/TransferStatus.java new file mode 100644 index 0000000..d9b7514 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/TransferStatus.java @@ -0,0 +1,86 @@ +package com.bestsch.bschclassmanage.enums; + +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum TransferStatus +{ + OUT(0,"转出"), + IN(1,"转入"); + + private Integer id; + private String name; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(TransferStatus.class)); + } + + public static List select() { + List list= list().stream() + .map(type -> new SelectIntVO(type.getId(), type.getName())) + .collect(Collectors.toList()); + return new ArrayList<>(list); + } + + public static Map map() + { + return list().stream().collect(Collectors.toMap(TransferStatus::getId, QuestionType->QuestionType)); + } + + public static String nameById(int id) { + for (TransferStatus type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (TransferStatus type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static TransferStatus getById(int id) + { + for (TransferStatus na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/UserGender.java b/src/main/java/com/bestsch/bschclassmanage/enums/UserGender.java new file mode 100644 index 0000000..1864bcf --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/UserGender.java @@ -0,0 +1,88 @@ +package com.bestsch.bschclassmanage.enums; + +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserGender +{ + FEMALE(0, "女"), + MALE(1, "男"); + + + private Integer id; + private String name; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(UserGender.class)); + } + + public static List select() { + List list= list().stream() + .map(type -> new SelectIntVO(type.getId(), type.getName())) + .collect(Collectors.toList()); + return new ArrayList<>(list); + } + + public static Map map() + { + return list().stream().collect(Collectors.toMap(UserGender::getId, QuestionType->QuestionType)); + } + + public static String nameById(int id) { + for (UserGender type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (UserGender type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static UserGender getById(int id) + { + for (UserGender na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/UserRole.java b/src/main/java/com/bestsch/bschclassmanage/enums/UserRole.java similarity index 90% rename from src/main/java/com/bestsch/classicalchinese/enums/UserRole.java rename to src/main/java/com/bestsch/bschclassmanage/enums/UserRole.java index 33c2a03..85eee76 100644 --- a/src/main/java/com/bestsch/classicalchinese/enums/UserRole.java +++ b/src/main/java/com/bestsch/bschclassmanage/enums/UserRole.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.enums; +package com.bestsch.bschclassmanage.enums; import java.util.ArrayList; @@ -7,16 +7,14 @@ import java.util.List; import java.util.Map; public enum UserRole { - - GENERAL_USER(0,"一般用户"), + AREAADMIN(7,"管理员"), TEACHER_USER(1,"教师"), SCH_LEADER_USER(2,"校领导"), STU_USER(3,"学生"), PATRIARCH_USER(4,"家长"), BUREAU_LEADER_USER(5,"局领导"), BUSINESS(6,"工作号"), - ADMIN(7,"管理员"), - ; + GENERAL_USER(8,"普通用户"); private Integer value; private String name; diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/UserStatus.java b/src/main/java/com/bestsch/bschclassmanage/enums/UserStatus.java new file mode 100644 index 0000000..79ff45d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/UserStatus.java @@ -0,0 +1,88 @@ +package com.bestsch.bschclassmanage.enums; + +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserStatus +{ + //状态 0禁用 1 正常 2休学 3出国 4留学 5复学 6停学 7退学 8留级 9其他 + + DISABLED(0,"禁用"), + NORMAL(1,"正常"); + + private Integer id; + private String name; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public static List list() + { + return new ArrayList<>(EnumSet.allOf(UserStatus.class)); + } + + public static List select() { + List list= list().stream() + .map(type -> new SelectIntVO(type.getId(), type.getName())) + .collect(Collectors.toList()); + return new ArrayList<>(list); + } + + public static Map map() + { + return list().stream().collect(Collectors.toMap(UserStatus::getId, QuestionType->QuestionType)); + } + + public static String nameById(int id) { + for (UserStatus type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (UserStatus type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static UserStatus getById(int id) + { + for (UserStatus na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/enums/UserType.java b/src/main/java/com/bestsch/bschclassmanage/enums/UserType.java new file mode 100644 index 0000000..9f08776 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/enums/UserType.java @@ -0,0 +1,19 @@ +package com.bestsch.bschclassmanage.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum UserType +{ + //状态 0禁用 1 正常 2休学 3出国 4留学 5复学 6停学 7退学 8留级 9其他 + + SUPER_ADMINISTRATOR(1,"超级管理员"), + REGULAR_USER(2,"普通用户"); + + private Integer id; + private String name; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/constant/LogModule.java b/src/main/java/com/bestsch/bschclassmanage/model/constant/LogModule.java new file mode 100644 index 0000000..638b6d2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/constant/LogModule.java @@ -0,0 +1,39 @@ +package com.bestsch.bschclassmanage.model.constant; + +/** + * 日志模块常量 + *

+ * 使用常量类的好处: + * 1. 集中管理,避免硬编码字符串 + * 2. 配合 IDE 自动补全,减少拼写错误 + * 3. 改动时只需修改一处 + * 4. 值使用中文,便于日志展示和识别 + */ +public final class LogModule { + + private LogModule() { + // 私有构造,防止实例化 + } + + + // ==================== 学制 ==================== + public static final String BASE_SYSTEM = "系统管理"; +// public static final String SCHOOL_SYSTEM = "学校管理"; + + // ==================== 字典管理 ==================== + public static final String SUBJECT = "学科管理"; + public static final String MAJORS = "专业管理"; + public static final String DIVISION = "系部管理"; + public static final String COURSE = "课程管理"; + public static final String CAMPUS = "课程管理"; + + + + // ==================== 学生/教师/班级 ==================== + public static final String STUDENT = "学生管理"; + public static final String TEACHER = "教师管理"; + public static final String CLASS = "班级管理"; + public static final String TEACH = "任教管理"; + + public static final String CUSTOMGROUP = "自定义组"; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/AddMemberDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/AddMemberDTO.java new file mode 100644 index 0000000..f4a0aba --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/AddMemberDTO.java @@ -0,0 +1,18 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 添加组员请求DTO + */ +@Data +public class AddMemberDTO { + @NotNull(message = "组ID不能为空") + private Integer groupId; + + @NotNull(message = "教师ID列表不能为空") + private List teaIds; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/BaseYearTermDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/BaseYearTermDTO.java new file mode 100644 index 0000000..0c2fc27 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/BaseYearTermDTO.java @@ -0,0 +1,85 @@ +package com.bestsch.bschclassmanage.model.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; +import java.util.Date; + +/** + * @Author wanghu + * @Date 2026-6-12 16:24 (可以根据需要修改) + * @Description: + */ +@Data +public class BaseYearTermDTO { + + private Integer id; + + @NotNull(message = "学年不能为空") + @Positive(message = "学年必须为正整数") + @Min(value = 2000, message = "学年不能小于2000") + private Integer year; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "学年开始日期不能为空") + private Date yearStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "学年结束日期不能为空") + private Date yearEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "第一学期开始日期不能为空") + private Date firstTermStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "第一学期结束日期不能为空") + private Date firstTermEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "第二学期开始日期不能为空") + private Date secondTermStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "第二学期结束日期不能为空") + private Date secondTermEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @NotNull(message = "毕业日期不能为空") + private Date upgradeDate; + + @AssertTrue(message = "学年开始日期不能晚于学年结束日期") + public boolean isYearDateValid() { + if (yearStartDate == null || yearEndDate == null) return true; + return !yearStartDate.after(yearEndDate); + } + + @AssertTrue(message = "第一学期开始日期不能晚于第一学期结束日期") + public boolean isFirstTermDateValid() { + if (firstTermStartDate == null || firstTermEndDate == null) return true; + return !firstTermStartDate.after(firstTermEndDate); + } + + @AssertTrue(message = "第二学期开始日期不能晚于第二学期结束日期") + public boolean isSecondTermDateValid() { + if (secondTermStartDate == null || secondTermEndDate == null) return true; + return !secondTermStartDate.after(secondTermEndDate); + } + + @AssertTrue(message = "第一学期结束日期不能晚于第二学期开始日期") + public boolean isFirstTermEndBeforeSecondTermStart() { + if (firstTermEndDate == null || secondTermStartDate == null) return true; + return !firstTermEndDate.after(secondTermStartDate); + } + + @AssertTrue(message = "毕业日期不能早于学年结束日期") + public boolean isUpgradeDateNotBeforeYearEnd() { + if (upgradeDate == null || yearEndDate == null) return true; + return !upgradeDate.before(yearEndDate); + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/SchCustomGroupDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/SchCustomGroupDTO.java new file mode 100644 index 0000000..d42d60d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/SchCustomGroupDTO.java @@ -0,0 +1,28 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class SchCustomGroupDTO { + private Integer id; // 更新时传 + + @NotBlank(message = "组名不能为空") + private String groupName; + + @NotNull(message = "组类型不能为空") + private Integer groupType; // 1-年级组 2-教研组 3-备课组 + + private Integer sort; + + private List gradeIds; + + private List subjectIds; + + private List leaderIds; + + private List memberIds; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/SchDicCourseDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/SchDicCourseDTO.java new file mode 100644 index 0000000..f70cca9 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/SchDicCourseDTO.java @@ -0,0 +1,41 @@ +package com.bestsch.bschclassmanage.model.dto; + +import com.bestsch.bschclassmanage.entity.SchDicDivision; +import com.bestsch.bschclassmanage.entity.SchDicMajors; +import lombok.Data; + +import javax.persistence.Column; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.List; +import java.util.Set; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +public class SchDicCourseDTO { + + + private Integer id; + + @NotBlank(message = "名称不能为空") + @Size(max = 255, message = "名称长度不能超过255") + private String name; + + @Size(max = 255, message = "别称长度不能超过255") + private String nickname; + + @Size(max = 255, message = "编码长度不能超过255") + private String code; + + private Set majorsIds; + + private Set divisionIds; + + private Integer type; + + private String typeName; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/SchTeacherDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/SchTeacherDTO.java new file mode 100644 index 0000000..092e132 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/SchTeacherDTO.java @@ -0,0 +1,24 @@ +package com.bestsch.bschclassmanage.model.dto; + +import com.bestsch.bschclassmanage.entity.SchTeacher; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchTeacherDTO extends SchTeacher { + + @NotNull(message = "组ID不能为空") + @Min(value = 1, message = "至少选择一个组") + private Integer groupId; + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/SetLeaderDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/SetLeaderDTO.java new file mode 100644 index 0000000..a02f9a8 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/SetLeaderDTO.java @@ -0,0 +1,18 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class SetLeaderDTO { + @NotNull(message = "组ID不能为空") + private Integer groupId; + + /** + * 组长教师ID列表(teaId),传入空列表表示清空所有组长 + * 必须为该组的现有成员(组员或组长) + */ + private List leaderIds; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/StuAbnormalStatusDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/StuAbnormalStatusDTO.java new file mode 100644 index 0000000..636dc4c --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/StuAbnormalStatusDTO.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class StuAbnormalStatusDTO { + + @NotNull(message = "学生ID列表不能为空") + @Size(min = 1, message = "至少选择一个学生") + private List stuIds; + + @NotNull(message = "异常状态不能为空") + @Min(value = 1, message = "异常状态不能为空须大于0") + private Integer abnormalStatus; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/StuTransferClassDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/StuTransferClassDTO.java new file mode 100644 index 0000000..bbdce1a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/StuTransferClassDTO.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class StuTransferClassDTO { + + @NotNull(message = "学生ID列表不能为空") + @Size(min = 1, message = "至少选择一个学生") + private List stuIds; + + @NotNull(message = "目标班级ID不能为空") + @Min(value = 1, message = "目标班级ID必须大于0") + private Integer transferClassId; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/TeaTransferGroupDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/TeaTransferGroupDTO.java new file mode 100644 index 0000000..3cc205f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/TeaTransferGroupDTO.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; +import java.util.Map; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TeaTransferGroupDTO { + @NotNull(message = "教师ID列表不能为空") + @Size(min = 1, message = "至少选择一个教师") + private List ids; + + @NotNull(message = "目标组ID不能为空") + @Size(min = 1, message = "至少选择一个组") + private List transferGroupIds; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/dto/TeaTransferInGroupDTO.java b/src/main/java/com/bestsch/bschclassmanage/model/dto/TeaTransferInGroupDTO.java new file mode 100644 index 0000000..e584069 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/dto/TeaTransferInGroupDTO.java @@ -0,0 +1,30 @@ +package com.bestsch.bschclassmanage.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TeaTransferInGroupDTO { + @NotNull(message = "教师ID列表不能为空") + @Size(min = 1, message = "至少选择一个教师") + private List schTeaIds; + + @NotNull(message = "目标组ID不能为空") + @Min(value=0, message = "至少选择一个组") + private Integer transferGroupId; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/entityField/DbFieldNames.java b/src/main/java/com/bestsch/bschclassmanage/model/entityField/DbFieldNames.java new file mode 100644 index 0000000..68023b7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/entityField/DbFieldNames.java @@ -0,0 +1,15 @@ +package com.bestsch.bschclassmanage.model.entityField; + +/** + * @Author wanghu + * @Date 2026-6-12 18:03 (可以根据需要修改) + * @Description: + */ +public final class DbFieldNames { + public static final String id = "id"; + public static final String schId = "sch_id"; + public static final String create_date = "create_date"; + public static final String update_date = "update_date"; + public static final String create_user_id = "create_user_id"; + public static final String update_user_id = "update_user_id"; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/entityField/EntityFieldNames.java b/src/main/java/com/bestsch/bschclassmanage/model/entityField/EntityFieldNames.java new file mode 100644 index 0000000..ff793ec --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/entityField/EntityFieldNames.java @@ -0,0 +1,68 @@ +package com.bestsch.bschclassmanage.model.entityField; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 实体类字段名称常量定义。 + *

+ * 集中管理所有实体类的公共字段名,避免硬编码字符串, + * 便于统一修改和 IDE 自动补全。 + *

+ * + * @author YourName + * @since 2026-07-10 + *//** + * 实体类字段名称常量定义。 + *

+ * 集中管理所有实体类的公共字段名,避免硬编码字符串, + * 便于统一修改和 IDE 自动补全。 + *

+ * + * @author YourName + * @since 2026-07-10 + */ +public final class EntityFieldNames { + + // ==================== 基础字段 ==================== + public static final String id = "id"; + public static final String account = "account"; + public static final String idCard = "idCard"; + public static final String name = "name"; + public static final String code = "code"; + public static final String sort = "sort"; + public static final String year = "year"; + public static final String enrollYear = "enrollYear"; + + // ==================== 关联字段 ==================== + public static final String gradeId = "gradeId"; + public static final String groupId = "groupId"; + public static final String schId = "schId"; + public static final String classId = "classId"; + public static final String schSystemId = "schSystemId"; + + public static final String teaId = "teaId"; + public static final String stuId = "stuId"; + + // ==================== 状态字段 ==================== + public static final String status = "status"; + public static final String abnormalStatus = "abnormalStatus"; + public static final String transferStatus = "transferStatus"; + public static final String graduate = "graduate"; + + // ==================== 审计字段 ==================== + public static final String createDate = "createDate"; + public static final String updateDate = "updateDate"; + public static final String createUserId = "createUserId"; + public static final String updateUserId = "updateUserId"; + + /** + * 私有构造函数,防止实例化。 + */ + private EntityFieldNames() { + throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/CustomGroupExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/CustomGroupExcelColumn.java new file mode 100644 index 0000000..62953a9 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/CustomGroupExcelColumn.java @@ -0,0 +1,40 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + + +@Data +public class CustomGroupExcelColumn { + + public static final String GROUP_NAME = "组名"; + public static final String GROUP_TYPE = "组类型"; + public static final String GRADE_BIN = "年级"; + public static final String SUBJECT_BIN = "学科"; + public static final String LEADER_NAME = "组长"; + public static final String MEMBER_NAME = "组员"; + + @NotBlank(message = CustomGroupExcelColumn.GROUP_NAME+"不能为空") + @Size(max = 20, message = CustomGroupExcelColumn.GROUP_NAME +"长度不能超过20") + @Excel(name = CustomGroupExcelColumn.GROUP_NAME) + private String groupName; + + @NotBlank(message = CustomGroupExcelColumn.GROUP_TYPE+"不能为空") + @Excel(name = CustomGroupExcelColumn.GROUP_TYPE) + private String groupType; + + @Excel(name = CustomGroupExcelColumn.GRADE_BIN) + private String gradeBin; + + @Excel(name = CustomGroupExcelColumn.SUBJECT_BIN) + private String subjectBin; + + @Excel(name = CustomGroupExcelColumn.LEADER_NAME) + private String leaderName; + + @Excel(name = CustomGroupExcelColumn.MEMBER_NAME) + private String memberName; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/ErrorExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/ErrorExcelColumn.java new file mode 100644 index 0000000..031ddd4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/ErrorExcelColumn.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.model.excel; + +import lombok.AllArgsConstructor; +import lombok.Data; + + +@Data +@AllArgsConstructor +public class ErrorExcelColumn { + private Integer rows; + private String columnValue; + private String errorMsg; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/ImportRuleExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/ImportRuleExcelColumn.java new file mode 100644 index 0000000..a8ff62f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/ImportRuleExcelColumn.java @@ -0,0 +1,16 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +@Data +public class ImportRuleExcelColumn { + @Excel(name = "规则项") + private String ruleItem; + + @Excel(name = "说明") + private String description; + + @Excel(name = "填写内容") + private String content; +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/SchClassExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/SchClassExcelColumn.java new file mode 100644 index 0000000..ba6a4f3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/SchClassExcelColumn.java @@ -0,0 +1,40 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + + +@Data +public class SchClassExcelColumn { + + public static final String GRADE_NAME = "年级"; + public static final String CLAZZ_NAME = "班级"; + public static final String CLAZZ_CNAME = "班级别名"; + public static final String BZR = "班主任"; + public static final String FBZR = "副班主任"; + + @NotBlank(message = SchClassExcelColumn.GRADE_NAME+"不能为空") + @Size(max = 20, message = SchClassExcelColumn.GRADE_NAME +"长度不能超过20") + @Excel(name = SchClassExcelColumn.GRADE_NAME) + private String gradeName; + + @NotBlank(message = SchClassExcelColumn.CLAZZ_NAME+"不能为空") + @Size(max = 20, message = SchClassExcelColumn.CLAZZ_NAME+"长度不能超过20") + @Excel(name = SchClassExcelColumn.CLAZZ_NAME) + private String clazzName; + + @Size(max = 20, message = SchClassExcelColumn.CLAZZ_CNAME+"长度不能超过20") + @Excel(name = SchClassExcelColumn.CLAZZ_CNAME) + private String clazzCName; + + @Excel(name = SchClassExcelColumn.BZR) + private String bzr; + + @Excel(name = SchClassExcelColumn.FBZR) + private String fbzr; + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/SchHeightClassExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/SchHeightClassExcelColumn.java new file mode 100644 index 0000000..af5bc58 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/SchHeightClassExcelColumn.java @@ -0,0 +1,57 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + + +@Data +public class SchHeightClassExcelColumn { + + public static final String GRADE_NAME = "学级(必填)"; + public static final String CLAZZ_CODE = "编号"; + public static final String CLAZZ_NAME = "班级"; + public static final String CLAZZ_CNAME = "别名"; + public static final String CAMPUS = "校区"; + public static final String DIVISION = "系部(必填)"; + public static final String MAJORS = "专业(必填)"; + public static final String BZR = "班主任"; + + @NotBlank(message = SchHeightClassExcelColumn.GRADE_NAME+"不能为空") + @Size(max = 20, message = SchHeightClassExcelColumn.GRADE_NAME +"长度不能超过20") + @Excel(name = SchHeightClassExcelColumn.GRADE_NAME) + private String gradeName; + + @Excel(name = SchHeightClassExcelColumn.CLAZZ_CODE) + private String clazzCode; + + @NotBlank(message = SchHeightClassExcelColumn.CLAZZ_NAME+"不能为空") + @Size(max = 20, message = SchHeightClassExcelColumn.CLAZZ_NAME+"长度不能超过20") + @Excel(name = SchHeightClassExcelColumn.CLAZZ_NAME) + private String clazzName; + + @Size(max = 20, message = SchHeightClassExcelColumn.CLAZZ_CNAME+"长度不能超过20") + @Excel(name = SchHeightClassExcelColumn.CLAZZ_CNAME) + private String clazzCName; + + @Excel(name = SchHeightClassExcelColumn.CAMPUS) + private String campus; + + @NotBlank(message = SchHeightClassExcelColumn.DIVISION+"不能为空") + @Size(max = 20, message = SchHeightClassExcelColumn.DIVISION+"长度不能超过20") + @Excel(name = SchHeightClassExcelColumn.DIVISION) + private String divistion; + + @NotBlank(message = SchHeightClassExcelColumn.MAJORS+"不能为空") + @Size(max = 20, message = SchHeightClassExcelColumn.MAJORS+"长度不能超过20") + @Excel(name = SchHeightClassExcelColumn.MAJORS) + private String majors; + + @Excel(name = SchHeightClassExcelColumn.BZR) + private String bzr; + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/StudentClassNoExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/StudentClassNoExcelColumn.java new file mode 100644 index 0000000..cbf0d34 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/StudentClassNoExcelColumn.java @@ -0,0 +1,44 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + + +@Data +public class StudentClassNoExcelColumn { + + public static final String GRADE_NAME = "年级"; + public static final String CLAZZ_NAME = "班级"; + public static final String STU_NAME = "姓名"; + public static final String ACCOUNT = "账号"; + public static final String CLAZZ_NO = "学号"; + + @NotBlank(message = StudentClassNoExcelColumn.GRADE_NAME+"不能为空") + @Size(max = 20, message = StudentClassNoExcelColumn.GRADE_NAME +"长度不能超过20") + @Excel(name = StudentClassNoExcelColumn.GRADE_NAME) + private String gradeName; + + @NotBlank(message = StudentClassNoExcelColumn.CLAZZ_NAME+"不能为空") + @Size(max = 20, message = StudentClassNoExcelColumn.GRADE_NAME +"长度不能超过20") + @Excel(name = StudentClassNoExcelColumn.CLAZZ_NAME) + private String clazzName; + + @NotBlank(message = StudentClassNoExcelColumn.STU_NAME+"不能为空") + @Size(max = 50, message = StudentClassNoExcelColumn.STU_NAME +"长度不能超过50") + @Excel(name = StudentClassNoExcelColumn.STU_NAME) + private String stuName; + + @NotBlank(message = StudentClassNoExcelColumn.ACCOUNT+"不能为空") + @Size(max = 50, message = StudentClassNoExcelColumn.ACCOUNT +"长度不能超过50") + @Excel(name = StudentClassNoExcelColumn.ACCOUNT) + private String account; + + @Excel(name = StudentClassNoExcelColumn.CLAZZ_NO) + private String clazzNo; + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/StudentExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/StudentExcelColumn.java new file mode 100644 index 0000000..37d1252 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/StudentExcelColumn.java @@ -0,0 +1,58 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + + +@Data +public class StudentExcelColumn { + + public static final String GRADE_NAME = "年级"; + public static final String CLAZZ_NAME = "班级"; + public static final String STU_NAME = "姓名"; + public static final String ACCOUNT = "账号"; + public static final String PASSWORD = "密码"; + public static final String ID_CARD = "身份证"; + public static final String CLAZZ_NO = "学号"; + public static final String GENDER = "性别(男,女)"; + + @NotBlank(message = StudentExcelColumn.GRADE_NAME+"不能为空") + @Size(max = 20, message = StudentExcelColumn.GRADE_NAME +"长度不能超过20") + @Excel(name = StudentExcelColumn.GRADE_NAME) + private String gradeName; + + @NotBlank(message = StudentExcelColumn.CLAZZ_NAME+"不能为空") + @Size(max = 20, message = StudentExcelColumn.GRADE_NAME +"长度不能超过20") + @Excel(name = StudentExcelColumn.CLAZZ_NAME) + private String clazzName; + + @NotBlank(message = StudentExcelColumn.STU_NAME+"不能为空") + @Size(max = 50, message = StudentExcelColumn.STU_NAME +"长度不能超过50") + @Excel(name = StudentExcelColumn.STU_NAME) + private String stuName; + + @NotBlank(message = StudentExcelColumn.ACCOUNT+"不能为空") + @Size(max = 50, message = StudentExcelColumn.ACCOUNT +"长度不能超过50") + @Excel(name = StudentExcelColumn.ACCOUNT) + private String account; + + @Excel(name = StudentExcelColumn.PASSWORD) + private String password; + + @Pattern(regexp = "^$|^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", + message = "身份证号码格式不正确(若填写必须为18位有效格式)") + @Excel(name = StudentExcelColumn.ID_CARD) + private String idCard; + + @Excel(name = StudentExcelColumn.CLAZZ_NO) + private String clazzNo; + + @Pattern(regexp = "^(\\s*|男|女)$", + message = "请输入正确性别,若填写,必须为(男,女)") + @Excel(name = StudentExcelColumn.GENDER) + private String gender; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/excel/TeacherExcelColumn.java b/src/main/java/com/bestsch/bschclassmanage/model/excel/TeacherExcelColumn.java new file mode 100644 index 0000000..4e1a30f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/excel/TeacherExcelColumn.java @@ -0,0 +1,61 @@ +package com.bestsch.bschclassmanage.model.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + + +/** + * @program: ResearchLearn + * @description: 导入研学基地实体类 + * @author: chenx + * @create: 2023-07-21 14:12 + **/ + +@Data +public class TeacherExcelColumn { + + public static final String GROUP_NAME = "组名(必填,多个组','隔开)"; + public static final String ACCOUNT = "用户名(必填,教师手机号)"; + public static final String PASSWORD = "密码(选填,若填写请按照强密码规则字母+数字+特殊符号,8位以上)"; + public static final String TEA_NAME = "姓名(必填)"; + public static final String ID_CARD = "身份证号"; + public static final String TEL = "手机号"; + public static final String GENDER = "性别(男,女)"; + + @NotBlank(message = TeacherExcelColumn.GROUP_NAME+"不能为空") + @Excel(name = TeacherExcelColumn.GROUP_NAME) + private String groupName; + + @NotBlank(message = TeacherExcelColumn.ACCOUNT+"不能为空") + @Size(max = 50, message = TeacherExcelColumn.ACCOUNT +"长度不能超过50") + @Excel(name = TeacherExcelColumn.ACCOUNT) + private String account; + + @Excel(name = TeacherExcelColumn.PASSWORD) + private String password; + + @NotBlank(message = TeacherExcelColumn.TEA_NAME+"不能为空") + @Size(max = 50, message = TeacherExcelColumn.TEA_NAME +"长度不能超过50") + @Excel(name = TeacherExcelColumn.TEA_NAME) + private String teaName; + + @Pattern(regexp = "^$|^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", + message = "身份证号码格式不正确(若填写必须为18位有效格式)") + @Excel(name = TeacherExcelColumn.ID_CARD) + private String idCard; + + @Pattern(regexp = "^(\\s*|1[3-9]\\d{9})$", + message = "请输入有效手机号码(若填写,必须为11位手机号)") + @Excel(name = TeacherExcelColumn.TEL) + private String tel; + + @Pattern(regexp = "^(\\s*|男|女)$", + message = "请输入正确性别,若填写,必须为(男,女)") + @Excel(name = TeacherExcelColumn.GENDER) + private String gender; + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/oa/TeaInfoVO.java b/src/main/java/com/bestsch/bschclassmanage/model/oa/TeaInfoVO.java new file mode 100644 index 0000000..9080a46 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/oa/TeaInfoVO.java @@ -0,0 +1,30 @@ +package com.bestsch.bschclassmanage.model.oa; + +import lombok.Data; + +@Data +public class TeaInfoVO { + private String SchSerID; + private String Teapolitical; + private String TeaWorkStart; + private String Account; + private String SchSerIDs; + private Integer role; + private String JiaoYuJu; + private String TeaSex; + private Integer IsLeadingMiddle; + private String TeaOriginPlace; + private String Photo; + private String TeaIDCard; + private String Name; + private Integer GroupID; + private String SchName; + private String TeaTeachStart; + private String TeaSerID; + private Integer UserID; + private String TeaNation; + private String Tel; + private String TeaWorkType; + private Integer TeaNo; + private String TeaBirth; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/oa/UserInfoVO.java b/src/main/java/com/bestsch/bschclassmanage/model/oa/UserInfoVO.java new file mode 100644 index 0000000..5bc05dd --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/oa/UserInfoVO.java @@ -0,0 +1,19 @@ +package com.bestsch.bschclassmanage.model.oa; + +import lombok.Data; + +@Data +public class UserInfoVO { + private String SchSerID; // 学校ID + private Integer No; // 教师编号 + private String IDCard; // 身份证 + private Integer UserID; // 用户ID + private Integer sex; // 性别 + private Integer usertype; // 用户类型 + private String SerID; // 序列号 + private String Photo; // 头像 + private String Tel; // 电话 + private String Uids; // 账户 + private Integer GroupID; // 分组ID + private String Name; // 姓名 +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseGroup.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseGroup.java new file mode 100644 index 0000000..d13ebc2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseGroup.java @@ -0,0 +1,19 @@ +package com.bestsch.bschclassmanage.model.tool; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class BaseGroup { + private Integer id; + private String code; + private String name; + private Integer type; + private Integer pid; + private Integer no; +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseTree.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseTree.java new file mode 100644 index 0000000..7a3e618 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseTree.java @@ -0,0 +1,21 @@ +package com.bestsch.bschclassmanage.model.tool; + +import com.fasterxml.jackson.core.type.TypeReference; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class BaseTree { + private Integer id; + private String code; + private String name; + private Integer type; + private String order; + private boolean expand; + private List children; +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseUser.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseUser.java new file mode 100644 index 0000000..3b837e3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/BaseUser.java @@ -0,0 +1,48 @@ +package com.bestsch.bschclassmanage.model.tool; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class BaseUser { + private int id; + private Integer[] tags; + private String phone; + private String profilePicture; + private LocalDateTime birth; + private Integer[] depts; + private Integer status; + private String idcard; + private Integer type; + private String email; + private String name; + private String account; + private Integer gender; + private List groups; + private List roleList; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class GroupInfo { + private Integer groupId; + private Integer no; + private Integer schoolId; + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class RoleInfo { + private Integer roleId; + private Integer schId; + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/tool/DeleteUser.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/DeleteUser.java new file mode 100644 index 0000000..524adf1 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/DeleteUser.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.model.tool; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class DeleteUser { + private Integer userId; + private Integer groupId; +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/model/PageInfo.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/PageInfo.java similarity index 93% rename from src/main/java/com/bestsch/classicalchinese/model/PageInfo.java rename to src/main/java/com/bestsch/bschclassmanage/model/tool/PageInfo.java index 0ac66a6..66b844e 100644 --- a/src/main/java/com/bestsch/classicalchinese/model/PageInfo.java +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/PageInfo.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.model; +package com.bestsch.bschclassmanage.model.tool; /** * @Author wanghu diff --git a/src/main/java/com/bestsch/bschclassmanage/model/tool/UserSysRole.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/UserSysRole.java new file mode 100644 index 0000000..fda8df7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/UserSysRole.java @@ -0,0 +1,36 @@ +package com.bestsch.bschclassmanage.model.tool; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + + +/** + * 用户系统角色上下文实体 + * 用于从请求头 currentrole 中解析当前操作人的身份信息 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserSysRole { + + /** + * 子账号/孩子ID + * 值为 0 通常代表:主账号操作 或 没有切换子账户 + */ + private Integer childId; + + /** + * 角色ID (例如:7 可能代表班主任、校长或普通教师等) + */ + private Integer roleId; + + /** + * 学校ID (例如:3260) + * 关键字段,用于数据隔离(如日志查询只查该学校的数据) + */ + private Integer schId; + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/tool/YearTerm.java b/src/main/java/com/bestsch/bschclassmanage/model/tool/YearTerm.java new file mode 100644 index 0000000..d747d9f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/tool/YearTerm.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.model.tool; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class YearTerm { + private Integer year; + private Integer term; +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/AcademicStageSchsystemVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/AcademicStageSchsystemVO.java new file mode 100644 index 0000000..e80d3ae --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/AcademicStageSchsystemVO.java @@ -0,0 +1,19 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +public class AcademicStageSchsystemVO { + private Integer academicStageId; + private String academicStageName; + private List academicStageList; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/BaseSchClassVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/BaseSchClassVO.java new file mode 100644 index 0000000..e47c2e4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/BaseSchClassVO.java @@ -0,0 +1,55 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.Builder; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +public class BaseSchClassVO { + + private Integer id; + + private String code; + + private Integer gradeId; + + private String gradeName; + + private Integer groupId; + + private String groupName; + + private Integer classId; + + @NotBlank(message = "名称不能为空") + @Size(max = 255, message = "名称长度不能超过255") + private String name; + + @Size(max = 255, message = "别称长度不能超过255") + private String cname; + + private Integer firstTeacherId; + + private String firstTeacherName; + + private Integer secondTeacherId; + + private String secondTeacherName; + + private Integer campusId; + + private String campusName; + + private Boolean graduate; + + private Boolean disableDel; + + private Integer enrollYear; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/BaseYearTermVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/BaseYearTermVO.java new file mode 100644 index 0000000..c1f9f13 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/BaseYearTermVO.java @@ -0,0 +1,63 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.bestsch.bschclassmanage.entity.BaseYearTerm; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Calendar; +import java.util.Date; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ + +@Data +public class BaseYearTermVO { + + private Integer id; + + private Integer year; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date yearStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date yearEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date firstTermStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date firstTermEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date secondTermStartDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date secondTermEndDate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date upgradeDate; + + private Boolean nowYear; + + // 带参构造:接收实体和当前学年ID,直接完成赋值 + public static BaseYearTermVO of(BaseYearTerm entity, Integer nowId) { + if (entity == null) return null; + BaseYearTermVO vo = new BaseYearTermVO(); + vo.setId(entity.getId()); + vo.setYear(entity.getYear()); + vo.setYearStartDate(entity.getYearStartDate()); + vo.setYearEndDate(entity.getYearEndDate()); + vo.setFirstTermStartDate(entity.getFirstTermStartDate()); + vo.setFirstTermEndDate(entity.getFirstTermEndDate()); + vo.setSecondTermStartDate(entity.getSecondTermStartDate()); + vo.setSecondTermEndDate(entity.getSecondTermEndDate()); + vo.setUpgradeDate(entity.getUpgradeDate()); + vo.setNowYear(nowId != null && nowId.equals(entity.getId())); + return vo; + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/HigherSchClassVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/HigherSchClassVO.java new file mode 100644 index 0000000..3392bcb --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/HigherSchClassVO.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.Data; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +public class HigherSchClassVO extends BaseSchClassVO { + + private Integer divisionId; + + private String divisionName; + + private Integer majorsId; + + private String majorsName; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/HistorySchClassVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/HistorySchClassVO.java new file mode 100644 index 0000000..3e19bf2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/HistorySchClassVO.java @@ -0,0 +1,44 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.util.Date; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +public class HistorySchClassVO { + + private Integer id; + + private Integer gradeId; + + private String gradeName; + + private Integer classId; + + private String name; + + private String cname; + + private Integer campusId; + + private String campusName; + + private Boolean graduate; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date CreateDate; + + private Integer majorsId; + + private String majorsName; + + private Integer schType; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/PageVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/PageVO.java new file mode 100644 index 0000000..ddc4070 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/PageVO.java @@ -0,0 +1,108 @@ +package com.bestsch.bschclassmanage.model.vo; + +import org.springframework.data.domain.Page; +import java.util.Collections; +import java.util.List; + +/** + * 统一分页响应对象 + * @param 数据类型 + */ +public class PageVO { + private int current; // 当前页码(从1开始) + private int pageSize; // 每页大小 + private long total; // 总记录数 + private List content; // 当前页数据 + + // ========== 构造方法 ========== + public PageVO() { + // 默认构造,用于反序列化 + } + + public PageVO(int current, int pageSize, long total, List content) { + this.current = current; + this.pageSize = pageSize; + this.total = total; + this.content = content != null ? content : Collections.emptyList(); + } + + // ========== 静态工厂方法 ========== + /** + * 从 Spring Data Page 转换 + */ + public static PageVO from(Page page) { + return new PageVO<>(page.getNumber() + 1, page.getSize(), page.getTotalElements(), page.getContent()); + } + + /** + * 创建空分页结果 + */ + public static PageVO empty(int pageSize) { + return new PageVO<>(1, pageSize, 0, Collections.emptyList()); + } + + // ========== getter / setter ========== + public int getCurrent() { + return current; + } + + public void setCurrent(int current) { + this.current = current; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public List getContent() { + return content; + } + + public void setContent(List content) { + this.content = content; + } + + // ========== 辅助计算方法 ========== + /** + * 总页数 + */ + public int getTotalPages() { + if (pageSize <= 0) { + return 0; + } + return (int) Math.ceil((double) total / pageSize); + } + + /** + * 是否有上一页 + */ + public boolean hasPrevious() { + return current > 1; + } + + /** + * 是否有下一页 + */ + public boolean hasNext() { + return current < getTotalPages(); + } + + /** + * 分页偏移量(用于SQL查询) + */ + public int getOffset() { + return (current - 1) * pageSize; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchCustomGroupVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchCustomGroupVO.java new file mode 100644 index 0000000..19cc172 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchCustomGroupVO.java @@ -0,0 +1,26 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchCustomGroupVO { + private Integer cgId; // 组id + private String cgName; // 组名称 + private List gradeIds; + private List subjectIds; + private List cgLeader; + private List cgMember; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchDicCourseVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchDicCourseVO.java new file mode 100644 index 0000000..7de60a3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchDicCourseVO.java @@ -0,0 +1,29 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.bestsch.bschclassmanage.entity.SchDicDivision; +import com.bestsch.bschclassmanage.entity.SchDicMajors; +import lombok.Builder; +import lombok.Data; +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +public class SchDicCourseVO { + + private Integer id; + private String name; + private String nickname; + private String code; + + private List majorsList; + + private List divisionList; + + private Integer type; + + private String typeName; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchStudentVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchStudentVO.java new file mode 100644 index 0000000..4e015c8 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchStudentVO.java @@ -0,0 +1,75 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.Date; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchStudentVO { + + private Integer id; + + private Integer stuId; + + @NotBlank(message = "账号不能为空") + @Size(max = 255, message = "账号长度不能超过255") + + private String account; + + @NotBlank(message = "名称不能为空") + @Size(max = 255, message = "名称长度不能超过255") + private String name; + + private Integer gender; + + @Pattern(regexp = "^$|^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", + message = "身份证号码格式不正确(若填写必须为18位有效格式)") + private String idCard; + + private Integer groupId; + + private String stuClassNo; + + private Integer gradeId; + + private String gradeName; + + private Integer classId; + + private String className; + + private Integer status; + + private String statusName; + + private Integer abnormalStatus; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date abnormalDate; + + private String abnormalStatusName; + + private String invitationCode; + + private Integer sort; + + private Integer schId; + + private String schName; + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchSystemTreeVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchSystemTreeVO.java new file mode 100644 index 0000000..3c2e7e4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchSystemTreeVO.java @@ -0,0 +1,40 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.bestsch.bschclassmanage.enums.NodeType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchSystemTreeVO { + // ========== 通用字段 ========== + private Integer id; // 当前节点主键(学制ID/年级ID/班级ID) + private String name; // 节点显示名称 + private Integer sort; // 排序序号(同层级排序) + private NodeType type; // 节点类型:SCHOOL, SYSTEM, GRADE, CLASS + private List children; // 子节点列表 + + // ========== 层级特定 ID(可选,便于前端直接获取) ========== + private Integer schsystemId; // 所属学制ID(仅年级/班级节点有效) + private Integer gradeId; // 所属年级ID(仅班级节点有效) + private Integer classId; // 班级ID(仅班级节点有效) + + // ========== 学校节点特有字段 ========== + private Integer educationType; // 教育类型(仅学校节点有效) + + // ========== 年级节点特有字段 ========== + private Integer enrollYear; // 入学年份(仅年级/班级节点有效,班级可继承年级的入学年份) + private Integer graduation; // 0-未毕业,1-已毕业(仅年级节点有效) + private boolean expand=false; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchSystemVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchSystemVO.java new file mode 100644 index 0000000..7a500d3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchSystemVO.java @@ -0,0 +1,22 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.fasterxml.jackson.annotation.JsonView; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchSystemVO { + private Integer id; // 学制id + private String name; // 学制名称 + private Boolean checked; // 是否选中(前端勾选状态) +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachClassMapVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachClassMapVO.java new file mode 100644 index 0000000..8d962e7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachClassMapVO.java @@ -0,0 +1,27 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchTeachClassMapVO { + + private Integer gradeId; + + private Integer classId; + + private List teachSubjectList; + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachMapIdVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachMapIdVO.java new file mode 100644 index 0000000..60a0d32 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachMapIdVO.java @@ -0,0 +1,31 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchTeachMapIdVO { + + private Integer id; + + private String subId; + + private String subName; + + private Integer teacherId; + + private String teacherName; + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachMapVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachMapVO.java new file mode 100644 index 0000000..ed3cfd2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeachMapVO.java @@ -0,0 +1,27 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchTeachMapVO { + + private List subjectList; + + private List classList; + + private List teachList; + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeacherTOutVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeacherTOutVO.java new file mode 100644 index 0000000..1480c95 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeacherTOutVO.java @@ -0,0 +1,30 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.Date; +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchTeacherTOutVO { + private Integer teaId; + private String name; + private String idCard; + private String groupNames; + private Integer schId; + private String schName; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeacherVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeacherVO.java new file mode 100644 index 0000000..1626905 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SchTeacherVO.java @@ -0,0 +1,73 @@ +package com.bestsch.bschclassmanage.model.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.Date; +import java.util.List; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchTeacherVO { + + private Integer id; + + private Integer teaId; + + /** + * 教师账户 + */ + @Size(max = 255, message = "教师账户长度不能超过255") + private String account; + + /** + * 教师姓名 + */ + @Size(max = 255, message = "教师姓名长度不能超过255") + private String name; + + /** + * 组id name + */ + private List groupList; + + /** + * 性别(0未知 1男 2女等,根据业务定义) + */ + private Integer gender; + + + @Pattern(regexp = "^$|^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", + message = "身份证号码格式不正确(若填写必须为18位有效格式)") + private String idCard; + + /** + * 联系电话 + */ + @Size(max = 255, message = "联系电话长度不能超过255") + private String tel; + + /** + * 状态(0禁用 1正常) + */ + private int status; + + private String statusName; + + + + + private Integer sort; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectGradeClassVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectGradeClassVO.java new file mode 100644 index 0000000..b61e19b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectGradeClassVO.java @@ -0,0 +1,22 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SelectGradeClassVO { + private Integer gradeId; + private String gradeName; + private Integer classId; + private String name; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectIntVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectIntVO.java new file mode 100644 index 0000000..60bebbb --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectIntVO.java @@ -0,0 +1,37 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SelectIntVO { + private Integer id; // id + private String name; //名称 + + public static Map toMap(List list) { + if (list == null || list.isEmpty()) { + return java.util.Collections.emptyMap(); + } + return list.stream() + .filter(vo -> vo != null && vo.getId() != null && vo.getName() != null) + .collect(Collectors.toMap( + SelectIntVO::getId, + SelectIntVO::getName, + (oldVal, newVal) -> oldVal // 如果有重复 key,保留第一个 + )); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectStrVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectStrVO.java new file mode 100644 index 0000000..e106702 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/SelectStrVO.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.model.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SelectStrVO { + private String id; // id + private String name; //名称 +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/TeacherSchVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/TeacherSchVO.java new file mode 100644 index 0000000..da448c8 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/TeacherSchVO.java @@ -0,0 +1,15 @@ +package com.bestsch.bschclassmanage.model.vo; + + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +public interface TeacherSchVO { + Integer getTeaId(); + String getTeaName(); + Integer getSchId(); + Integer getIdCard(); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/model/vo/oa/SchInfoVO.java b/src/main/java/com/bestsch/bschclassmanage/model/vo/oa/SchInfoVO.java new file mode 100644 index 0000000..82cf1ff --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/model/vo/oa/SchInfoVO.java @@ -0,0 +1,29 @@ +package com.bestsch.bschclassmanage.model.vo.oa; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author wanghu + * @Date 2026-6-10 15:09 (可以根据需要修改) + * @Description: + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SchInfoVO { + @JsonProperty("SchSerId") + private String schSerId; + @JsonProperty("UserSchSerId") + private Integer userSchSerId; + @JsonProperty("SchName") + private String schName; +} diff --git a/src/main/java/com/bestsch/bschclassmanage/scheduler/ClassUpgradeScheduler.java b/src/main/java/com/bestsch/bschclassmanage/scheduler/ClassUpgradeScheduler.java new file mode 100644 index 0000000..564faa1 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/scheduler/ClassUpgradeScheduler.java @@ -0,0 +1,69 @@ +package com.bestsch.bschclassmanage.scheduler; + +import com.bestsch.bschclassmanage.service.IBaseYearTermService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import java.util.Date; + +/** + * 班级升级定时任务 + * 每年9月1日凌晨2点执行 + */ +@Slf4j +@Component +public class ClassUpgradeScheduler { + + @Autowired + private ISchClassService schClassService; // 注入业务服务 + + @Autowired + private IBaseYearTermService baseYearTermService; // 注入业务服务 + + /** + * 定时执行班级升级 + * Cron:每天凌晨2点执行 + */ + @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行 + public void upgradeClasses() { + log.info("===== 班级升级定时任务开始 ====="); + try { + Date today = new Date(); + if (baseYearTermService.isUpgradeDate(today)) { + // 如果今天是升级日,则执行升级 + schClassService.upgradeAllClasses(); + } else { + log.info("今天不是升级日,跳过"); + } + log.info("===== 班级升级定时任务成功完成 ====="); + } catch (Exception e) { + log.error("班级升级定时任务执行失败", e); + // 可以发送告警邮件或短信 + } + } + + /** + * 定时执行数据备份 + * Cron:每天凌晨0点执行 + */ + @Scheduled(cron = "0 0 0 * * ?") // 每天凌晨0点执行 + public void backupAllSnapshot() { + log.info("===== 班级数据备份定时任务开始 ====="); + try { + Date today = new Date(); + if (baseYearTermService.isBackupClassDataDate(today)) { + // 如果今天是升级日,则执行升级 + schClassService.backupAllSnapshot(); + } else { + log.info("今天不是备份日,跳过"); + } + log.info("===== 班级数据备份定时任务成功完成 ====="); + } catch (Exception e) { + log.error("班级数据备份定时任务执行失败", e); + // 可以发送告警邮件或短信 + } + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IBaseDicGradeService.java b/src/main/java/com/bestsch/bschclassmanage/service/IBaseDicGradeService.java new file mode 100644 index 0000000..81c863a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IBaseDicGradeService.java @@ -0,0 +1,17 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.Repository.BaseDicGradeRepository; +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface IBaseDicGradeService { + + List getSysGradeList(); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IBaseDicSubjectService.java b/src/main/java/com/bestsch/bschclassmanage/service/IBaseDicSubjectService.java new file mode 100644 index 0000000..363f347 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IBaseDicSubjectService.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicSubject; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface IBaseDicSubjectService { + + List getSysSubjectList(); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IBaseSchsystemGradeService.java b/src/main/java/com/bestsch/bschclassmanage/service/IBaseSchsystemGradeService.java new file mode 100644 index 0000000..feae259 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IBaseSchsystemGradeService.java @@ -0,0 +1,28 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.entity.BaseSchsystemGrade; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Service +public interface IBaseSchsystemGradeService { + + List getSchGradeCacheList(Integer schId,Integer schsystemId,Integer gradeId); + + Map getNowYearGradeMap(Integer schId,Integer schsystemId); + + Map getGradeNameMap(Integer schId, Integer schsystemId,Integer gradeId); + + List getGradeSelect(Integer schId, Integer schsystemId, Integer gradeId); + + List getGradeByMajorsId(Integer schId,Integer majorsId); + + Integer getSchsystemIdByGradeId(Integer schId,Integer gradeId); + + Integer getSchGradeIdBySchsystemId(Integer schId,Integer gradeId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IBaseSchsystemService.java b/src/main/java/com/bestsch/bschclassmanage/service/IBaseSchsystemService.java new file mode 100644 index 0000000..488d21f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IBaseSchsystemService.java @@ -0,0 +1,13 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseSchsystem; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface IBaseSchsystemService { + + List getSchsystemList(); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IBaseYearTermService.java b/src/main/java/com/bestsch/bschclassmanage/service/IBaseYearTermService.java new file mode 100644 index 0000000..2340347 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IBaseYearTermService.java @@ -0,0 +1,43 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.entity.BaseYearTerm; +import com.bestsch.bschclassmanage.model.tool.YearTerm; +import com.bestsch.bschclassmanage.model.vo.BaseYearTermVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.Mapping; + +import java.util.Date; +import java.util.List; + +@Service + +public interface IBaseYearTermService { + + BaseYearTerm getNowYearTerm(); + + /** + * 获取当前学年和学期 + * @return YearTerm 对象,包含 year 和 term + * @throws IllegalStateException 如果当前学年未配置或当前日期不在学期区间内 + */ + YearTerm getCurrentYearTerm(); + + List getAllYearTerm(); + + List getAllYearTermVO(); + + void createNowYearTerm(UserContext.UserInfo user,BaseYearTerm entity); + + void updateYearTerm(UserContext.UserInfo user,BaseYearTerm entity); + + BaseYearTermVO convertToVO(BaseYearTerm entity); + + List convertToVOList(List entities); + + boolean isUpgradeDate(Date date); + + boolean isBackupClassDataDate(Date date); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IComSchTreeService.java b/src/main/java/com/bestsch/bschclassmanage/service/IComSchTreeService.java new file mode 100644 index 0000000..f194573 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IComSchTreeService.java @@ -0,0 +1,46 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.model.tool.BaseTree; +import com.bestsch.bschclassmanage.model.vo.SchSystemTreeVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public interface IComSchTreeService { + + SchSystemTreeVO getGradeTree(Integer schId); + + SchSystemTreeVO getClassHistoryTree(Integer schId); + + SchSystemTreeVO getClassTree(Integer schId); + + SchSystemTreeVO getHigherSchGradeTree(Integer schId); + + SchSystemTreeVO getHigherSchClassTree(Integer schId); + + + List getSchTree(Integer schId); + + BaseTree getTeacherTree(Integer schId); + + List getSchoolList(); + + BaseTree getTeaTree(Integer schId); + + void validateGroupsBelongToSchool(Integer schId,List groupIds); + + String getTeaGroupName(Integer schId, Integer id); + + List getTeaGroupNameList(Integer schId, List ids); + + List getGroupTree(); + + String getSchoolName(Integer schId); + + Map> getSchGroupTypeList(Integer schId, int type); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ILogService.java b/src/main/java/com/bestsch/bschclassmanage/service/ILogService.java new file mode 100644 index 0000000..676486f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ILogService.java @@ -0,0 +1,19 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +@Service +public interface ILogService { + + void save(OperationLogRecord log); + void saveAllLogAsync(List logs); + PageVO search(Integer schId, String keyword,Boolean isSystem, Pageable pageable); + OperationLogRecord buildLogRecord(UserContext.UserInfo ctx, String module, String content, LocalDateTime now); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchBinSchsystemService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchBinSchsystemService.java new file mode 100644 index 0000000..a5fb03f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchBinSchsystemService.java @@ -0,0 +1,37 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchBinSchsystem; +import com.bestsch.bschclassmanage.enums.AcademicStage; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.vo.AcademicStageSchsystemVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public interface ISchBinSchsystemService { + + + List getSchIds(); + + List getSchBinSchsystemList(Integer schId); + + List getSchBinSchsystemIds(Integer schId); + + + Map getAcademicStageToSchsystemMap(Integer schId); + + List getAcademicStageSchsystemList(Integer schId); + + void saveSchBinSchsystem(SchBinSchsystem entity, Integer[] schsystemIds); + + Integer getSchType(Integer schId); + + List selectSchBinSchsystem(Integer schId); + + Map getSchBinSchsystemMap(Integer schId); + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchClassService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchClassService.java new file mode 100644 index 0000000..5fcaf85 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchClassService.java @@ -0,0 +1,72 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.model.vo.BaseSchClassVO; +import com.bestsch.bschclassmanage.model.vo.HigherSchClassVO; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Service +public interface ISchClassService { + + //List getSchClassList(Integer schId); + + List getSchClassCacheList(Integer schId); + + List getSchGradeateClassCacheList(Integer schId); + + List getSchAllClassCacheList(Integer schId); + + List getSchClassCacheFilter(Integer schId,List gradeIds,Integer classId); + + List getSchClassCacheFilter(Integer schId,Integer gradeId,Integer classId); + + List getSchAllClassCacheFilter(Integer schId,List gradeIds,Integer classId); + + List getSchAllClassCacheFilter(Integer schId,Integer gradeId,Integer classId); + + List searcBaseSchClass(Integer schId, Integer schsystemId,Integer gradeId,Integer classId); + + void addBaseSchClass(UserContext.UserInfo user, Integer gradeId, Integer number); + + void editClassName(UserContext.UserInfo user, Integer id, String cname); + + void editClassFirstTeacher(UserContext.UserInfo user, Integer id, Integer firstTeacherId) ; + + void editClassSecondTeacher(UserContext.UserInfo user, Integer id, Integer SecondTeacherId); + + void editClassCampus(UserContext.UserInfo user, Integer id, Integer campusId); + + + PageVO searcHigherSchClass(Integer schId, + Integer year, + Integer campusId, + Integer divisionId, + Integer majorsId, + Pageable pageable); + + void saveHigherSchClass(UserContext.UserInfo user, SchClass entity); + + + void deleteSchClass(UserContext.UserInfo user,Integer id,Integer schId); + + List getClassSelect(Integer schId, Integer gradeId); + + void importClasses(UserContext.UserInfo user,MultipartFile file); + + void importHeightClasses(UserContext.UserInfo user,MultipartFile file); + + Integer getMinEnrollYearBySchsystem(Integer schId, Integer schsystemId); + + void upgradeAllClasses(); + + void backupAllSnapshot(); + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchClassTeachService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchClassTeachService.java new file mode 100644 index 0000000..1eb07b0 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchClassTeachService.java @@ -0,0 +1,30 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.model.vo.SchTeachMapIdVO; +import com.bestsch.bschclassmanage.model.vo.SchTeachMapVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Service +public interface ISchClassTeachService { + + List getSchClassTeachCacheList(Integer schId,Integer gradeId,Integer classId); + + SchTeachMapVO getSchTeachMapVO(Integer schId, Integer schsystemId, Integer gradeId); + + List getSchClassTeachMapVO(Integer schId, Integer gradeId, Integer classId); + + void saveTeach(UserContext.UserInfo user, SchClassTeach entity); + + void delTeachById(UserContext.UserInfo user,Integer id); + + void delClassTeach(UserContext.UserInfo user, Integer classId); + + void delBatch(UserContext.UserInfo user,Integer schsystemId,Integer gradeId); + + void importTeach(UserContext.UserInfo user,MultipartFile file,Integer schsystemId,Integer gradeId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchCustomGroupService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchCustomGroupService.java new file mode 100644 index 0000000..2bd776f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchCustomGroupService.java @@ -0,0 +1,28 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.model.dto.AddMemberDTO; +import com.bestsch.bschclassmanage.model.dto.SchCustomGroupDTO; +import com.bestsch.bschclassmanage.model.dto.SetLeaderDTO; +import com.bestsch.bschclassmanage.model.vo.SchCustomGroupVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Service +public interface ISchCustomGroupService { + + List getSchCustomGroup(Integer schId, Integer type); + + void saveSchCustomGroup(UserContext.UserInfo user, SchCustomGroupDTO dto); + + void saveMembers(UserContext.UserInfo user, AddMemberDTO dto); + + void setLeaders(UserContext.UserInfo user, SetLeaderDTO dto); + + void deleteSchCustomGroup(UserContext.UserInfo user, Integer groupId); + + void importCustomGroup(UserContext.UserInfo user, MultipartFile file); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchDicCampusService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicCampusService.java new file mode 100644 index 0000000..2520cc0 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicCampusService.java @@ -0,0 +1,25 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchDicCampus; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public interface ISchDicCampusService { + + List getSchDicCampusCacheList(Integer schId); + + void saveSchCampus(UserContext.UserInfo user, SchDicCampus entity); + + void sortSchCampus(UserContext.UserInfo user,List Ids); + + void delete(UserContext.UserInfo user,Integer id); + + List select(Integer schId); + + Map toIdAndNameMap(Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchDicCourseService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicCourseService.java new file mode 100644 index 0000000..d43a76d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicCourseService.java @@ -0,0 +1,26 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchDicCourse; +import com.bestsch.bschclassmanage.model.dto.SchDicCourseDTO; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchDicCourseVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface ISchDicCourseService { + + List getSchDicCourseList(Integer schId); + + PageVO search(Integer schId, Integer type, String keyword, + Integer divisionId, Integer majorsId, + Pageable pageable); + + void saveSchCourse(UserContext.UserInfo user, SchDicCourseDTO dto); + + void delete(UserContext.UserInfo user, Integer id); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchDicDivisionService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicDivisionService.java new file mode 100644 index 0000000..2685c62 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicDivisionService.java @@ -0,0 +1,25 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchDicDivision; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public interface ISchDicDivisionService { + + List getSchDicDivisionCacheList(Integer schId); + + void saveSchDivision(UserContext.UserInfo user, SchDicDivision entity); + + void sortSchDivision(UserContext.UserInfo user,List Ids); + + void delete(UserContext.UserInfo user,Integer id); + + List select(Integer schId); + + Map toIdAndNameMap(Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchDicMajorsService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicMajorsService.java new file mode 100644 index 0000000..8f98b8e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicMajorsService.java @@ -0,0 +1,27 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchDicMajors; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public interface ISchDicMajorsService { + + List getSchDicMajorsCacheList(Integer schId); + + List getSchDicMajorsList(Integer schId, String keyword); + + void saveSchMajors(UserContext.UserInfo user, SchDicMajors entity); + + void sortSchMajors(UserContext.UserInfo user,List Ids); + + void delete(UserContext.UserInfo user,Integer id); + + List select(Integer schId); + + Map toIdAndNameMap(Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchDicSubjectService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicSubjectService.java new file mode 100644 index 0000000..877d563 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchDicSubjectService.java @@ -0,0 +1,25 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchDicSubject; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +@Service +public interface ISchDicSubjectService { + + List getSchSubList(Integer schId,Integer schSystemId); + + void saveSchSub(UserContext.UserInfo user, SchDicSubject entity); + + void schSubSort(UserContext.UserInfo user,List subIds,Integer schSystemId); + + void delSchSub(UserContext.UserInfo user,Integer id); + + List select(Integer schId,Integer schsystemId); + + Map toIdAndNameMap(Integer schId, Integer schsystemId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchInfoService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchInfoService.java new file mode 100644 index 0000000..0452164 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchInfoService.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.entity.SchInfo; +import com.bestsch.bschclassmanage.model.vo.oa.SchInfoVO; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface ISchInfoService { + + List getSchList(); + + List getSchVOList(String SchIDArr); + + SchInfoVO GetSchFirst(String SchID); + + SchInfoVO GetSchFirst(Integer schId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchStudentService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchStudentService.java new file mode 100644 index 0000000..4a23796 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchStudentService.java @@ -0,0 +1,63 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.model.dto.StuAbnormalStatusDTO; +import com.bestsch.bschclassmanage.model.dto.StuTransferClassDTO; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchStudentVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +@Service +public interface ISchStudentService { + + List getSchGradeClassStudentCacheList(Integer schId, Integer schsystemId, Integer gradeId, Integer classId); + +// Page searchBaseSchStudent(Integer schId, Integer schsystemId, Integer gradeId, Integer classId, +// String keyword,boolean abnormalStatus_NORMAL, Pageable pageable); +// +// Page searchBaseSchStudent(Integer schId, Integer schsystemId, Integer gradeId, Integer classId, +// String keyword, boolean abnormalStatus_NORMAL, +// Integer transferStatus, Pageable pageable); + + PageVO searchBaseSchStudentVO(Integer schId, Integer schsystemId,Integer gradeId, Integer classId, + String keyword,boolean abnormalStatus_NORMAL, Pageable pageable); + +// Page searchHigherSchStudent(Integer schId,List classIds, +// String keyword,boolean abnormalStatus_NORMAL, Pageable pageable); + + PageVO searchHigherSchStudentVO(Integer schId, Integer year, Integer classId, + String keyword,boolean abnormalStatus_NORMAL, Pageable pageable); + + PageVO searchTransferOutStudent(Integer schId, Integer gradeId,Integer classId,String keyword, + Pageable pageable); + + List searchSchClassStudentVO(Integer schId, Integer gradeId, Integer classId, boolean onlyNormal); + + + void saveStudent(UserContext.UserInfo user, SchStudentVO entity); + + void deleteStudent(UserContext.UserInfo user, String ids); + + void transferClass(UserContext.UserInfo user,StuTransferClassDTO model); + + void setAbnormalStatus(UserContext.UserInfo user,StuAbnormalStatusDTO model); + + void setTransferOut(UserContext.UserInfo user,String ids); + + void setTransferIn(UserContext.UserInfo user,StuTransferClassDTO model); + + List transferOutSchSelect(); + + void importStudents(UserContext.UserInfo user,MultipartFile file); + + void studentClassNoTemplate(HttpServletResponse response, Integer schId, Integer systemId, Integer gradeId, Integer classId); + + void importStudentClassNo(UserContext.UserInfo user, MultipartFile file, Integer schsystemId, Integer gradeId,Integer classId); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISchTeacherService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISchTeacherService.java new file mode 100644 index 0000000..65b0557 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISchTeacherService.java @@ -0,0 +1,51 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.model.dto.SchTeacherDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferGroupDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferInGroupDTO; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchTeacherTOutVO; +import com.bestsch.bschclassmanage.model.vo.SchTeacherVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.utils.UserContext; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; + +@Service +public interface ISchTeacherService { + + List getSchTeacherList(Integer schId); + + List getSchTeacherCacheList(Integer schId); + + PageVO searchSchTeacher(Integer schId, Integer groupId, String keyword, Pageable pageable); + + PageVO searchTransferOutTeacher(Integer schId, Integer groupId, String keyword, Pageable pageable); + + void saveTeacher(UserContext.UserInfo user, SchTeacherDTO dto); + + void deleteTeacher(UserContext.UserInfo user,String ids); + + Map toIdAndNameMap(Integer schId); + + List toIdAndNameSelect(Integer groupId,Integer schId); + + List toTeacherGroupSelect(Integer schId); + + List transferOutSchSelect(); + + void setTransferOut(UserContext.UserInfo user,String ids); + + void setTransferIn(UserContext.UserInfo user,TeaTransferInGroupDTO model); + + void moveGroup(UserContext.UserInfo user,TeaTransferGroupDTO model); + + void setTeacherStatus(UserContext.UserInfo user,String ids,Integer status); + + void importTeachers(UserContext.UserInfo user,MultipartFile file); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/IStudentClassHistoryService.java b/src/main/java/com/bestsch/bschclassmanage/service/IStudentClassHistoryService.java new file mode 100644 index 0000000..b7cf51e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/IStudentClassHistoryService.java @@ -0,0 +1,12 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface IStudentClassHistoryService { + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISyncGroupService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISyncGroupService.java new file mode 100644 index 0000000..073f9bf --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISyncGroupService.java @@ -0,0 +1,16 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.model.tool.BaseGroup; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface ISyncGroupService { + + void syncAddOrUpdate(BaseGroup group); + void addOrUpdateSchool(BaseGroup group); + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/ISyncUserService.java b/src/main/java/com/bestsch/bschclassmanage/service/ISyncUserService.java new file mode 100644 index 0000000..5bf8bb6 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/ISyncUserService.java @@ -0,0 +1,16 @@ +package com.bestsch.bschclassmanage.service; + +import com.bestsch.bschclassmanage.model.tool.BaseGroup; +import com.bestsch.bschclassmanage.model.tool.BaseUser; +import com.bestsch.bschclassmanage.model.tool.DeleteUser; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public interface ISyncUserService { + + void syncAddOrUpdate(List userList); + + void deleteUser(List deleteUserList); +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/com/BestOpenApi.java b/src/main/java/com/bestsch/bschclassmanage/service/com/BestOpenApi.java new file mode 100644 index 0000000..a199c78 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/com/BestOpenApi.java @@ -0,0 +1,20 @@ +package com.bestsch.bschclassmanage.service.com; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.model.tool.BaseGroup; + +import java.lang.reflect.Array; +import java.util.ArrayList; + +public class BestOpenApi { + + + public BaseGroup getGroupFirst (Integer id){ + return new BaseGroup(); + } + + public String addGroup (BaseGroup group){ + return JSON.toJSONString(new BaseGroup[]{group}); + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/com/ComSchTreeService.java b/src/main/java/com/bestsch/bschclassmanage/service/com/ComSchTreeService.java new file mode 100644 index 0000000..78c16d3 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/com/ComSchTreeService.java @@ -0,0 +1,1128 @@ +package com.bestsch.bschclassmanage.service.com; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.BaseYearTermRepository; +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.Repository.SchDicMajorsRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.entity.*; +import com.bestsch.bschclassmanage.enums.AcademicStage; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.tool.BaseTree; +import com.bestsch.bschclassmanage.model.vo.SchSystemTreeVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import com.yunhai.platform.utils.exception.DException; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class ComSchTreeService implements IComSchTreeService { + + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private IBaseSchsystemService baseSchsystemService; // 新增 + + @Autowired + @Lazy + private ISchClassService schClassService; + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private IBaseYearTermService baseYearTermService; + + @Autowired + private SchDicMajorsRepository schDicMajorsRepository; + + @Autowired + @Lazy + private ISchTeacherService schTeacherService; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private RedisUtil redisUtil; + + // 基础学制缓存(ID -> BaseSchsystem) + private Map baseSchsystemMap; + private final Object lock = new Object(); + + /** + * 获取基础学制映射(带双重检查锁) + */ + private Map getBaseSchsystemMap() { + if (baseSchsystemMap == null) { + synchronized (lock) { + if (baseSchsystemMap == null) { + List list = baseSchsystemService.getSchsystemList(); + baseSchsystemMap = list.stream() + .collect(Collectors.toMap( + BaseSchsystem::getId, + b -> b, + (a, b) -> a + )); + } + } + } + return baseSchsystemMap; + } + + public SchSystemTreeVO getGradeTree(Integer schId) { + return getGradeClassTree(schId, false); + } + + public SchSystemTreeVO getClassTree(Integer schId) { + return getGradeClassTree(schId, true); + } + + public SchSystemTreeVO getHigherSchGradeTree(Integer schId) { + return getHigherSchGradeClassTree(schId, false); + } + + public SchSystemTreeVO getHigherSchClassTree(Integer schId) { + return getHigherSchGradeClassTree(schId, true); + } + + + public List getSchTree(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_TREE + "_" + schId; + String json = redisUtil.get(cacheKey,String.class); + List treeList = OtherUtil.jsonParseArrayTree(json, BaseTree.class); + return treeList; + } + + + public String getSchoolName(Integer schId) { + if (schId == null) { + return null; + } + // 方式1:从已缓存的学校列表中查找(推荐) + List schoolList = getSchoolList(); // 复用已有的学校列表缓存 + return schoolList.stream() + .filter(s -> s.getId().equals(schId)) + .map(SelectIntVO::getName) + .findFirst() + .orElse(null); + } + + + /** + * 获取 type=7 的节点及其所有子节点(教师组子树) + * @param schId 学校ID + * @return 教师组节点(含子节点),若未找到则返回 null + */ + public BaseTree getTeaTree(Integer schId) { + List treeList = getSchTree(schId); + if (treeList == null || treeList.isEmpty()) { + return null; + } + // 遍历根节点列表(通常只有一个),递归查找 type=7 + for (BaseTree root : treeList) { + root.setExpand(true); + BaseTree result = findNodeByType(root, NodeType.TEACHER.getId()); + if (result != null) { + return result; + } + } + return null; + } + + + + + /** + * 校验一组组ID是否都属于指定学校,若存在不属于该校的组则抛出异常 + * @param schId 学校ID + * @param groupIds 组ID列表 + * @throws DException 当存在组不属于该校时抛出 + */ + public void validateGroupsBelongToSchool(Integer schId, List groupIds) { + if (groupIds == null || groupIds.isEmpty()) { + return; + } + + // 方式一:通过教师树校验(如有缓存) + BaseTree teaTree = getTeaTree(schId); + if (teaTree == null) { + throw new DException("该校暂无教师组"); + } + List allNodes = flattenTree(teaTree); + Set validGroupIds = allNodes.stream() + .map(BaseTree::getId) + .collect(Collectors.toSet()); + + for (Integer groupId : groupIds) { + if (!validGroupIds.contains(groupId)) { + throw new DException("组ID " + groupId + " 不属于当前学校"); + } + } + } + + public List getGroupTree() { + String cacheKey = "bsch.classmanage.group_tree"; + // 直接从Redis获取JSON字符串 + String json = redisUtil.get(cacheKey, String.class); + // 解析为树结构 + List treeList = OtherUtil.jsonParseArrayTree(json, BaseTree.class); + // 过滤并处理:type=2的节点停止递归 + return filterTreeByType(treeList, NodeType.SCHOOL.getId()); + } + + public List getSchoolList() { + String cacheKey = RedisConstants.SCHOOL_LIST; + // 1. 尝试从缓存获取 + String cachedJson = redisUtil.get(cacheKey, String.class); + if (StringUtils.isNotBlank(cachedJson)) { + return JSON.parseArray(cachedJson, SelectIntVO.class); + } + + // 2. 从组树构建(扁平化收集所有学校节点) + List treeList = getGroupTree(); + if (treeList == null || treeList.isEmpty()) { + return Collections.emptyList(); + } + + // 收集所有学校节点 + List schoolNodes = new ArrayList<>(); + for (BaseTree root : treeList) { + flattenTreeByType(root, NodeType.SCHOOL.getId(), schoolNodes); + } + + List result = schoolNodes.stream() + .map(node -> { + SelectIntVO vo = new SelectIntVO(); + vo.setId(node.getId()); + vo.setName(node.getName()); + return vo; + }) + .sorted(Comparator.comparing(SelectIntVO::getName)) + .collect(Collectors.toList()); + + // 3. 存入缓存(30天) + String json = JSON.toJSONString(result); + redisUtil.set(cacheKey, json, RedisConstants.CACHE_EXPIRE_30D); + return result; + } + + public Map> getSchGroupTypeList(Integer schId, int type) { + Map academicStageToSchsystemMap = schBinSchsystemService.getAcademicStageToSchsystemMap(schId); + Map> resultMap = new HashMap<>(); + List schTree = getSchTree(schId); + if (schTree == null || schTree.isEmpty()) { + return resultMap; + } + + if (academicStageToSchsystemMap.size() == 1) { + // 单学段:收集所有目标节点,仍需要 parent 参数以支持名称拼接 + List allNodes = new ArrayList<>(); + collectNodesByType(schTree, type, allNodes); // 恢复 parent 参数 + Integer schsystemId = academicStageToSchsystemMap.values().iterator().next(); + resultMap.put(schsystemId, allNodes); + } else { + // 多学段:构建学段名称 → 学段ID 映射(仅包含学校支持的学段) + Map stageNameToId = AcademicStage.list().stream() + .filter(s -> academicStageToSchsystemMap.containsKey(s.getKey())) + .collect(Collectors.toMap(AcademicStage::getValue, AcademicStage::getKey)); + // 递归收集,传入学段->学制映射,初始 currentStageId = null + collectNodesGroupByStage(schTree, type, resultMap, stageNameToId, + academicStageToSchsystemMap, null); + } + return resultMap; + } + + + public String getTeaGroupName(Integer schId, Integer id) { + BaseTree tree = getTeaTree(schId); + if (tree == null) return null; + // 懒加载缓存(若树结构不变) + if (idToNameCache == null) { + idToNameCache = new HashMap<>(); + buildCache(tree); + } + return idToNameCache.get(id); + } + + + public List getTeaGroupNameList(Integer schId, List ids) { + // 1. 构建缓存(如果尚未构建) + if (idToNameCache == null) { + BaseTree tree = getTeaTree(schId); + if (tree == null) { + return Collections.emptyList(); + } + idToNameCache = new HashMap<>(); + buildCache(tree); + } + + // 2. 如果缓存为空,直接返回空 + if (idToNameCache.isEmpty()) { + return Collections.emptyList(); + } + + // 3. 处理 ids 参数 + List targetIds; + if (ids == null) { + // 如果 ids 为 null,返回全部(从缓存中取出所有 key) + targetIds = new ArrayList<>(idToNameCache.keySet()); + } else { + // 过滤掉 null 的 ID,并去重(可选) + targetIds = ids.stream() + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (targetIds.isEmpty()) { + return Collections.emptyList(); + } + } + + // 4. 根据 targetIds 构建结果列表 + List result = new ArrayList<>(); + for (Integer id : targetIds) { + String name = idToNameCache.get(id); + if (name != null) { + SelectIntVO vo = new SelectIntVO(); + vo.setId(id); + vo.setName(name); + result.add(vo); + } + } + return result; + } + + /** + * 获取教师组织树 + * - 组织节点 type=0,children 为子节点列表(保证非 null) + * - 教师节点 type=1,children 为空列表([]) + */ + public BaseTree getTeacherTree(Integer schId) { + // 1. 获取教师组织树(组织骨架) + BaseTree teaTree = getTeaTree(schId); + if (teaTree == null) { + teaTree = new BaseTree(); + teaTree.setId(0); + teaTree.setName("教师组"); + teaTree.setType(0); + teaTree.setChildren(new ArrayList<>()); + teaTree.setExpand(true); + } + + // 2. 获取该校所有教师 + List teacherList = schTeacherService.getSchTeacherList(schId); + if (CollectionUtils.isEmpty(teacherList)) { + // 即使没有教师,也要确保所有节点 children 非 null + ensureChildrenNotEmpty(teaTree); + return teaTree; + } + + // 3. 批量查询教师的组织关系 + List teaIds = teacherList.stream().map(SchTeacher::getTeaId).collect(Collectors.toList()); + List groups = schTeacherGroupRepository.findByTeaIdInAndSchId(teaIds, schId); + Map> teaIdToGroupIds = groups.stream() + .collect(Collectors.groupingBy(SchTeacherGroup::getTeaId, + Collectors.mapping(SchTeacherGroup::getGroupId, Collectors.toList()))); + + // 收集所有组织ID(用于修正类型) + Set orgIdSet = groups.stream().map(SchTeacherGroup::getGroupId).collect(Collectors.toSet()); + // 收集所有教师 teaId 集合 + Set teacherIdSet = new HashSet<>(teaIds); + + // 4. 修正树节点类型:组织节点 type=0,教师节点 type=1 + fixTreeTypes(teaTree, teacherIdSet, orgIdSet); + + // 5. 构建组织ID -> 节点映射 + Map orgNodeMap = new HashMap<>(); + buildOrgNodeMap(teaTree, orgNodeMap); + + // 6. 遍历教师,添加到对应组织 + for (SchTeacher teacher : teacherList) { + List groupIds = teaIdToGroupIds.getOrDefault(teacher.getTeaId(), Collections.emptyList()); + if (groupIds.isEmpty()) { + BaseTree defaultGroup = getOrCreateDefaultGroup(teaTree, orgNodeMap); + addTeacherToNode(defaultGroup, teacher); + } else { + for (Integer groupId : groupIds) { + BaseTree parentNode = orgNodeMap.get(groupId); + if (parentNode == null) { + parentNode = getOrCreateDefaultGroup(teaTree, orgNodeMap); + } + addTeacherToNode(parentNode, teacher); + } + } + } + + // 7. 排序 + sortTreeNodes(teaTree); + + // 8. 确保所有节点的 children 都不为 null,统一为 List(空列表) + ensureChildrenNotEmpty(teaTree); + + return teaTree; + } + + /** + * 递归确保所有节点的 children 不为 null,若为 null 则设置为空列表 [] + */ + private void ensureChildrenNotEmpty(BaseTree node) { + if (node == null) return; + if (node.getChildren() == null) { + node.setChildren(new ArrayList<>()); + } + if (node.getChildren() != null) { + for (BaseTree child : node.getChildren()) { + ensureChildrenNotEmpty(child); + } + } + } + + /** + * 递归修正树中节点的类型: + * - 根节点设为 type=0 + * - 如果节点ID在 teacherIdSet 中,设为 type=1 + * - 如果节点ID在 orgIdSet 中,设为 type=0 + * - 其他情况:如果有 children(非空且非空列表)则设为 type=0,否则设为 type=0(默认为组织) + */ + private void fixTreeTypes(BaseTree node, Set teacherIdSet, Set orgIdSet) { + if (node == null) return; + // 根节点(id=0 或 其他)设为组织 + if (node.getId().equals(0) || node.getType() == 7) { + node.setType(0); + } else if (teacherIdSet.contains(node.getId())) { + node.setType(1); + } else if (orgIdSet.contains(node.getId())) { + node.setType(0); + } else { + // 根据是否有 children 判断 + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + node.setType(0); + } else { + node.setType(0); + } + } + // 递归处理子节点 + if (node.getChildren() != null) { + for (BaseTree child : node.getChildren()) { + fixTreeTypes(child, teacherIdSet, orgIdSet); + } + } + } + + /** + * 将教师添加到指定组织节点(去重) + * 教师节点的 children 设置为空列表([]),而非 null + */ + private void addTeacherToNode(BaseTree parentNode, SchTeacher teacher) { + if (parentNode == null) return; + // 检查是否已存在该教师(按 teaId 去重) + if (isTeacherExists(parentNode, teacher.getTeaId())) { + return; + } + BaseTree teacherNode = new BaseTree(); + teacherNode.setId(teacher.getTeaId()); + teacherNode.setName(teacher.getName()); + teacherNode.setType(1); + teacherNode.setCode(null); + teacherNode.setOrder(teacher.getSort() != null ? String.valueOf(teacher.getSort()) : null); + teacherNode.setExpand(false); + // ★ 修改点:教师节点的 children 设为空列表,而不是 null + teacherNode.setChildren(new ArrayList<>()); + + if (parentNode.getChildren() == null) { + parentNode.setChildren(new ArrayList<>()); + } + parentNode.getChildren().add(teacherNode); + } + + /** + * 递归构建组织 ID -> 节点映射(仅 type=0) + */ + private void buildOrgNodeMap(BaseTree node, Map orgNodeMap) { + if (node == null) return; + if (node.getType() == 0) { + orgNodeMap.put(node.getId(), node); + } + if (node.getChildren() != null) { + for (BaseTree child : node.getChildren()) { + buildOrgNodeMap(child, orgNodeMap); + } + } + } + + /** + * 获取或创建“未分组”节点(ID = -1) + */ + private BaseTree getOrCreateDefaultGroup(BaseTree root, Map orgNodeMap) { + final Integer DEFAULT_GROUP_ID = -1; + BaseTree defaultGroup = orgNodeMap.get(DEFAULT_GROUP_ID); + if (defaultGroup == null) { + defaultGroup = new BaseTree(); + defaultGroup.setId(DEFAULT_GROUP_ID); + defaultGroup.setName("未分组"); + defaultGroup.setType(0); + defaultGroup.setChildren(new ArrayList<>()); + defaultGroup.setExpand(true); + if (root.getChildren() == null) { + root.setChildren(new ArrayList<>()); + } + root.getChildren().add(defaultGroup); + orgNodeMap.put(DEFAULT_GROUP_ID, defaultGroup); + } + return defaultGroup; + } + + /** + * 检查节点下是否已存在指定 teaId 的教师 + */ + private boolean isTeacherExists(BaseTree parentNode, Integer teaId) { + if (parentNode.getChildren() == null) return false; + for (BaseTree child : parentNode.getChildren()) { + if (child.getType() == 1 && child.getId().equals(teaId)) { + return true; + } + } + return false; + } + + /** + * 排序:先按 order 排(若不为空),再按 name 排序(组织节点和教师节点分别处理) + * 这里只对教师节点排序,组织节点保留原顺序 + */ + private void sortTreeNodes(BaseTree node) { + if (node == null || node.getChildren() == null) return; + // 分离组织节点和教师节点 + List orgChildren = node.getChildren().stream() + .filter(c -> c.getType() == 0) + .collect(Collectors.toList()); + List teacherChildren = node.getChildren().stream() + .filter(c -> c.getType() == 1) + .sorted(Comparator.comparing((BaseTree t) -> { + String order = t.getOrder(); + if (order != null && !order.isEmpty()) { + try { + return Integer.parseInt(order); + } catch (NumberFormatException e) { + return Integer.MAX_VALUE; + } + } + return Integer.MAX_VALUE; + }) + .thenComparing(BaseTree::getName, String.CASE_INSENSITIVE_ORDER)) + .collect(Collectors.toList()); + + // 合并:先组织,后教师 + List sorted = new ArrayList<>(); + sorted.addAll(orgChildren); + sorted.addAll(teacherChildren); + node.setChildren(sorted); + + // 递归排序子组织 + for (BaseTree child : orgChildren) { + sortTreeNodes(child); + } + } + + // ==================== 私有构建方法 ==================== + + private SchSystemTreeVO getGradeClassTree(Integer schId, boolean includeClass) { + // 1. 构建学校根节点 + SchSystemTreeVO root = buildSchoolRoot(schId); + + // 2. 获取学制列表并构建学制节点 + List systemList = schBinSchsystemService.selectSchBinSchsystem(schId); + if (CollectionUtils.isEmpty(systemList)) { + root.setExpand(true); + root.setChildren(Collections.emptyList()); + return root; + } + List systemNodes = systemList.stream() + .map(system -> buildSystemNode(schId, system, includeClass)) + .collect(Collectors.toList()); + root.setChildren(systemNodes); + return root; + } + + /** + * 递归查找指定 type 的节点(返回该节点及子树) + */ + private BaseTree findNodeByType(BaseTree node, int targetType) { + if (node == null) { + return null; + } + if (node.getType() != null && node.getType() == targetType) { + return node; // 找到目标节点,返回整个节点(含其 children) + } + if (node.getChildren() != null) { + for (BaseTree child : node.getChildren()) { + BaseTree found = findNodeByType(child, targetType); + if (found != null) { + return found; + } + } + } + return null; + } + + + + + /** + * 构建学校根节点 + */ + private SchSystemTreeVO buildSchoolRoot(Integer schId) { + Integer schTypeId = schBinSchsystemService.getSchType(schId); + String schoolName = getSchoolName(schId); // 需自行实现 + SchSystemTreeVO root = new SchSystemTreeVO(); + root.setName(schoolName); + root.setType(NodeType.SCHOOL); + root.setEducationType(schTypeId); + root.setExpand(true); + root.setSort(1); + return root; + } + + /** + * 构建学制节点(含其下的年级和班级) + */ + private SchSystemTreeVO buildSystemNode(Integer schId, SelectIntVO system, boolean includeClass) { + SchSystemTreeVO systemNode = new SchSystemTreeVO(); + systemNode.setId(system.getId()); + systemNode.setSchsystemId(system.getId()); + systemNode.setName(system.getName()); + systemNode.setType(NodeType.SECTION); + systemNode.setExpand(true); + // 获取年级列表和入学年份映射 + List gradeList = baseSchsystemGradeService.getSchGradeCacheList(schId, system.getId(), null); + if (CollectionUtils.isEmpty(gradeList)) { + systemNode.setChildren(Collections.emptyList()); + return systemNode; + } + + Map yearMap = baseSchsystemGradeService.getNowYearGradeMap(schId, system.getId()); + + // 如果需要班级,提前分组加载(final 确保 lambda 可访问) + final Map> classGroupMap; + if (includeClass) { + List gradeIds = gradeList.stream() + .map(BaseSchsystemGrade::getGradeId) + .collect(Collectors.toList()); + if (!gradeIds.isEmpty()) { + List classList = schClassService.getSchClassCacheFilter(schId, gradeIds, null); + if (!CollectionUtils.isEmpty(classList)) { + classGroupMap = classList.stream() + .collect(Collectors.groupingBy(SchClass::getGradeId)); + } else { + classGroupMap = Collections.emptyMap(); + } + } else { + classGroupMap = Collections.emptyMap(); + } + } else { + classGroupMap = Collections.emptyMap(); + } + + // 构建年级节点 + List gradeNodes = gradeList.stream() + .map(grade -> { + List classList = null; + if (includeClass) { + classList = classGroupMap.getOrDefault(grade.getGradeId(), Collections.emptyList()); + } + return buildGradeNode(grade, system.getId(), yearMap, includeClass, classList); + }) + .collect(Collectors.toList()); + systemNode.setChildren(gradeNodes); + return systemNode; + } + + /** + * 构建年级节点(包含班级子节点) + */ + private SchSystemTreeVO buildGradeNode(BaseSchsystemGrade grade, Integer systemId, + Map yearMap, + boolean includeClass, + List classList) { + SchSystemTreeVO gradeNode = new SchSystemTreeVO(); + gradeNode.setId(grade.getGradeId()); + gradeNode.setGradeId(grade.getGradeId()); + gradeNode.setName(grade.getGradeNickname()); + gradeNode.setEnrollYear(yearMap.get(grade.getGradeId())); + gradeNode.setSchsystemId(systemId); + gradeNode.setType(NodeType.GRADE); + gradeNode.setSort(grade.getId()); + gradeNode.setExpand(true); + if (includeClass && !CollectionUtils.isEmpty(classList)) { + List classNodes = classList.stream() + .map(clazz -> buildClassNode(clazz, grade.getGradeId(), systemId, yearMap.get(grade.getGradeId()))) + .collect(Collectors.toList()); + gradeNode.setChildren(classNodes); + } else { + gradeNode.setChildren(Collections.emptyList()); + } + return gradeNode; + } + + /** + * 构建班级节点(叶子节点) + */ + private SchSystemTreeVO buildClassNode(SchClass clazz, Integer gradeId, Integer systemId, Integer enrollYear) { + SchSystemTreeVO classNode = new SchSystemTreeVO(); + classNode.setId(clazz.getClassId()); + classNode.setClassId(clazz.getClassId()); + classNode.setGradeId(gradeId); + classNode.setSchsystemId(systemId); + classNode.setName(StringUtils.isBlank(clazz.getCname()) ? clazz.getName() : clazz.getCname()); + classNode.setEnrollYear(enrollYear); + classNode.setType(NodeType.CLASS); + classNode.setSort(clazz.getSort()); + classNode.setChildren(Collections.emptyList()); // 叶子节点 + return classNode; + } + + + /** + * 递归过滤树结构,当节点type等于指定类型时停止递归 + * @param treeList 树节点列表 + * @param stopType 停止递归的类型 + * @return 过滤后的树列表 + */ + private List filterTreeByType(List treeList, int stopType) { + if (treeList == null || treeList.isEmpty()) { + return treeList; + } + + List result = new ArrayList<>(); + + for (BaseTree node : treeList) { + // 如果当前节点type等于stopType,保留该节点但清空子节点 + if (node.getType() == stopType) { + // 保留该节点,但移除所有子节点(停止递归) + node.setChildren(null); // 或者 node.setChildren(new ArrayList<>()); + result.add(node); + } else { + // type不等于stopType,递归处理子节点 + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + List filteredChildren = filterTreeByType(node.getChildren(), stopType); + node.setChildren(filteredChildren); + } + result.add(node); + } + } + return result; + } + + + private SchSystemTreeVO getHigherSchGradeClassTree(Integer schId, boolean includeClass) { + // 1. 构建学校根节点 + SchSystemTreeVO root = buildSchoolRoot(schId); + + // 获取当前学年 + Integer year = baseYearTermService.getNowYearTerm().getYear(); + // 获取专业最大学制 + Integer maxSchsystemLeng = schDicMajorsRepository.findMaxSchsystemLengBySchId(schId).orElse(0); + + if(maxSchsystemLeng==0){ + throw new IllegalArgumentException("请创建高校系部和专业!"); + } + + + SelectIntVO systemVO=schBinSchsystemService.selectSchBinSchsystem(schId).stream().findFirst() + .orElseThrow(() -> new RuntimeException("学制未选择!")); + + // 2. 循环生成年级节点(从当前学年往前推) + List gradeNodes = new ArrayList<>(); + for (int i = 0; i < maxSchsystemLeng; i++) { + int gradeYear = year - i; // 递减 + // 构建每个年级节点(根据业务查询年级信息) + SchSystemTreeVO gradeNode = buildGradeNode(schId, gradeYear,systemVO, includeClass); + gradeNodes.add(gradeNode); + } + + // 3. 将年级节点挂到根节点下 + root.setChildren(gradeNodes); + + return root; + } + + private SchSystemTreeVO buildGradeNode(Integer schId, Integer gradeYear,SelectIntVO systemVO, boolean includeClass) { + SchSystemTreeVO node = new SchSystemTreeVO(); + node.setId(gradeYear); // 或根据实际年级ID + node.setName(gradeYear + "级"); + node.setType(NodeType.GRADE); // 年级类型为2 + node.setGradeId(gradeYear); + node.setSchsystemId(systemVO.getId()); + if (includeClass) { + // 查询该年级下的班级列表,并转换为子节点 + List classList = schClassRepository.findBySchIdAndEnrollYear(schId, gradeYear); + List classNodes = classList.stream() + .map(cls -> { + SchSystemTreeVO classNode = new SchSystemTreeVO(); + classNode.setId(cls.getClassId()); + classNode.setName(cls.getName()); + classNode.setClassId(cls.getClassId()); + classNode.setEnrollYear(cls.getEnrollYear()); + classNode.setType(NodeType.CLASS); // 班级类型 + return classNode; + }) + .collect(Collectors.toList()); + node.setChildren(classNodes); + } + + return node; + } + + + + /** + * 原有递归收集方法(单学段或无条件收集) + * 不进行分组,将所有符合类型的节点加入 result 列表 + */ + private void collectNodesByType(List treeList, int targetType, + List result) { + for (BaseTree node : treeList) { + if (node.getType() == targetType) { + SelectIntVO vo = new SelectIntVO(); + vo.setId(node.getId()); + vo.setName(node.getName()); + result.add(vo); + } + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + collectNodesByType(node.getChildren(), targetType, result); + } + } + } + + /** + * 递归收集树中指定类型的节点,并按学段分组(支持祖先链匹配) + * @param treeList 当前层级节点 + * @param targetType 目标类型 + * @param resultMap 结果Map + * @param stageNameToId 学段名称→学段ID映射 + * @param stageToSchsystemMap 学段ID→学制ID映射 + * @param currentStageId 当前路径上最近匹配的学段ID(null表示尚未匹配) + */ + private void collectNodesGroupByStage(List treeList, int targetType, + Map> resultMap, + Map stageNameToId, + Map stageToSchsystemMap, + Integer currentStageId) { + for (BaseTree node : treeList) { + // 1. 检查当前节点是否为学段(名称匹配),更新最近学段ID + Integer newStageId = currentStageId; + if (stageNameToId.containsKey(node.getName())) { + newStageId = stageNameToId.get(node.getName()); + } + + // 2. 如果当前节点是目标类型,且存在有效的学段ID,则加入结果 + if (node.getType() == targetType && newStageId != null) { + Integer schsystemId = stageToSchsystemMap.get(newStageId); + if (schsystemId != null) { + SelectIntVO vo = new SelectIntVO(); + vo.setId(node.getId()); + vo.setName(node.getName()); // 简单版,如需拼接可替换 + resultMap.computeIfAbsent(schsystemId, k -> new ArrayList<>()).add(vo); + } + } + + // 3. 递归子节点,传递当前节点作为 parent(用于拼接),以及更新后的学段ID + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + collectNodesGroupByStage(node.getChildren(), targetType, resultMap, + stageNameToId, stageToSchsystemMap, newStageId); + } + } + } + + private Map idToNameCache; + + private void buildCache(BaseTree node) { + if (node == null) return; + idToNameCache.put(node.getId(), node.getName()); + if (node.getChildren() != null) { + for (BaseTree child : node.getChildren()) { + buildCache(child); + } + } + } + + private List flattenTree(BaseTree root) { + List result = new ArrayList<>(); + if (root == null) return result; + result.add(root); + if (root.getChildren() != null) { + for (BaseTree child : root.getChildren()) { + result.addAll(flattenTree(child)); + } + } + return result; + } + + /** + * 递归扁平化树,收集指定类型的节点 + */ + private void flattenTreeByType(BaseTree node, int type, List collector) { + if (node == null) return; + if (node.getType() != null && node.getType() == type) { + collector.add(node); + } + if (node.getChildren() != null) { + for (BaseTree child : node.getChildren()) { + flattenTreeByType(child, type, collector); + } + } + } +//------------- + + public SchSystemTreeVO getClassHistoryTree(Integer schId) { + if(schBinSchsystemService.getSchType(schId).equals(SchType.BASICEDUCATION.getKey())) + { + return getGradeClassTreeWithFullName(schId); + }else { + return buildVocationalTree(schId); + } + } + + /** + * 构建年级-班级树(使用完整名称) + */ + private SchSystemTreeVO getGradeClassTreeWithFullName(Integer schId) { + SchSystemTreeVO root = buildSchoolRoot(schId); + List systemList = schBinSchsystemService.selectSchBinSchsystem(schId); + if (CollectionUtils.isEmpty(systemList)) { + root.setExpand(true); + root.setChildren(Collections.emptyList()); + return root; + } + List systemNodes = systemList.stream() + .map(system -> buildSystemNodeWithFullName(schId, system)) + .collect(Collectors.toList()); + root.setChildren(systemNodes); + return root; + } + private SchSystemTreeVO buildSystemNodeWithFullName(Integer schId, SelectIntVO system) { + SchSystemTreeVO systemNode = new SchSystemTreeVO(); + systemNode.setId(system.getId()); + systemNode.setName(system.getName()); + systemNode.setType(NodeType.SECTION); + systemNode.setExpand(true); + systemNode.setSchsystemId(system.getId()); // system.getId() 就是基础学制ID + + // 1. 获取学制长度 + Map baseMap = getBaseSchsystemMap(); + final Integer schsystemLength = Optional.ofNullable(baseMap.get(system.getId())) + .map(BaseSchsystem::getGraduationLeng) + .orElse(0); + + // 2. 获取该学制下【所有】年级(包括已删除的) + // 注意:这里必须使用全量查询,建议改用 Repository 方法 + // 如果 getSchGradeCacheList 无法返回历史,请替换为 baseSchsystemGradeRepository.findAllBySchIdAndSchsystemId + List allGrades = baseSchsystemGradeService.getSchGradeCacheList(schId, system.getId(), null); + // 如果 allGrades 不包含历史,但您希望得到完整名称,可以补充默认列表 + // 为保险,我们同时根据学制长度构造一个默认名称列表 + List gradeNameList = allGrades.stream() + .sorted(Comparator.comparingInt(BaseSchsystemGrade::getGradeId).reversed()) + .map(BaseSchsystemGrade::getGradeNickname) + .collect(Collectors.toList()); + + // 如果年级列表长度不足学制长度,补充默认名称(例如“初一”、“初二”等) + // 这里根据当前年份推算起始年份,然后生成默认名称 + Integer currentYear = baseYearTermService.getNowYearTerm().getYear(); // 2025 + int startYear = currentYear - schsystemLength + 1; // 2022 + // 如果 allGrades 不够,则用默认名称补齐 + if (gradeNameList.size() < schsystemLength) { + // 根据学制长度生成默认名称:从“一年级”到“N年级” + for (int i = gradeNameList.size(); i < schsystemLength; i++) { + gradeNameList.add((i + 1) + "年级"); + } + } + + // 3. 获取该学制下所有班级 + List gradeIds = allGrades.stream().map(BaseSchsystemGrade::getGradeId).collect(Collectors.toList()); + List allClasses = schClassService.getSchAllClassCacheFilter(schId, gradeIds, null); + + // 4. 按入学年份分组 + Map> classByYear = allClasses.stream() + .filter(c -> c.getEnrollYear() != null) + .collect(Collectors.groupingBy(SchClass::getEnrollYear)); + + // 5. 确定年份范围:最小入学年份 -> 当前学年 + Integer minYear = classByYear.keySet().stream().min(Integer::compareTo).orElse(null); + if (minYear == null) { + systemNode.setChildren(Collections.emptyList()); + return systemNode; + } + + // 6. 推算每个年份的年级名称(核心修正) + Map yearToGradeName = new HashMap<>(); + // 起始年份 = 当前年份 - 学制长度 + 1 + for (int i = 0; i < schsystemLength; i++) { + int year = startYear + i; + if (year >= minYear && year <= currentYear) { + // 如果年级列表有该索引,使用名称;否则用默认 + String name = (i < gradeNameList.size()) ? gradeNameList.get(i) : (i + 1) + "年级"; + yearToGradeName.put(year, name); + } + } + // 处理早于 startYear 的年份(如2021),赋予最后一个年级名称 + if (minYear < startYear) { + String lastName = (schsystemLength <= gradeNameList.size()) ? gradeNameList.get(schsystemLength - 1) : schsystemLength + "年级"; + for (int year = minYear; year < startYear; year++) { + yearToGradeName.put(year, lastName); + } + } + + // 7. 用班级的 gradeId 映射覆盖(如果存在更精确的名称) + Map gradeIdToName = allGrades.stream() + .collect(Collectors.toMap( + BaseSchsystemGrade::getGradeId, + BaseSchsystemGrade::getGradeNickname, + (a, b) -> a + )); + for (SchClass clazz : allClasses) { + Integer year = clazz.getEnrollYear(); + if (year == null || year < minYear || year > currentYear) continue; + Integer gId = clazz.getGradeId(); + String name = gradeIdToName.get(gId); + if (name != null) { + yearToGradeName.put(year, name); + } + } + + // 8. 生成所有年份节点 + List gradeNodes = new ArrayList<>(); + for (int year = minYear; year <= currentYear; year++) { + List classList = classByYear.getOrDefault(year, Collections.emptyList()); + String gradeName = yearToGradeName.getOrDefault(year, year + "级"); + SchSystemTreeVO gradeNode = buildGradeNodeWithFullNameByYear( + year, gradeName, system.getId(), schsystemLength, classList + ); + gradeNodes.add(gradeNode); + } + systemNode.setChildren(gradeNodes); + return systemNode; + } + + private SchSystemTreeVO buildGradeNodeWithFullNameByYear(Integer enrollYear, + String gradeName, + Integer systemId, + Integer schsystemLength, + List classList) { + SchSystemTreeVO gradeNode = new SchSystemTreeVO(); + gradeNode.setId(enrollYear); + gradeNode.setGradeId(enrollYear); + gradeNode.setEnrollYear(enrollYear); + + // 计算毕业状态 + int graduation = 0; + if (enrollYear != null && schsystemLength != null) { + Integer currentYear = baseYearTermService.getNowYearTerm().getYear(); + Integer graduationYear = enrollYear + schsystemLength; + graduation = (currentYear >= graduationYear) ? 1 : 0; // 当年已毕业 + } + + // 组装显示名称 + String displayName = enrollYear + "级"; + if (graduation == 1) { + displayName += "(已毕业)"; + } else { + displayName += "(" + gradeName + ")"; + } + gradeNode.setName(displayName); + gradeNode.setGraduation(graduation); + gradeNode.setSchsystemId(systemId); + gradeNode.setType(NodeType.GRADE); + gradeNode.setSort(enrollYear); + gradeNode.setExpand(true); + + if (!CollectionUtils.isEmpty(classList)) { + gradeNode.setChildren(classList.stream() + .map(clazz -> buildClassNode(clazz, enrollYear, systemId, enrollYear)) + .collect(Collectors.toList())); + } else { + gradeNode.setChildren(Collections.emptyList()); + } + return gradeNode; + } + + private SchSystemTreeVO buildVocationalTree(Integer schId) { + // 1. 构建学校根节点 + SchSystemTreeVO root = buildSchoolRoot(schId); + root.setExpand(true); + + // 2. 获取该校所有班级 + List allClasses = schClassService.getSchAllClassCacheList(schId); + if (CollectionUtils.isEmpty(allClasses)) { + root.setChildren(Collections.emptyList()); + return root; + } + + // 3. 按入学年份分组 + Map> classByYear = allClasses.stream() + .filter(c -> c.getEnrollYear() != null) + .collect(Collectors.groupingBy(SchClass::getEnrollYear)); + + // 4. 确定年份范围 + Integer currentYear = baseYearTermService.getNowYearTerm().getYear(); + Integer minYear = classByYear.keySet().stream().min(Integer::compareTo).orElse(null); + if (minYear == null) { + root.setChildren(Collections.emptyList()); + return root; + } + + // 5. 生成年级节点(从 minYear 到 currentYear) + List gradeNodes = new ArrayList<>(); + // 职业教育学制通常为3年,但这里根据班级实际年份生成,毕业状态可按需计算 + for (int year = minYear; year <= currentYear; year++) { + List classList = classByYear.getOrDefault(year, Collections.emptyList()); + + // 计算毕业状态(假设学制3年,可根据实际调整) + int graduation = 0; + if (year >0) { + Integer graduationYear = year + 3; // 3年制 + graduation = (currentYear >= graduationYear) ? 1 : 0; + } + + // 构建年级节点 + SchSystemTreeVO gradeNode = new SchSystemTreeVO(); + gradeNode.setId(year); + gradeNode.setGradeId(year); + gradeNode.setEnrollYear(year); + gradeNode.setName(year + "级"); + gradeNode.setGraduation(graduation); + gradeNode.setType(NodeType.GRADE); + gradeNode.setSort(year); + gradeNode.setExpand(true); + + // 构建班级子节点(schsystemId 传 null,班级节点不依赖学制) + if (!CollectionUtils.isEmpty(classList)) { + Integer gradeYear=year; + List classNodes = classList.stream() + .map(clazz -> buildClassNode(clazz, gradeYear, null, gradeYear)) + .collect(Collectors.toList()); + gradeNode.setChildren(classNodes); + } else { + gradeNode.setChildren(Collections.emptyList()); + } + gradeNodes.add(gradeNode); + } + root.setChildren(gradeNodes); + return root; + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/com/LogService.java b/src/main/java/com/bestsch/bschclassmanage/service/com/LogService.java new file mode 100644 index 0000000..75da02b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/com/LogService.java @@ -0,0 +1,76 @@ +package com.bestsch.bschclassmanage.service.com; + +import com.bestsch.bschclassmanage.Repository.OperationLogRecordRepository; +import com.bestsch.bschclassmanage.Repository.specification.OperationLogSpecifications; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.service.ILogService; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Service +public class LogService implements ILogService { + + @Autowired + private OperationLogRecordRepository repository; + + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) // 独立事务,不受业务回滚影响 + public void save(OperationLogRecord log) { + repository.save(log); + } + + @Async("logExecutor") + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) // 独立事务,不受业务回滚影响 + public void saveAllLogAsync(List logs){ + repository.saveAll(logs); + } + + @Override + public PageVO search(Integer schId, String keyword,Boolean isSystem, Pageable pageable) { + // 构建规格 + Specification spec = Specification + .where(OperationLogSpecifications.schIdEquals(schId)) + .and(OperationLogSpecifications.keywordLike(keyword)); + // 默认排序:按操作时间降序 + if (!pageable.getSort().isSorted()) { + pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), + Sort.by(Sort.Direction.DESC, "operateTime")); + } + + spec = spec.and(OperationLogSpecifications.IsSystem(isSystem)); + + // 执行查询 + Page page = repository.findAll(spec, pageable); + // 转换为 PageVO,注意 PageVO 构造方法可能需要 current, pageSize, total, list + // 假设 PageVO 构造方法为 (int current, int pageSize, long total, List list) + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), page.getTotalElements(), page.getContent()); + } + + public OperationLogRecord buildLogRecord(UserContext.UserInfo ctx, String module, String content,LocalDateTime now) { + OperationLogRecord logRecord = new OperationLogRecord(); + logRecord.setOperator(ctx.getUserName()); + logRecord.setOperatorId(ctx.getUserId()); + logRecord.setIp(ctx.getIp()); + logRecord.setSchId(ctx.getSchId()); + logRecord.setModule(module); + logRecord.setOperateTime(now); + logRecord.setContent(content); + return logRecord; + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseDicGradeService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseDicGradeService.java new file mode 100644 index 0000000..cb9745d --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseDicGradeService.java @@ -0,0 +1,34 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.BaseDicGradeRepository; +import com.bestsch.bschclassmanage.entity.BaseDicGrade; +import com.bestsch.bschclassmanage.service.IBaseDicGradeService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class BaseDicGradeService implements IBaseDicGradeService { + + @Autowired + private BaseDicGradeRepository baseDicGradeRepository; + + @Autowired + private RedisUtil redisUtil; + + public List getSysGradeList() { + + String cacheKey = RedisConstants.SYSTEM_GRAGE; + + if (redisUtil.hasKey(cacheKey)) + return redisUtil.getList(cacheKey,BaseDicGrade.class); + + List list = baseDicGradeRepository.findAll(); + redisUtil.set(cacheKey, list , RedisConstants.CACHE_EXPIRE_30D); + return list; + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseDicSubjectService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseDicSubjectService.java new file mode 100644 index 0000000..79527d7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseDicSubjectService.java @@ -0,0 +1,34 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.BaseDicSubjectRepository; +import com.bestsch.bschclassmanage.entity.BaseDicSubject; +import com.bestsch.bschclassmanage.service.IBaseDicSubjectService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class BaseDicSubjectService implements IBaseDicSubjectService { + + @Autowired + private BaseDicSubjectRepository baseDicSubjectRepository; + + @Autowired + private RedisUtil redisUtil; + + public List getSysSubjectList() { + + String cacheKey = RedisConstants.SYSTEM_SUBJECT; + + if (redisUtil.hasKey(cacheKey)) + return redisUtil.getList(cacheKey,BaseDicSubject.class); + + List list = baseDicSubjectRepository.findAll(); + redisUtil.set(cacheKey, list , RedisConstants.CACHE_EXPIRE_30D); + return list; + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseSchsystemGradeService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseSchsystemGradeService.java new file mode 100644 index 0000000..b9a0453 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseSchsystemGradeService.java @@ -0,0 +1,208 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.BaseSchsystemGradeRepository; +import com.bestsch.bschclassmanage.Repository.SchDicMajorsRepository; +import com.bestsch.bschclassmanage.entity.BaseSchsystemGrade; +import com.bestsch.bschclassmanage.entity.BaseYearTerm; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.IBaseYearTermService; +import com.bestsch.bschclassmanage.service.ISchBinSchsystemService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import com.yunhai.platform.utils.exception.DException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class BaseSchsystemGradeService implements IBaseSchsystemGradeService { + + @Autowired + private BaseSchsystemGradeRepository baseSchsystemGradeRepository; + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private IBaseYearTermService baseYearTermService; + + + @Autowired + private SchDicMajorsRepository schDicMajorsRepository; + + @Autowired + private RedisUtil redisUtil; + + public List getSchGradeCacheList(Integer schId){ + + String cacheKey = RedisConstants.SCHOOL_GRAGE+"_"+schId; + + if (redisUtil.hasKey(cacheKey)) + return redisUtil.getList(cacheKey,BaseSchsystemGrade.class); + + List schsystemIds= schBinSchsystemService.getSchBinSchsystemIds(schId); + + List list=baseSchsystemGradeRepository.findBySchSystemIdIn(schsystemIds); + + redisUtil.set(cacheKey, list , RedisConstants.CACHE_EXPIRE_30D); + return list; + } + + + public List getSchGradeCacheList(Integer schId,Integer schsystemId,Integer gradeId) { + List list = getSchGradeCacheList(schId); + + if (schsystemId != null && schsystemId > 0) + list = list.stream().filter(s -> s.getSchSystemId().equals(schsystemId)).collect(Collectors.toList()); + + if (gradeId != null && gradeId > 0) + list = list.stream().filter(s -> s.getGradeId().equals(gradeId)).collect(Collectors.toList()); + + return list; + } + + + public Map getNowYearGradeMap(Integer schId,Integer schsystemId) { + // 1. 获取当前学年 + BaseYearTerm nowTerm = baseYearTermService.getNowYearTerm(); + + if (nowTerm == null) { + return Collections.emptyMap(); + } + + Integer year = nowTerm.getYear(); + + // 2. 获取学制年级列表并按学制分组 + List allGrades = getSchGradeCacheList(schId,schsystemId,null); + if (allGrades == null || allGrades.isEmpty()) { + return Collections.emptyMap(); + } + + Map> gradeMap = allGrades.stream() + .collect(Collectors.groupingBy(BaseSchsystemGrade::getSchSystemId)); + + // 3. 构建 Map + Map result = new HashMap<>(); + gradeMap.forEach((schSystemId, gradeList) -> { + if (gradeList.isEmpty()) return; + gradeList.sort(Comparator.comparing(BaseSchsystemGrade::getGradeId)); + // 获取最低年级的 gradeId + Integer minGradeId = gradeList.get(0).getGradeId(); + for (BaseSchsystemGrade grade : gradeList) { + // 偏移量 = 当前年级 - 最低年级(低年级偏移0,高年级偏移大) + int offset = grade.getGradeId() - minGradeId; + int startYear = year - offset; + result.put(grade.getGradeId(), startYear); + } + }); + + return result; + } + + + public Map getGradeNameMap(Integer schId, Integer schsystemId, Integer gradeId) { + List gradeList = getGradeSelect(schId,schsystemId,gradeId); + if (gradeList == null || gradeList.isEmpty()) { + return Collections.emptyMap(); + } + return gradeList.stream() + .filter(grade -> grade != null && grade.getId() != null && grade.getName() != null) + .collect(Collectors.toMap( + SelectIntVO::getId, // key: 年级ID + SelectIntVO::getName, // value: 年级别称 + (oldVal, newVal) -> oldVal // 冲突保留旧值 + )); + } + + public List getGradeSelect(Integer schId, Integer schsystemId, Integer gradeId) { + + Integer schType=schBinSchsystemService.getSchType(schId); + if(schType.equals(SchType.BASICEDUCATION.getKey())) + { + // 获取年级映射(schsystemId 和 gradeId 传 null,表示不限定) + List gradeList = getSchGradeCacheList(schId, schsystemId, gradeId); + if (gradeList == null || gradeList.isEmpty()) { + return Collections.emptyList(); + } + // 转换为 SelectIntVO 列表,按 gradeId 排序(可选) + return gradeList.stream() + .map(entry -> new SelectIntVO(entry.getGradeId(), entry.getGradeNickname())) + .sorted(Comparator.comparingInt(SelectIntVO::getId)) + .collect(Collectors.toList()); + }else { + + Integer year = baseYearTermService.getNowYearTerm().getYear(); + + // 获取专业最大学制 + Integer maxSchsystemLeng = schDicMajorsRepository.findMaxSchsystemLengBySchId(schId).orElse(1); + + schBinSchsystemService.selectSchBinSchsystem(schId).stream().findFirst() + .orElseThrow(() -> new RuntimeException("学制未选择!")); + + // 2. 循环生成年级节点(从当前学年往前推) + List gradeMap = new ArrayList<>(); + for (int i = 0; i < maxSchsystemLeng; i++) { + int gradeYear = year - i; // 递减 + SelectIntVO gradeVo=new SelectIntVO(); + gradeVo.setId(gradeYear); + gradeVo.setName(gradeYear+"级"); + gradeMap.add(gradeVo); + } + return gradeMap; + } + + } + + + public List getGradeByMajorsId(Integer schId,Integer majorsId) { + List gradeMap = new ArrayList<>(); + Integer schType=schBinSchsystemService.getSchType(schId); + + if(schType.equals(SchType.VOCATIONALEDUCATION.getKey())) + { + Integer year = baseYearTermService.getNowYearTerm().getYear(); + Integer maxSchsystemLeng = schDicMajorsRepository.findMaxSchsystemLengBySchId(schId).orElse(1); + + schBinSchsystemService.selectSchBinSchsystem(schId).stream().findFirst() + .orElseThrow(() -> new RuntimeException("学制未选择!")); + + for (int i = 0; i < maxSchsystemLeng; i++) { + int gradeYear = year - i; // 递减 + SelectIntVO gradeVo=new SelectIntVO(); + gradeVo.setId(gradeYear); + gradeVo.setName(gradeYear+"级"); + gradeMap.add(gradeVo); + } + + } + return gradeMap; + } + + public Integer getSchsystemIdByGradeId(Integer schId,Integer gradeId){ + if(gradeId==null) throw new DException("年级Id不允许为空!"); + + Optional schsystemGradeOpt= getSchGradeCacheList(schId,null,gradeId).stream().findFirst(); + if(schsystemGradeOpt.isPresent()) + return schsystemGradeOpt.get().getSchSystemId(); + else { + throw new DException("年级Id不正确!"); + } + } + + public Integer getSchGradeIdBySchsystemId(Integer schId,Integer gradeId){ + List schsystemIds= schBinSchsystemService.getSchBinSchsystemIds(schId); + Integer schType= schBinSchsystemService.getSchType(schId); + if(schType.equals(SchType.VOCATIONALEDUCATION.getKey())&&schsystemIds.size()==1) + return schsystemIds.get(0); + else { + BaseSchsystemGrade baseSchsystemGradeFirst= getSchGradeCacheList(schId,null,gradeId) + .stream().findFirst().orElseThrow(() -> new DException("年级学制不存在,ID=" + gradeId)); + + return baseSchsystemGradeFirst.getSchSystemId(); + } + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseSchsystemService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseSchsystemService.java new file mode 100644 index 0000000..f132cd8 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseSchsystemService.java @@ -0,0 +1,47 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.BaseSchsystemGradeRepository; +import com.bestsch.bschclassmanage.Repository.BaseSchsystemRepository; +import com.bestsch.bschclassmanage.entity.BaseSchsystem; +import com.bestsch.bschclassmanage.service.IBaseSchsystemService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class BaseSchsystemService implements IBaseSchsystemService { + + @Autowired + private BaseSchsystemRepository baseSchSystemRepository; + + @Autowired + private BaseSchsystemGradeRepository baseSchsystemGradeRepository; + + @Autowired + private RedisUtil redisUtil; + + //学制列表 + public List getSchsystemList() { + String cacheKey = RedisConstants.SYSTEM_SCHSYSTEM; + + if (redisUtil.hasKey(cacheKey)) + return redisUtil.getList(cacheKey,BaseSchsystem.class); + + //加锁防止缓存击穿 + synchronized (this) { + // 双重检查 + if (redisUtil.hasKey(cacheKey)) + return redisUtil.getList(cacheKey,BaseSchsystem.class); + + // 3. 从数据库查询 + List list = baseSchSystemRepository.findAll(); + // 4. 存入缓存(即使是空列表也缓存,避免穿透) + redisUtil.set(cacheKey, list, RedisConstants.CACHE_EXPIRE_30D); + return list; + } + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseYearTermService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseYearTermService.java new file mode 100644 index 0000000..a0008ac --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/BaseYearTermService.java @@ -0,0 +1,288 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.BaseYearTermRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.BaseYearTerm; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.tool.YearTerm; +import com.bestsch.bschclassmanage.model.vo.BaseYearTermVO; +import com.bestsch.bschclassmanage.service.IBaseYearTermService; +import com.bestsch.bschclassmanage.service.ILogService; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.utils.DateUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class BaseYearTermService implements IBaseYearTermService { + + @Autowired + private BaseYearTermRepository baseYearTermRepository; + + @Autowired + private RedisUtil redisUtil; + + @Autowired + private ILogService logService; + + private static final String MODULE_SYSTEM="系统管理"; + + //学年学期 + private String cacheKey = RedisConstants.SYSTEM_YEARTERM; + + public List getAllYearTerm() { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, BaseYearTerm.class); + } + Sort sort = Sort.by(Sort.Order.desc(EntityFieldNames.year)); + List clist = baseYearTermRepository.findAll(sort); + redisUtil.set(cacheKey, clist, RedisConstants.CACHE_EXPIRE_30D); + return clist; + } + + public List getAllYearTermVO() { + List entities = getAllYearTerm(); + return convertToVOList(entities); + } + + public BaseYearTerm getNowYearTerm() { + Date now = new Date(); + List yearTermList = getAllYearTerm(); + if (yearTermList == null || yearTermList.isEmpty()) { + return null; + } + return yearTermList.stream() + .filter(s -> s.getYearStartDate().compareTo(now) <= 0 && s.getYearEndDate().compareTo(now) >= 0) + .findFirst() + .orElse(null); + } + + + + + @OperationLog(module = MODULE_SYSTEM) + @Transactional(rollbackFor = Exception.class) + public void createNowYearTerm(UserContext.UserInfo user,BaseYearTerm entity){ + if(getAllYearTerm().stream().anyMatch(s->s.getYear().equals(entity.getYear()))) + throw new IllegalArgumentException("创建学年已存在!"); + redisUtil.del(cacheKey); + baseYearTermRepository.save(entity); + { + String content = createNowYearTermLog(entity); + LogContextHolder.setDescription(content); + } + + } + + private String createNowYearTermLog(BaseYearTerm entity) { + try { + // 构建日志内容 + String content = String.format("创建新学年学期: 学年[%d], 学年起止[%s ~ %s], 第一学期[%s ~ %s], 第二学期[%s ~ %s], 升级日期[%s]", + entity.getYear(), + entity.getYearStartDate() != null ? entity.getYearStartDate().toString() : "未设置", + entity.getYearEndDate() != null ? entity.getYearEndDate().toString() : "未设置", + entity.getFirstTermStartDate() != null ? entity.getFirstTermStartDate().toString() : "未设置", + entity.getFirstTermEndDate() != null ? entity.getFirstTermEndDate().toString() : "未设置", + entity.getSecondTermStartDate() != null ? entity.getSecondTermStartDate().toString() : "未设置", + entity.getSecondTermEndDate() != null ? entity.getSecondTermEndDate().toString() : "未设置", + entity.getUpgradeDate() != null ? entity.getUpgradeDate().toString() : "未设置" + ); + return content; + + } catch (Exception e) { + log.error("记录创建学年学期日志失败", e); + return "创建学年学期日志失败"; + } + } + + @OperationLog(module = MODULE_SYSTEM) + @Transactional(rollbackFor = Exception.class) + public void updateYearTerm(UserContext.UserInfo user,BaseYearTerm entity){ + if (entity.getId() == null) { + throw new IllegalArgumentException("更新时ID不能为空"); + } + + BaseYearTerm existing = baseYearTermRepository.findById(entity.getId()) + .orElseThrow(() -> new IllegalArgumentException("学年记录不存在,ID=" + entity.getId())); + + BaseYearTerm oldEntity = new BaseYearTerm(); + BeanUtils.copyProperties(existing, oldEntity); + + // 将传入 entity 中允许更新的字段复制到 existing,忽略 id 及创建审计字段 + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + + redisUtil.del(cacheKey); + baseYearTermRepository.save(entity); + + { + String content = updateYearTermLog(user,oldEntity,entity); + LogContextHolder.setDescription(content); + } + } + + private String updateYearTermLog(UserContext.UserInfo user,BaseYearTerm oldEntity, BaseYearTerm newEntity) { + try { + + List changes = new ArrayList<>(); + if (!oldEntity.getYear().equals(newEntity.getYear())) { + changes.add("年份: " + oldEntity.getYear() + " -> " + newEntity.getYear()); + } + // 比较所有日期字段 + compareDateField(changes, "学年开始", oldEntity.getYearStartDate(), newEntity.getYearStartDate()); + compareDateField(changes, "学年结束", oldEntity.getYearEndDate(), newEntity.getYearEndDate()); + compareDateField(changes, "第一学期开始", oldEntity.getFirstTermStartDate(), newEntity.getFirstTermStartDate()); + compareDateField(changes, "第一学期结束", oldEntity.getFirstTermEndDate(), newEntity.getFirstTermEndDate()); + compareDateField(changes, "第二学期开始", oldEntity.getSecondTermStartDate(), newEntity.getSecondTermStartDate()); + compareDateField(changes, "第二学期结束", oldEntity.getSecondTermEndDate(), newEntity.getSecondTermEndDate()); + compareDateField(changes, "升级日期", oldEntity.getUpgradeDate(), newEntity.getUpgradeDate()); + + String changeStr = changes.isEmpty() ? "无变化" : String.join("; ", changes); + String content = String.format("更新学年学期(ID=%d,年份=%d):%s", + newEntity.getId(), newEntity.getYear(), changeStr); + + return content; + } catch (Exception e) { + log.error("记录更新学年学期日志失败", e); + return "更新学年学期日志失败"; + } + } + private void compareDateField(List changes, String fieldName, Date oldDate, Date newDate) { + // 如果两个日期都为 null,视为无变化 + if (oldDate == null && newDate == null) { + return; + } + // 如果其中一个为 null,或两者不相等,记录变更 + if (oldDate == null || newDate == null || !oldDate.equals(newDate)) { + String oldStr = oldDate != null ? DateUtils.formatDate(oldDate, "yyyy-MM-dd") : "null"; + String newStr = newDate != null ? DateUtils.formatDate(newDate, "yyyy-MM-dd") : "null"; + changes.add(fieldName + ": " + oldStr + " -> " + newStr); + } + } + + public BaseYearTermVO convertToVO(BaseYearTerm entity) { + if (entity == null) return null; + BaseYearTerm nowTerm = getNowYearTerm(); + Integer nowId = nowTerm != null ? nowTerm.getId() : null; + return BaseYearTermVO.of(entity, nowId); + } + + public List convertToVOList(List entities) { + if (entities == null) return null; + BaseYearTerm nowTerm = getNowYearTerm(); + Integer nowId = nowTerm != null ? nowTerm.getId() : null; + return entities.stream() + .map(entity -> BaseYearTermVO.of(entity, nowId)) + .collect(Collectors.toList()); + } + + + public boolean isUpgradeDate(Date date) { + if (date == null) { + return false; + } + // 1. 获取当前学年 + BaseYearTerm currentTerm = getNowYearTerm(); + if (currentTerm == null) { + return false; // 没有当前学年,无法升级 + } + + // 2. 获取当前学年配置的升级日期 + Date upgradeDate = currentTerm.getUpgradeDate(); + if (upgradeDate == null) { + return false; // 当前学年未设置升级日期 + } + + // 3. 比较日期部分(忽略时分秒) + Calendar inputCal = Calendar.getInstance(); + inputCal.setTime(date); + Calendar termCal = Calendar.getInstance(); + termCal.setTime(upgradeDate); + + return inputCal.get(Calendar.YEAR) == termCal.get(Calendar.YEAR) + && inputCal.get(Calendar.MONTH) == termCal.get(Calendar.MONTH) + && inputCal.get(Calendar.DAY_OF_MONTH) == termCal.get(Calendar.DAY_OF_MONTH); + } + + public boolean isBackupClassDataDate(Date date) { + BaseYearTerm nowTerm = getNowYearTerm(); + if (nowTerm == null) { + return false; + } + LocalDate target = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + Date firstEnd = nowTerm.getFirstTermEndDate(); + if (firstEnd != null) { + LocalDate firstEndDate = firstEnd.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + if (target.equals(firstEndDate.plusDays(1))) { + return true; + } + } + Date secondEnd = nowTerm.getSecondTermEndDate(); + if (secondEnd != null) { + LocalDate secondEndDate = secondEnd.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + if (target.equals(secondEndDate.plusDays(1))) { + return true; + } + } + return false; + } + + + @Override + public YearTerm getCurrentYearTerm() { + BaseYearTerm nowTerm = getNowYearTerm(); + if (nowTerm == null) { + throw new IllegalStateException("当前学年未设置,请先配置学年学期"); + } + int year = nowTerm.getYear(); + int term = getCurrentTerm(); // 调用下面定义的 getCurrentTerm 方法 + return new YearTerm(year, term); + } + + // 辅助方法(如果还没实现) + public int getCurrentYear() { + BaseYearTerm nowTerm = getNowYearTerm(); + if (nowTerm == null) { + throw new IllegalStateException("当前学年未设置"); + } + return nowTerm.getYear(); + } + + public int getCurrentTerm() { + BaseYearTerm nowTerm = getNowYearTerm(); + if (nowTerm == null) { + throw new IllegalStateException("当前学年未设置"); + } + Date now = new Date(); + Date firstStart = nowTerm.getFirstTermStartDate(); + Date firstEnd = nowTerm.getFirstTermEndDate(); + if (firstStart != null && firstEnd != null) { + if (!now.before(firstStart) && !now.after(firstEnd)) { + return 1; + } + } + Date secondStart = nowTerm.getSecondTermStartDate(); + Date secondEnd = nowTerm.getSecondTermEndDate(); + if (secondStart != null && secondEnd != null) { + if (!now.before(secondStart) && !now.after(secondEnd)) { + return 2; + } + } + throw new IllegalStateException("当前日期不在任何学期区间内,请检查学年学期配置"); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchBinSchsystemService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchBinSchsystemService.java new file mode 100644 index 0000000..266bf98 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchBinSchsystemService.java @@ -0,0 +1,211 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.SchBinSchsystemRepository; +import com.bestsch.bschclassmanage.entity.BaseSchsystem; +import com.bestsch.bschclassmanage.entity.SchBinSchsystem; +import com.bestsch.bschclassmanage.enums.AcademicStage; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.AcademicStageSchsystemVO; +import com.bestsch.bschclassmanage.model.vo.SchSystemVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.IBaseSchsystemService; +import com.bestsch.bschclassmanage.service.ISchBinSchsystemService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class SchBinSchsystemService implements ISchBinSchsystemService { + + @Autowired + private SchBinSchsystemRepository schBinSchsystemRepository; + + @Autowired + private IBaseSchsystemService baseSchsystemService; + + + @Autowired + private RedisUtil redisUtil; + + public List getSchBinSchsystemList(Integer schId){ + Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + predicates.add(criteriaBuilder.equal(root.get(EntityFieldNames.schId),schId)); + return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); + }; + return schBinSchsystemRepository.findAll(specification); + } + + public List getSchIds(){ + return schBinSchsystemRepository.findAll().stream().map(s->s.getSchId()).distinct().collect(Collectors.toList()); + } + + + public List getSchBinSchsystemIds(Integer schId){ + return getSchBinSchsystemList(schId).stream().map(s->s.getSchSystemId()).collect(Collectors.toList()); + } + + + + /** + * 获取学校关联的学段与学制映射(一个学段仅对应一个学制) + * @param schId 学校ID + * @return Map<学段ID, 学制ID> + */ + public Map getAcademicStageToSchsystemMap(Integer schId) { + List schsystemIds = getSchBinSchsystemIds(schId); + return baseSchsystemService.getSchsystemList().stream() + .filter(s -> schsystemIds.contains(s.getId())) + .collect(Collectors.toMap( + BaseSchsystem::getAcademicStage, // key: 学段ID + BaseSchsystem::getId, // value: 学制ID + (existing, replacement) -> existing // 若有重复,保留第一个(理论上不会发生) + )); + } + + public List getAcademicStageSchsystemList(Integer schId) { + List academicStageEnumList = AcademicStage.list(); + List baseSchSystemList = baseSchsystemService.getSchsystemList(); + Set checkedIdSet = new HashSet<>(getSchBinSchsystemIds(schId)); + + Map> groupByStage = baseSchSystemList.stream() + .filter(s -> s.getAcademicStage() != null) + .collect(Collectors.groupingBy(BaseSchsystem::getAcademicStage)); + + return academicStageEnumList.stream() + .map(stageEnum -> { + List stageSystems = groupByStage.getOrDefault(stageEnum.getKey(), Collections.emptyList()); + List schSystemVOList = stageSystems.stream() + .map(sys -> SchSystemVO.builder() + .id(sys.getId()) + .name(sys.getName()) + .checked(checkedIdSet.contains(sys.getId())) + .build()) + .collect(Collectors.toList()); + + return AcademicStageSchsystemVO.builder() + .academicStageId(stageEnum.getKey()) + .academicStageName(stageEnum.getValue()) + .academicStageList(schSystemVOList) + .build(); + }) + .collect(Collectors.toList()); + } + + @Transactional(rollbackFor = Exception.class) + public void saveSchBinSchsystem(SchBinSchsystem entity, Integer[] schsystemIds) { + + Integer schId=entity.getSchId(); + + List existingList = getSchBinSchsystemList(schId); + if (!existingList.isEmpty()) { + schBinSchsystemRepository.deleteAll(existingList); + } + + List newList = new ArrayList<>(schsystemIds.length); + for (Integer systemId : schsystemIds) { + if (systemId == null) { + continue; + } + SchBinSchsystem newEntity = new SchBinSchsystem(); // ← 每次 new 一个新对象 + // 如果需要复制 entity 的其他属性 + BeanUtils.copyProperties(entity, newEntity); + newEntity.setSchSystemId(systemId); + newList.add(newEntity); + } + + if (!newList.isEmpty()) { + schBinSchsystemRepository.saveAll(newList); + } + String cacheKey = RedisConstants.SCHOOL_GRAGE+"_"+schId; + redisUtil.del(cacheKey); + } + + + //获取学校类型 + public Integer getSchType(Integer schId) { + Set schsystemIds = getSchBinSchsystemList(schId) + .stream() + .map(s -> s.getSchSystemId()) + .collect(Collectors.toSet()); + + Set typeIds = baseSchsystemService.getSchsystemList() + .stream() + .filter(s -> schsystemIds.contains(s.getId())) + .map(s -> s.getType()) + .collect(Collectors.toSet()); + + // 校验:类型必须唯一 + if (typeIds.isEmpty()) { + throw new IllegalArgumentException("该学校未绑定任何学制,请先绑定"); + } + if (typeIds.size() > 1) { + throw new IllegalArgumentException("该学校绑定了多种学制类型(" + typeIds + "),数据异常,请检查"); + } + + // 此时 typeIds 仅有一个元素,直接获取 + Integer typeId = typeIds.iterator().next(); + + if(typeId.equals(SchType.VOCATIONALEDUCATION.getKey())&&schsystemIds.size()>1){ + throw new IllegalArgumentException("该学校只能选择单个学制,请重新选择学制!"); + } + + // 从枚举中匹配该 typeId + return SchType.list().stream() + .filter(s -> s.getKey().equals(typeId)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("未找到对应的学制类型,typeId=" + typeId)) + .getKey(); + } + + + + public List selectSchBinSchsystem(Integer schId) { + // 1. 获取学校绑定的学制 ID 集合 + List binList = getSchBinSchsystemList(schId); + if (binList == null || binList.isEmpty()) { + return Collections.emptyList(); + } + Set schsystemIds = binList.stream() + .map(SchBinSchsystem::getSchSystemId) + .collect(Collectors.toSet()); + + // 2. 获取全部学制并过滤出绑定的 + List allSystems = baseSchsystemService.getSchsystemList(); + if (allSystems == null || allSystems.isEmpty()) { + return Collections.emptyList(); + } + + // 3. 转换为 SchSystemVO 列表,checked 固定为 true + return allSystems.stream() + .filter(s -> schsystemIds.contains(s.getId())) + .map(s -> { + SelectIntVO vo = new SelectIntVO(); + vo.setId(s.getId()); + vo.setName(s.getName()); + return vo; + }) + .collect(Collectors.toList()); + } + + + public Map getSchBinSchsystemMap(Integer schId) { + List list= selectSchBinSchsystem(schId); + return list.stream() + .collect(Collectors.toMap( + SelectIntVO::getId, // key + SelectIntVO::getName, // value + (oldVal, newVal) -> oldVal // 若key冲突,保留旧值(理论上不会冲突) + )); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchClassService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchClassService.java new file mode 100644 index 0000000..37223c5 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchClassService.java @@ -0,0 +1,189 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.vo.*; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.ISchBinSchsystemService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.service.ISchInfoService; +import com.bestsch.bschclassmanage.service.impl.classes.*; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.*; + +@Slf4j +@Service +public class SchClassService implements ISchClassService { + + + + @Autowired + private SchClassQueryService queryService; + + @Autowired + private SchClassInfoService infoService; + + @Autowired + private SchClassHigherService higherService; + + @Autowired + private SchClassImportService importService; + + @Autowired + private SchClassUpgradeService upgradeService; + + // ==================== 查询 ==================== +// @Override +// public List getSchClassList(Integer schId) { +// return queryService.getSchClassCacheList(schId,false); +// } + + @Override + public List getSchGradeateClassCacheList(Integer schId) { + return queryService.getSchGradeateClassCacheList(schId); + } + + @Override + public List getSchAllClassCacheList(Integer schId) { + return queryService.getSchAllClassCacheList(schId); + } + + + + @Override + public List getSchClassCacheList(Integer schId) { + return queryService.getSchClassCacheList(schId); + } + + @Override + public List getSchClassCacheFilter(Integer schId, List gradeIds, Integer classId) { + return queryService.getSchClassCacheFilter(schId, gradeIds, classId); + } + + @Override + public List getSchClassCacheFilter(Integer schId, Integer gradeId, Integer classId) { + return queryService.getSchClassCacheFilter(schId, gradeId, classId); + } + + @Override + public List getSchAllClassCacheFilter(Integer schId, List gradeIds, Integer classId) { + return queryService.getSchAllClassCacheFilter(schId, gradeIds, classId); + } + + @Override + public List getSchAllClassCacheFilter(Integer schId, Integer gradeId, Integer classId) { + return queryService.getSchAllClassCacheFilter(schId, gradeId, classId); + } + + + @Override + public List searcBaseSchClass(Integer schId, Integer schsystemId, Integer gradeId, Integer classId) { + return queryService.searcBaseSchClass(schId, schsystemId, gradeId, classId); + } + + @Override + public PageVO searcHigherSchClass(Integer schId, Integer year, Integer campusId, + Integer divisionId, Integer majorsId, Pageable pageable) { + return queryService.searcHigherSchClass(schId, year, campusId, divisionId, majorsId, pageable); + } + + @Override + public List getClassSelect(Integer schId, Integer gradeId) { + return queryService.getClassSelect(schId, gradeId); + } + + // ==================== K12 写操作 ==================== + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void addBaseSchClass(UserContext.UserInfo user, Integer gradeId, Integer number) { + infoService.addBaseSchClass(user, gradeId, number); + } + + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void editClassName(UserContext.UserInfo user, Integer id, String cname) { + infoService.editClassName(user, id, cname); + } + + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void editClassFirstTeacher(UserContext.UserInfo user, Integer id, Integer firstTeacherId) { + infoService.editClassFirstTeacher(user, id, firstTeacherId); + } + + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void editClassSecondTeacher(UserContext.UserInfo user, Integer id, Integer secondTeacherId) { + infoService.editClassSecondTeacher(user, id, secondTeacherId); + } + + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void editClassCampus(UserContext.UserInfo user, Integer id, Integer campusId) { + infoService.editClassCampus(user, id, campusId); + } + + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void deleteSchClass(UserContext.UserInfo user, Integer id, Integer schId) { + infoService.deleteSchClass(user, id, schId); + } + + // ==================== 职业教育写操作 ==================== + @OperationLog(module = LogModule.CLASS) + @Transactional(rollbackFor = Exception.class) + @Override + public void saveHigherSchClass(UserContext.UserInfo user, SchClass entity) { + higherService.saveHigherSchClass(user, entity); + } + + // ==================== 导入 ==================== + + + @Transactional(rollbackFor = Exception.class) + @Override + public void importClasses(UserContext.UserInfo user, MultipartFile file) { + importService.importClasses(user, file); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void importHeightClasses(UserContext.UserInfo user, MultipartFile file) { + importService.importHeightClasses(user, file); + } + + @Override + public Integer getMinEnrollYearBySchsystem(Integer schId, Integer schsystemId) { + return queryService.getMinEnrollYearBySchsystem(schId,schsystemId); + } + + @Override + public void upgradeAllClasses() { + upgradeService.upgradeAllClasses(); + } + + @Override + public void backupAllSnapshot() { + upgradeService.backupAllSnapshot(); + } + + + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchClassTeachService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchClassTeachService.java new file mode 100644 index 0000000..3a37e96 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchClassTeachService.java @@ -0,0 +1,104 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.vo.SchTeachMapIdVO; +import com.bestsch.bschclassmanage.model.vo.SchTeachMapVO; +import com.bestsch.bschclassmanage.service.ISchClassTeachService; +import com.bestsch.bschclassmanage.service.impl.teachs.*; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +/** + * 任教服务门面(对外接口实现) + * 职责:实现 ISchClassTeachService,委托给各子服务 + * + *

事务管理:统一在门面层管理,保证数据一致性 + *

日志记录:使用 @OperationLog 注解,由切面统一处理 + */ +@Slf4j +@Service +public class SchClassTeachService implements ISchClassTeachService { + + // ==================== 子服务 ==================== + + @Autowired + private SchClassTeachQueryService queryService; + + @Autowired + private SchClassTeachInfoService infoService; + + @Autowired + private SchClassTeachImportService importService; + + // ==================== 查询方法(委托给 QueryService) ==================== + +// public List getSchClassTeachList(Integer schId, Integer gradeId, Integer classId) { +// return queryService.getSchClassTeachList(schId, gradeId, classId); +// } +// +// public List getSchGradeTeachList(Integer schId, List gradeIds) { +// return queryService.getSchGradeTeachList(schId, gradeIds); +// } + + @Override + public List getSchClassTeachCacheList(Integer schId, Integer gradeId, Integer classId) { + return queryService.getSchClassTeachCacheList(schId, gradeId, classId); + } + + @Override + public SchTeachMapVO getSchTeachMapVO(Integer schId, Integer schsystemId, Integer gradeId) { + return queryService.getSchTeachMapVO(schId, schsystemId, gradeId); + } + + + @Override + public List getSchClassTeachMapVO(Integer schId, Integer gradeId, Integer classId) { + return queryService.getSchClassTeachMapVO(schId, gradeId,classId); + } + + // ==================== 写操作(事务 + 日志,委托给 InfoService) ==================== + + @OperationLog(module = LogModule.TEACHER) + @Transactional(rollbackFor = Exception.class) + @Override + public void saveTeach(UserContext.UserInfo user, SchClassTeach entity) { + infoService.saveTeach(user, entity); + } + + @OperationLog(module = LogModule.TEACHER) + @Transactional(rollbackFor = Exception.class) + @Override + public void delTeachById(UserContext.UserInfo user, Integer id) { + infoService.delTeachById(user, id); + } + + @OperationLog(module = LogModule.TEACHER) + @Transactional(rollbackFor = Exception.class) + @Override + public void delClassTeach(UserContext.UserInfo user, Integer classId) { + infoService.delClassTeach(user, classId); + } + + @OperationLog(module = LogModule.TEACHER) + @Transactional(rollbackFor = Exception.class) + @Override + public void delBatch(UserContext.UserInfo user, Integer schsystemId, Integer gradeId) { + infoService.delBatch(user, schsystemId, gradeId); + } + + // ==================== 导入(委托给 ImportService) ==================== + + @Transactional(rollbackFor = Exception.class) + @Override + public void importTeach(UserContext.UserInfo user, MultipartFile file, Integer schsystemId, Integer gradeId) { + importService.importTeach(user, file, schsystemId, gradeId); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchCustomGroupService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchCustomGroupService.java new file mode 100644 index 0000000..0b7ab0c --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchCustomGroupService.java @@ -0,0 +1,828 @@ +package com.bestsch.bschclassmanage.service.impl; + +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import com.bestsch.bschclassmanage.Repository.*; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.*; +import com.bestsch.bschclassmanage.enums.CustomGroupType; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.dto.AddMemberDTO; +import com.bestsch.bschclassmanage.model.dto.SchCustomGroupDTO; +import com.bestsch.bschclassmanage.model.dto.SetLeaderDTO; +import com.bestsch.bschclassmanage.model.excel.CustomGroupExcelColumn; +import com.bestsch.bschclassmanage.model.excel.ErrorExcelColumn; +import com.bestsch.bschclassmanage.model.vo.SchCustomGroupVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.ISchCustomGroupService; +import com.bestsch.bschclassmanage.service.ISchDicSubjectService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.utils.*; +import com.yunhai.platform.utils.exception.DException; +import com.yunhai.platform.utils.exception.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; +@Slf4j +@Service +public class SchCustomGroupService implements ISchCustomGroupService { + + @Autowired + private SchTeacherCustomGroupRepository teacherCustomGroupRepository; + @Autowired + private SchTeacherCustomGroupInGradeRepository groupInGradeRepository; + @Autowired + private SchTeacherCustomGroupInSubjectRepository groupInSubjectRepository; + @Autowired + private SchTeacherCustomGroupInTeacherRepository groupInTeacherRepository; + + @Autowired + private ISchTeacherService schTeacherService; + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + @Autowired + private ISchDicSubjectService schDicSubjectService; + + @Autowired + private RedisUtil redisUtil; + + /** + * 获取学校的自定义组列表(年级组/教研组/备课组),包含年级、学科、组长、组员信息 + * + * @param schId 学校ID + * @param type 组类型:1-年级组,2-教研组,3-备课组 + * @return 组VO列表 + */ + @Override + public List getSchCustomGroup(Integer schId, Integer type) { + if (schId == null || type == null) { + return Collections.emptyList(); + } + + List groups = teacherCustomGroupRepository.findBySchIdAndGroupType(schId, type) + .stream() + .sorted(Comparator.comparing(SchTeacherCustomGroup::getSort, + Comparator.nullsLast(Comparator.naturalOrder()))) + .collect(Collectors.toList()); + if (groups.isEmpty()) { + return Collections.emptyList(); + } + + List groupIds = groups.stream().map(SchTeacherCustomGroup::getId).collect(Collectors.toList()); + + // 2. 批量查询关联数据 + List gradeRelations = groupInGradeRepository.findByCgGroupIdIn(groupIds); + Map> groupIdToGradeIds = gradeRelations.stream() + .collect(Collectors.groupingBy(SchTeacherCustomGroupInGrade::getCgGroupId, + Collectors.mapping(SchTeacherCustomGroupInGrade::getGradeId, Collectors.toList()))); + + List subjectRelations = groupInSubjectRepository.findByCgGroupIdIn(groupIds); + Map> groupIdToSubIds = subjectRelations.stream() + .collect(Collectors.groupingBy(SchTeacherCustomGroupInSubject::getCgGroupId, + Collectors.mapping(SchTeacherCustomGroupInSubject::getSubId, Collectors.toList()))); + + List teacherRelations = groupInTeacherRepository.findByCgGroupIdIn(groupIds); + Map> groupIdToLeaderIds = teacherRelations.stream() + .filter(r -> r.getGroupType() != null && r.getGroupType() == 1) + .collect(Collectors.groupingBy(SchTeacherCustomGroupInTeacher::getCgGroupId, + Collectors.mapping(SchTeacherCustomGroupInTeacher::getTeaId, Collectors.toList()))); + Map> groupIdToMemberIds = teacherRelations.stream() + .filter(r -> r.getGroupType() != null && r.getGroupType() == 2) + .collect(Collectors.groupingBy(SchTeacherCustomGroupInTeacher::getCgGroupId, + Collectors.mapping(SchTeacherCustomGroupInTeacher::getTeaId, Collectors.toList()))); + + Set allTeacherIds = new HashSet<>(); + groupIdToLeaderIds.values().forEach(allTeacherIds::addAll); + groupIdToMemberIds.values().forEach(allTeacherIds::addAll); + groups.forEach(g -> { if (g.getLeaderId() != null) allTeacherIds.add(g.getLeaderId()); }); + + // 教师名称映射 - 保证 effectively final + List allTeachers = schTeacherService.getSchTeacherCacheList(schId); + Map teacherNameMap = Optional.ofNullable( + allTeachers.stream() + .filter(t -> allTeacherIds.contains(t.getTeaId())) + .collect(Collectors.toMap(SchTeacher::getTeaId, SchTeacher::getName, (a, b) -> a)) + ).orElse(Collections.emptyMap()); + +// // 年级名称 - effectively final +// Map gradeNameMap = Optional.ofNullable( +// baseSchsystemGradeService.getGradeNameMap(schId, null, null) +// ).orElse(Collections.emptyMap()); + +// // 学科名称 - effectively final +// Map subjectNameMap = Optional.ofNullable( +// schDicSubjectService.toIdAndNameMap(schId, null) +// ).orElse(Collections.emptyMap()); +// Map subIdToName = Optional.ofNullable( +// subjectNameMap.entrySet().stream() +// .collect(Collectors.toMap( +// e -> { +// try { +// return Integer.parseInt(e.getKey()); +// } catch (NumberFormatException ex) { +// return -1; +// } +// }, +// Map.Entry::getValue, +// (a, b) -> a +// )) +// ).orElse(Collections.emptyMap()); + + // 组装VO + List result = new ArrayList<>(groups.size()); + for (SchTeacherCustomGroup group : groups) { + Integer groupId = group.getId(); + +// List gradeVOList = convertToSelectIntVO( +// groupIdToGradeIds.getOrDefault(groupId, Collections.emptyList()), +// gradeNameMap, "未知年级" +// ); +// +// List subjectVOList = convertToSelectStrVO( +// groupIdToSubIds.getOrDefault(groupId, Collections.emptyList()), +// subIdToName, "未知学科" +// ); + + Integer leaderId = groupIdToLeaderIds.getOrDefault(groupId, Collections.emptyList()) + .stream().findFirst().orElse(group.getLeaderId()); + SelectIntVO leaderVO = null; + if (leaderId != null) { + String leaderName = teacherNameMap.getOrDefault(leaderId, "未知教师"); + leaderVO = new SelectIntVO(leaderId, leaderName); + } + + List memberIds = new ArrayList<>(groupIdToMemberIds.getOrDefault(groupId, Collections.emptyList())); + if (leaderId != null) { + memberIds.remove(leaderId); + } + memberIds = memberIds.stream().distinct().collect(Collectors.toList()); + List memberVOList = memberIds.stream() + .map(tid -> new SelectIntVO(tid, teacherNameMap.getOrDefault(tid, "未知教师"))) + .collect(Collectors.toList()); + + SchCustomGroupVO vo = SchCustomGroupVO.builder() + .cgId(groupId) + .cgName(group.getGroupName()) + .gradeIds(groupIdToGradeIds.get(groupId)) + .subjectIds(groupIdToSubIds.get(groupId)) + .cgLeader(leaderVO != null ? Collections.singletonList(leaderVO) : Collections.emptyList()) + .cgMember(memberVOList) + .build(); + result.add(vo); + } + return result; + } + + // ========== 辅助方法 ========== + + /** + * 将年级ID列表转换为 SelectIntVO 列表 + */ + private List convertToSelectIntVO(List ids, Map nameMap, String defaultName) { + if (ids == null || ids.isEmpty()) { + return Collections.emptyList(); + } + return ids.stream() + .map(id -> new SelectIntVO(id, nameMap.getOrDefault(id, defaultName))) + .collect(Collectors.toList()); + } + + /** + * 将学科ID列表转换为 SelectStrVO 列表 + */ + private List convertToSelectStrVO(List ids, Map nameMap, String defaultName) { + if (ids == null || ids.isEmpty()) { + return Collections.emptyList(); + } + return ids.stream() + .map(id -> new SelectStrVO(String.valueOf(id), nameMap.getOrDefault(id, defaultName))) + .collect(Collectors.toList()); + } + + + //添加(变价)组 关联年级 关联学科 + // ========== 保存/更新组(含年级、学科关联) ========== + + @OperationLog(module = LogModule.CUSTOMGROUP) // 可调整为 LogModule.GROUP + @Transactional(rollbackFor = Exception.class) + public void saveSchCustomGroup(UserContext.UserInfo user, SchCustomGroupDTO dto) { + Integer schId = user.getSchId(); + boolean isNew = dto.getId() == null || dto.getId() == 0; + + // 1. 参数校验 + if (dto.getGroupName() == null || dto.getGroupName().trim().isEmpty()) { + throw new IllegalArgumentException("组名不能为空"); + } + if (dto.getGroupType() == null) { + throw new IllegalArgumentException("组类型不能为空"); + } + + // 2. 重名校验(同学校同类型下组名唯一) + boolean nameExists; + SchTeacherCustomGroup oldEntity = null; + + if (isNew) { + nameExists = teacherCustomGroupRepository.existsBySchIdAndGroupTypeAndGroupName( + schId, dto.getGroupType(), dto.getGroupName()); + if (nameExists) { + throw new IllegalArgumentException("组名已存在:" + dto.getGroupName()); + } + } else { + // 更新:排除自身,检查其他组同名 + nameExists = teacherCustomGroupRepository.existsBySchIdAndGroupTypeAndGroupNameAndIdNot( + schId, dto.getGroupType(), dto.getGroupName(), dto.getId()); + if (nameExists) { + throw new IllegalArgumentException("组名已存在:" + dto.getGroupName()); + } + // 查询旧实体,用于日志对比 + oldEntity = teacherCustomGroupRepository.findById(dto.getId()) + .orElseThrow(() -> new IllegalArgumentException("组不存在,ID=" + dto.getId())); + } + + // 3. 构建新实体并设置基础字段 + SchTeacherCustomGroup entity; + if (isNew) { + entity = new SchTeacherCustomGroup(); + entity.setSchId(schId); + entity.setGroupName(dto.getGroupName()); + entity.setGroupType(dto.getGroupType()); + entity.setSort(dto.getSort() != null ? dto.getSort() : 0); + OtherUtil.setBaseEntityValue(user, entity); // 设置创建时间、创建人 + } else { + entity = oldEntity; + // 更新允许修改的字段 + entity.setGroupName(dto.getGroupName()); + entity.setGroupType(dto.getGroupType()); + entity.setSort(dto.getSort() != null ? dto.getSort() : entity.getSort()); + OtherUtil.setBaseEntityValue(user, entity); // 更新修改时间、修改人 + } + + // 4. 保存组基本信息 + SchTeacherCustomGroup saved = teacherCustomGroupRepository.save(entity); + Integer groupId = saved.getId(); + + // 5. 处理年级关联(全量替换) + if (dto.getGradeIds() != null) { + updateGradeRelations(groupId, dto.getGradeIds()); + } + + // 6. 处理学科关联(全量替换) + if (dto.getSubjectIds() != null) { + updateSubjectRelations(groupId, dto.getSubjectIds()); + } + + // 7. 清除缓存(如果有) + String cacheKey = RedisConstants.SCHOOL_CUSTOM_GROUP + "_" + schId; + redisUtil.del(cacheKey); + + // 8. 构建日志描述 + String description = buildCustomGroupLogDescription(saved, isNew, oldEntity); + LogContextHolder.setDescription(description); + } + + @Transactional + public void updateGradeRelations(Integer groupId, List gradeIds) { + groupInGradeRepository.deleteByCgGroupId(groupId); + if (gradeIds != null && !gradeIds.isEmpty()) { + List list = gradeIds.stream() + .map(gid -> { + SchTeacherCustomGroupInGrade rel = new SchTeacherCustomGroupInGrade(); + rel.setCgGroupId(groupId); + rel.setGradeId(gid); + return rel; + }) + .collect(Collectors.toList()); + groupInGradeRepository.saveAll(list); + } + } + + @Transactional + public void updateSubjectRelations(Integer groupId, List subjectIds) { + groupInSubjectRepository.deleteByCgGroupId(groupId); + if (subjectIds != null && !subjectIds.isEmpty()) { + List list = subjectIds.stream() + .map(sid -> { + SchTeacherCustomGroupInSubject rel = new SchTeacherCustomGroupInSubject(); + rel.setCgGroupId(groupId); + rel.setSubId(sid); + return rel; + }) + .collect(Collectors.toList()); + groupInSubjectRepository.saveAll(list); + } + } + + private String buildCustomGroupLogDescription(SchTeacherCustomGroup newGroup, boolean isNew, SchTeacherCustomGroup oldGroup) { + StringBuilder sb = new StringBuilder(); + if (isNew) { + sb.append("新增自定义组:").append(newGroup.getGroupName()); + sb.append(",类型:").append(newGroup.getGroupType()); + sb.append(",排序:").append(newGroup.getSort()); + } else { + sb.append("修改自定义组:").append(newGroup.getGroupName()); + // 可记录变更详情(如有需要) + if (!oldGroup.getGroupName().equals(newGroup.getGroupName())) { + sb.append(",组名从【").append(oldGroup.getGroupName()).append("】改为【").append(newGroup.getGroupName()).append("】"); + } + if (!oldGroup.getGroupType().equals(newGroup.getGroupType())) { + sb.append(",类型从【").append(oldGroup.getGroupType()).append("】改为【").append(newGroup.getGroupType()).append("】"); + } + } + return sb.toString(); + } + + //添加(保存)组员 + + // ========== 添加组员 ========== + + // ========== 全量保存组员(替换原有组员,自动排除组长) ========== + + /** + * 全量保存组员(groupType=2) + * - 先删除该组所有组员(groupType=2) + * - 再批量插入传入的组员(自动过滤掉组长) + * - 若 teaIds 为空,则清空组员 + * + * @param user 当前操作用户(用于日志) + * @param dto 请求参数,包含组ID和全量组员ID列表 + */ + @OperationLog(module = LogModule.CAMPUS) + @Transactional(rollbackFor = Exception.class) + public void saveMembers(UserContext.UserInfo user, AddMemberDTO dto) { + Integer groupId = dto.getGroupId(); + List teaIds = dto.getTeaIds(); + + // 1. 参数校验 + if (groupId == null || groupId <= 0) { + throw new IllegalArgumentException("组ID无效"); + } + if (teaIds == null) { + // 如果传 null,视为不修改;传空列表表示清空 + return; + } + + // 2. 检查组是否存在 + SchTeacherCustomGroup group = teacherCustomGroupRepository.findById(groupId) + .orElseThrow(() -> new IllegalArgumentException("组不存在,ID=" + groupId)); + + // 3. 查询当前组长ID(如果有),用于从组员列表中排除 + Integer leaderId = groupInTeacherRepository.findByCgGroupIdAndGroupType(groupId, 1) + .stream().findFirst().map(SchTeacherCustomGroupInTeacher::getTeaId).orElse(null); + + // 4. 过滤传入的组员:去掉 null、去掉组长(如果组长在列表中) + List finalMemberIds = teaIds.stream() + .filter(Objects::nonNull) + .filter(tid -> !tid.equals(leaderId)) + .distinct() + .collect(Collectors.toList()); + + // 5. 全量替换:先删除所有组员(groupType=2),再插入新组员 + groupInTeacherRepository.deleteByCgGroupIdAndGroupType(groupId, 2); + + if (!finalMemberIds.isEmpty()) { + List newRelations = finalMemberIds.stream() + .map(tid -> { + SchTeacherCustomGroupInTeacher rel = new SchTeacherCustomGroupInTeacher(); + rel.setCgGroupId(groupId); + rel.setGroupType(2); + rel.setTeaId(tid); + return rel; + }) + .collect(Collectors.toList()); + groupInTeacherRepository.saveAll(newRelations); + } + + // 6. 清除缓存 + String cacheKey = RedisConstants.SCHOOL_CUSTOM_GROUP + "_" + group.getSchId(); + redisUtil.del(cacheKey); + + // 7. 构建日志描述 + String description = String.format("保存组【%s】(ID=%d)的组员,共 %d 人,教师ID:%s", + group.getGroupName(), groupId, finalMemberIds.size(), finalMemberIds); + LogContextHolder.setDescription(description); + } + + //设置组长 +// ========== 设置多个组长(覆盖式,从组员中选取) ========== + + /** + * 设置组的多个组长 + * - 将当前所有组长(groupType=1)降级为组员(groupType=2) + * - 将传入的教师ID列表设为组长(groupType=1) + * - 传入的教师必须是该组的现有成员(否则会抛出异常) + * - 传入空列表则清空组长 + * + * @param user 当前操作用户 + * @param dto 请求参数 + */ + @OperationLog(module = LogModule.CAMPUS) + @Transactional(rollbackFor = Exception.class) + public void setLeaders(UserContext.UserInfo user, SetLeaderDTO dto) { + Integer groupId = dto.getGroupId(); + List newLeaderIds = dto.getLeaderIds() != null ? dto.getLeaderIds() : Collections.emptyList(); + + // 1. 参数校验 + if (groupId == null || groupId <= 0) { + throw new IllegalArgumentException("组ID无效"); + } + + // 2. 检查组是否存在 + SchTeacherCustomGroup group = teacherCustomGroupRepository.findById(groupId) + .orElseThrow(() -> new IllegalArgumentException("组不存在,ID=" + groupId)); + + // 3. 获取该组所有成员(全部记录) + List allMembers = groupInTeacherRepository.findByCgGroupId(groupId); + if (allMembers.isEmpty()) { + // 如果组没有成员,但设置了组长,可以先添加成员,但这里要求必须从组员中选,所以先提示无成员 + // 根据业务,可以先添加组员再设组长,这里抛出异常 + throw new IllegalArgumentException("该组暂无成员,无法设置组长"); + } + + // 4. 将传入的ID去重 + List uniqueLeaderIds = newLeaderIds.stream() + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + + // 5. 校验传入的ID是否都在组成员中 + Set existTeaIds = allMembers.stream() + .map(SchTeacherCustomGroupInTeacher::getTeaId) + .collect(Collectors.toSet()); + List invalidIds = uniqueLeaderIds.stream() + .filter(tid -> !existTeaIds.contains(tid)) + .collect(Collectors.toList()); + if (!invalidIds.isEmpty()) { + throw new IllegalArgumentException("以下教师不是该组成员,无法设为组长:" + invalidIds); + } + + // 6. 将当前所有组长降级为组员(groupType改为2) + for (SchTeacherCustomGroupInTeacher member : allMembers) { + if (member.getGroupType() == 1) { + member.setGroupType(2); + } + } + + // 7. 将新的组长ID对应的记录升级为组长(groupType=1) + for (SchTeacherCustomGroupInTeacher member : allMembers) { + if (uniqueLeaderIds.contains(member.getTeaId())) { + member.setGroupType(1); + } + } + + // 8. 批量保存(使用 saveAll) + groupInTeacherRepository.saveAll(allMembers); + + // 9. 清除缓存 + String cacheKey = RedisConstants.SCHOOL_CUSTOM_GROUP + "_" + group.getSchId(); + redisUtil.del(cacheKey); + + // 10. 构建日志描述 + String description = String.format("设置组【%s】(ID=%d)的组长为:%s", + group.getGroupName(), groupId, uniqueLeaderIds.isEmpty() ? "无" : uniqueLeaderIds.toString()); + LogContextHolder.setDescription(description); + } + //删除组 + // ========== 删除组(级联删除所有关联) ========== + /** + * 删除自定义组及其所有关联数据 + * - 删除组基本信息 + * - 删除组-年级关联 + * - 删除组-学科关联 + * - 删除组-教师关联(包括组长和组员) + * + * @param user 当前操作用户(用于日志) + * @param groupId 组ID + */ + @OperationLog(module = LogModule.CAMPUS) + @Transactional(rollbackFor = Exception.class) + public void deleteSchCustomGroup(UserContext.UserInfo user, Integer groupId) { + // 1. 参数校验 + if (groupId == null || groupId <= 0) { + throw new IllegalArgumentException("组ID无效"); + } + + // 2. 查询组是否存在,并获取组基本信息(用于日志和缓存) + SchTeacherCustomGroup group = teacherCustomGroupRepository.findById(groupId) + .orElseThrow(() -> new IllegalArgumentException("组不存在,ID=" + groupId)); + + // 3. 级联删除关联数据 + // 3.1 删除年级关联 + groupInGradeRepository.deleteByCgGroupId(groupId); + + // 3.2 删除学科关联 + groupInSubjectRepository.deleteByCgGroupId(groupId); + + // 3.3 删除教师关联(包括组长和组员) + groupInTeacherRepository.deleteByCgGroupId(groupId); + + // 3.4 删除组基本信息 + teacherCustomGroupRepository.deleteById(groupId); + + // 4. 清除缓存 + String cacheKey = RedisConstants.SCHOOL_CUSTOM_GROUP + "_" + group.getSchId(); + redisUtil.del(cacheKey); + + // 5. 构建日志描述 + String description = String.format("删除自定义组:%s(ID=%d),类型:%d", + group.getGroupName(), groupId, group.getGroupType()); + LogContextHolder.setDescription(description); + } + + @OperationLog(module = LogModule.CUSTOMGROUP) + @Transactional(rollbackFor = Exception.class) + public void importCustomGroup(UserContext.UserInfo user, MultipartFile file) { + List errorMsgArr = new ArrayList<>(); + ImportParams params = new ImportParams(); + params.setTitleRows(1); + params.setHeadRows(1); + Date now = new Date(); + + try (InputStream is = file.getInputStream()) { + // ---------- 1. 提前加载基础数据并构建映射 ---------- + List schTeacherList = schTeacherService.getSchTeacherList(user.getSchId()); + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), null, null); + Map subjectMap = schDicSubjectService.toIdAndNameMap(user.getSchId(), null); + List existingGroupList = teacherCustomGroupRepository.findBySchId(user.getSchId()); + + // 教师姓名 -> ID + Map teacherNameToId = schTeacherList.stream() + .collect(Collectors.toMap( + t -> t.getName().trim(), + SchTeacher::getId, + (a, b) -> a + )); + + // 年级名称 -> ID + Map gradeNameToId = gradeList.stream() + .collect(Collectors.toMap( + vo -> vo.getName().trim(), + SelectIntVO::getId, + (a, b) -> a + )); + + // 学科名称 -> ID(subjectMap 是 ID->Name,需反转) + Map subjectNameToId = subjectMap.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getValue, + Map.Entry::getKey, + (a, b) -> a + )); + + // ---------- 2. 解析 Excel ---------- + List list; + try { + list = ExcelImportUtil.importExcel(is, CustomGroupExcelColumn.class, params); + } catch (Exception e) { + log.error("Excel解析失败", e); + throw new DException("Excel 数据格式有误,请检查所有单元格类型是否正确。错误详情:" + e.getMessage()); + } + if (list == null || list.isEmpty()) { + throw new DException("上传的 Excel 中没有有效数据行,请检查后重新上传!"); + } + + List dtoList = new ArrayList<>(); + int currentRow = params.getTitleRows() + params.getHeadRows(); // 初始为表头行号 + + for (CustomGroupExcelColumn item : list) { + int row = ++currentRow; // 当前数据行号 + + // ---------- 3. 基础校验 ---------- + List validateMsgs = ValidationUtil.validateMsgs(item); + if (!validateMsgs.isEmpty()) { + errorMsgArr.add(new ErrorExcelColumn(row, "导入规则", String.join("\r\n", validateMsgs))); + continue; + } + + // ---------- 4. 组类型 ---------- + Integer groupTypeId = CustomGroupType.getIdByName(item.getGroupType()); + if (groupTypeId == null) { + errorMsgArr.add(new ErrorExcelColumn(row, item.getGroupType(), "组类型选项不存在")); + continue; + } + + // ---------- 5. 构建 DTO ---------- + SchCustomGroupDTO dto = new SchCustomGroupDTO(); + dto.setGroupType(groupTypeId); + dto.setGroupName(item.getGroupName()); // 必须要有 getGroupName() + + // --- 年级 --- + if (StringUtils.isNotBlank(item.getGradeBin())) { + List gradeNames = Arrays.asList(item.getGradeBin().split(",")); + List notFound = gradeNames.stream() + .map(String::trim) + .filter(name -> !gradeNameToId.containsKey(name)) + .collect(Collectors.toList()); + if (!notFound.isEmpty()) { + errorMsgArr.add(new ErrorExcelColumn(row, String.join(",", notFound), "年级不存在")); + continue; + } + dto.setGradeIds(gradeNames.stream() + .map(String::trim) + .map(gradeNameToId::get) + .distinct() + .collect(Collectors.toList())); + } + + // --- 学科 --- + if (StringUtils.isNotBlank(item.getSubjectBin())) { + List subjectNames = Arrays.asList(item.getSubjectBin().split(",")); + List notFound = subjectNames.stream() + .map(String::trim) + .filter(name -> !subjectNameToId.containsKey(name)) + .collect(Collectors.toList()); + if (!notFound.isEmpty()) { + errorMsgArr.add(new ErrorExcelColumn(row, String.join(",", notFound), "学科不存在")); + continue; + } + dto.setSubjectIds(subjectNames.stream() + .map(String::trim) + .map(subjectNameToId::get) + .distinct() + .collect(Collectors.toList())); + } + + // --- 组员 --- + if (StringUtils.isNotBlank(item.getMemberName())) { + List memberNames = Arrays.asList(item.getMemberName().split(",")); + List notFound = memberNames.stream() + .map(String::trim) + .filter(name -> !teacherNameToId.containsKey(name)) + .collect(Collectors.toList()); + if (!notFound.isEmpty()) { + errorMsgArr.add(new ErrorExcelColumn(row, String.join(",", notFound), "组员教师不存在")); + continue; + } + dto.setMemberIds(memberNames.stream() + .map(String::trim) + .map(teacherNameToId::get) + .distinct() + .collect(Collectors.toList())); + } + + // --- 组长 --- + if (StringUtils.isNotBlank(item.getLeaderName())) { + List leaderNames = Arrays.asList(item.getLeaderName().split(",")); + List notFound = leaderNames.stream() + .map(String::trim) + .filter(name -> !teacherNameToId.containsKey(name)) + .collect(Collectors.toList()); + if (!notFound.isEmpty()) { + errorMsgArr.add(new ErrorExcelColumn(row, String.join(",", notFound), "组长教师不存在")); + continue; + } + dto.setLeaderIds(leaderNames.stream() + .map(String::trim) + .map(teacherNameToId::get) + .distinct() + .collect(Collectors.toList())); + } + + dtoList.add(dto); + } + + // ---------- 6. 如果有错误,抛出 ---------- + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + // ---------- 7. 保存主表 ---------- + List saveList = new ArrayList<>(); + for (SchCustomGroupDTO dto : dtoList) { + // 查找是否已存在(按学校、组名、组类型) + Optional existOpt = existingGroupList.stream() + .filter(g -> g.getGroupName().equals(dto.getGroupName()) && g.getGroupType().equals(dto.getGroupType())) + .findFirst(); + + SchTeacherCustomGroup entity; + if (existOpt.isPresent()) { + entity = existOpt.get(); + // 更新基本信息(如果需要,可保留其他字段) + entity.setGroupName(dto.getGroupName()); + entity.setGroupType(dto.getGroupType()); + // 如果实体有 sort 字段,可设置 entity.setSort(...) + entity.setUpdateDate(now); + entity.setUpdateUserId(user.getUserId()); + } else { + entity = new SchTeacherCustomGroup(); + entity.setSchId(user.getSchId()); + entity.setGroupName(dto.getGroupName()); + entity.setGroupType(dto.getGroupType()); + entity.setSort(0); // 或 dto.getSort() + entity.setCreateDate(now); + entity.setCreateUserId(user.getUserId()); + entity.setUpdateDate(now); + entity.setUpdateUserId(user.getUserId()); + } + saveList.add(entity); + } + + // 批量保存主表,获取带 ID 的实体列表 + saveList = teacherCustomGroupRepository.saveAll(saveList); + + // ---------- 8. 保存关联关系(年级、学科、组长、组员) ---------- + // 将 dtoList 与 saveList 关联(按顺序对应) + for (int i = 0; i < saveList.size(); i++) { + SchTeacherCustomGroup group = saveList.get(i); + SchCustomGroupDTO dto = dtoList.get(i); + Integer groupId = group.getId(); + + // 8.1 年级关联 + if (dto.getGradeIds() != null && !dto.getGradeIds().isEmpty()) { + updateGradeRelations(groupId, dto.getGradeIds()); + } else { + // 如果为空,删除所有年级关联(若要求全量替换) + groupInGradeRepository.deleteByCgGroupId(groupId); + } + + // 8.2 学科关联 + if (dto.getSubjectIds() != null && !dto.getSubjectIds().isEmpty()) { + updateSubjectRelations(groupId, dto.getSubjectIds()); + } else { + groupInSubjectRepository.deleteByCgGroupId(groupId); + } + + // 8.3 教师关联(组长 + 组员) + // 先删除该组所有教师关联,再重新插入 + groupInTeacherRepository.deleteByCgGroupId(groupId); + + List teacherRelations = new ArrayList<>(); + + // 添加组长(groupType = 1) + if (dto.getLeaderIds() != null) { + for (Integer leaderId : dto.getLeaderIds()) { + SchTeacherCustomGroupInTeacher rel = new SchTeacherCustomGroupInTeacher(); + rel.setCgGroupId(groupId); + rel.setGroupType(1); + rel.setTeaId(leaderId); + teacherRelations.add(rel); + } + } + + // 添加组员(groupType = 2),排除组长 + Set leaderIdSet = dto.getLeaderIds() != null ? new HashSet<>(dto.getLeaderIds()) : Collections.emptySet(); + if (dto.getMemberIds() != null) { + for (Integer memberId : dto.getMemberIds()) { + // 如果该教师同时也是组长,则不再作为组员(避免重复) + if (leaderIdSet.contains(memberId)) { + continue; + } + SchTeacherCustomGroupInTeacher rel = new SchTeacherCustomGroupInTeacher(); + rel.setCgGroupId(groupId); + rel.setGroupType(2); + rel.setTeaId(memberId); + teacherRelations.add(rel); + } + } + + if (!teacherRelations.isEmpty()) { + groupInTeacherRepository.saveAll(teacherRelations); + } + } + + // 9. 清除缓存 + String cacheKey = RedisConstants.SCHOOL_CUSTOM_GROUP + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + // 10. 记录日志(如有) + importLogs(user, saveList); + + } catch (DException e) { + throw e; + } catch (Exception e) { + log.error("导入自定义组时发生系统异常,操作人:" + user.getUserName(), e); + throw new DException("导入失败,请联系管理员!
错误详情:
" + e.getMessage()); + } + } + + /** + * 记录导入日志 + * @param user 操作用户 + * @param groups 导入的组列表 + */ + private void importLogs(UserContext.UserInfo user, List groups) { + if (groups == null || groups.isEmpty()) { + return; + } + // 提取组名称列表 + String groupNames = groups.stream() + .map(SchTeacherCustomGroup::getGroupName) + .collect(Collectors.joining("、")); + String description = "导入自定义组:" + groupNames; + + // 方式2:使用 LogContextHolder(与 @OperationLog 配合) + LogContextHolder.setDescription(description); + + // 方式3:仅记录到普通日志文件 + log.info("用户 {} 导入了自定义组:{}", user.getUserName(), groupNames); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicCampusService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicCampusService.java new file mode 100644 index 0000000..bf227a7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicCampusService.java @@ -0,0 +1,245 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.Repository.SchDicCampusRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchDicCampus; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicCampusService; +import com.bestsch.bschclassmanage.utils.*; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchDicCampusService implements ISchDicCampusService { + + @Autowired + private SchDicCampusRepository schDicCampusRepository; + + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private RedisUtil redisUtil; + + + public List getSchDicCampusList(Integer schId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schDicCampusRepository.findAll(spec); + } + + // 获取学校院校列表(带缓存) + public List getSchDicCampusCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + // 注意:返回副本或不可变列表,避免外部修改影响缓存 + return redisUtil.getList(cacheKey,SchDicCampus.class); + } + // 同步查询数据库,防止缓存击穿 + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey,SchDicCampus.class); + } + List list = getSchDicCampusList(schId); + + // 根据 sort 字段升序排序,null 值排在最后 + list.sort(Comparator.comparing(SchDicCampus::getSort, + Comparator.nullsLast(Comparator.naturalOrder()))); + + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + return list; + } + } + + + @OperationLog(module = LogModule.CAMPUS) + @Transactional(rollbackFor = Exception.class) + public void saveSchCampus(UserContext.UserInfo user, SchDicCampus entity) { + + Integer schId=user.getSchId(); + + boolean isNew=entity.getId() == null || entity.getId() == 0; + // 参数校验 + if (entity.getName() == null || entity.getName().trim().isEmpty()) + throw new IllegalArgumentException("校区名称不能为空"); + + boolean nameExists; + SchDicCampus oldEntity=null; + + if (isNew) { + // 新增:检查同名校区 + nameExists = schDicCampusRepository.existsBySchIdAndName(schId, entity.getName()); + if (nameExists) { + throw new IllegalArgumentException("校区名称已存在:" + entity.getName()); + } + OtherUtil.setBaseEntityValue(user, entity); + + schDicCampusRepository.save(entity); + } else { + // 更新:排除自身,检查其他校区同名 + nameExists = schDicCampusRepository.existsBySchIdAndNameAndIdNot(schId, entity.getName(), entity.getId()); + if (nameExists) { + throw new IllegalArgumentException("校区名称已存在:" + entity.getName()); + } + Integer entityId=entity.getId(); + SchDicCampus existing = schDicCampusRepository.findById(entityId) + .orElseThrow(() -> new IllegalArgumentException("校区不存在,ID=" + entityId)); + + oldEntity=OtherUtil.deepCopy(existing,SchDicCampus.class); + + OtherUtil.setBaseEntityValue(user, entity); + + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.code, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + + entity=schDicCampusRepository.save(existing); + } + + // 清除缓存 + String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + schId; + redisUtil.del(cacheKey); + + { + String description = buildCampusLogDescription(entity,isNew,oldEntity); + LogContextHolder.setDescription(description); + } + } + + /** + * 构建学部操作的详细日志描述 + */ + private String buildCampusLogDescription(SchDicCampus newEntity,boolean isNew,SchDicCampus oldEntity) { + if (isNew) { + return String.format("新增校区:%s(序号:%d)", + newEntity.getName(), + newEntity.getSort() != null ? newEntity.getSort() : 0); + } else { + List changes = new ArrayList<>(); + if (!Objects.equals(oldEntity.getName(), newEntity.getName())) { + changes.add(String.format("名称从 '%s' 修改为 '%s'", oldEntity.getName(), newEntity.getName())); + } + if (!Objects.equals(oldEntity.getSort(), newEntity.getSort())) { + changes.add(String.format("序号从 %d 修改为 %d", oldEntity.getSort(), newEntity.getSort())); + } + if (changes.isEmpty()) { + return "更新校区:无实际变更"; + } + return "更新校区:" + String.join(";", changes); + } + } + + @OperationLog(module = LogModule.CAMPUS) + @Transactional(rollbackFor = Exception.class) + public void sortSchCampus(UserContext.UserInfo user,List ids) + { + List campusList = getSchDicCampusCacheList(user.getSchId()); + Map campusMap = campusList.stream() + .collect(Collectors.toMap(SchDicCampus::getId, Function.identity())); + + Date now = new Date(); + // 1. 按传入顺序更新 sort 值 + int sortOrder = 1; + for (Integer id : ids) { + SchDicCampus campus = campusMap.get(id); + if (campus != null) { + campus.setSort(sortOrder++); + campus.setUpdateDate(now); + campus.setUpdateUserId(user.getUserId()); + } + } + + // 2. 处理未出现在排序列表中的校区(设置 sort = null 或一个大值) + for (SchDicCampus campus : campusList) { + if (!ids.contains(campus.getId())) { + campus.setSort(null); // 或者设置一个最大值,比如 999 + campus.setUpdateDate(now); + campus.setUpdateUserId(user.getUserId()); + } + } + // 批量保存 + schDicCampusRepository.saveAll(campusList); + String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + user.getSchId(); + redisUtil.del(cacheKey); + { + String names = ids.stream() + .map(id -> { + SchDicCampus m = campusMap.get(id); + return m != null ? m.getName() : String.valueOf(id); + }) + .collect(Collectors.joining("、")); + String description = String.format("调整校区排序:共 %d 个专业(列表:%s)", ids.size(), names); + LogContextHolder.setDescription(description); + } + } + + /** + * 删除校区 + * 1. 参数非空校验 + * 2. 校验校区是否存在(匹配学校+校区ID,防止跨学校删除) + * 3. 校验校区是否绑定班级,存在关联则禁止删除 + * 4. 删除数据库数据 + 清除对应学校校区缓存 + * @param id 校区ID + */ + + @OperationLog(module = LogModule.CAMPUS) + @Transactional(rollbackFor = Exception.class) + public void delete(UserContext.UserInfo user, Integer id) { + // 1. 参数合法性校验 + if (user.getSchId() == null || id == null) { + throw new DException("学校ID、校区ID不能为空"); + } + + // 2. 校验当前学校下该校区是否存在,防止越权删除其他学校校区 + SchDicCampus campus = schDicCampusRepository.findByIdAndSchId(id, user.getSchId()) + .orElseThrow(() -> new DException("校区不存在,无法删除")); + + // 3. 业务校验:判断校区是否关联班级,有班级则禁止删除 + long bindClassCount = schClassRepository.countByCampusId(id); + if (bindClassCount > 0) { + throw new DException(String.format("该校区下存在%s个班级,不可删除,请先移除班级关联", bindClassCount)); + } + + // 4. 删除数据 + schDicCampusRepository.delete(campus); + + // 5. 清除当前学校校区缓存 + String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + LogContextHolder.setDescription("删除校区:"+campus.getName()); + log.debug("操作人:{},删除校区日志:{}", user.getUserName(), JSON.toJSONString(campus)); + } + + public List select(Integer schId) { + List list = getSchDicCampusCacheList(schId); + return ModelMapperUtil.toSelectIntVOList(list, SchDicCampus::getId, SchDicCampus::getName); + } + + public Map toIdAndNameMap(Integer schId) { + List list = getSchDicCampusCacheList(schId); + return ModelMapperUtil.toMap(list, SchDicCampus::getId, SchDicCampus::getName); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicCourseService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicCourseService.java new file mode 100644 index 0000000..16c45a7 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicCourseService.java @@ -0,0 +1,466 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.*; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.*; +import com.bestsch.bschclassmanage.enums.CourseType; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.dto.SchDicCourseDTO; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchDicCourseVO; +import com.bestsch.bschclassmanage.service.ISchDicCourseService; +import com.bestsch.bschclassmanage.service.ISchDicDivisionService; +import com.bestsch.bschclassmanage.service.ISchDicMajorsService; +import com.bestsch.bschclassmanage.utils.*; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchDicCourseService implements ISchDicCourseService { + + @Autowired + private SchDicCourseRepository schDicCourseRepository; + @Autowired + private SchDicCourseMajorsRepository schDicCourseMajorsRepository; + @Autowired + private SchDicCourseDivisionRepository schDicCourseDivisionRepository; + @Autowired + private ISchDicMajorsService schDicMajorsService; + @Autowired + private ISchDicDivisionService schDicDivisionService; + + @Autowired + private RedisUtil redisUtil; + + + public List getSchDicCourseList(Integer schId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schDicCourseRepository.findAll(spec); + } + + public List getSchDicCourseCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_COURSE + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + // 注意:返回副本或不可变列表,避免外部修改影响缓存 + return redisUtil.getList(cacheKey,SchDicCourse.class); + } + // 同步查询数据库,防止缓存击穿 + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey,SchDicCourse.class); + } + List list = getSchDicCourseList(schId); + + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + return list; + } + } + + + public PageVO search(Integer schId, Integer type, String keyword, + Integer divisionId, Integer majorsId, + Pageable pageable) { + + // 1. 查询课程分页(动态条件已在 Repository 中处理) + Page coursePage = schDicCourseRepository.findCoursesByConditions( + schId, type, keyword, divisionId, majorsId, pageable + ); + + if (coursePage.isEmpty()) { + return PageVO.empty(pageable.getPageSize()); + } + + // 2. 提取课程 ID 列表 + List courseIds = coursePage.getContent().stream() + .map(SchDicCourse::getId) + .collect(Collectors.toList()); + + // 3. 批量加载关联关系(按课程ID分组) + Map> majorsGroup = loadMajorsGroup(courseIds, schId); + Map> divisionGroup = loadDivisionGroup(courseIds, schId); + + // 4. 获取当前学校的所有专业和学部(用于填充实体详情) + Map majorsMap = schDicMajorsService.getSchDicMajorsCacheList(schId) + .stream() + .collect(Collectors.toMap(SchDicMajors::getId, Function.identity())); + + Map divisionMap = schDicDivisionService.getSchDicDivisionCacheList(schId) + .stream() + .collect(Collectors.toMap(SchDicDivision::getId, Function.identity())); + + // 5. 转换每个课程为 VO + List voList = coursePage.getContent().stream() + .map(course -> convertToVO(course, majorsGroup, divisionGroup, majorsMap, divisionMap)) + .collect(Collectors.toList()); + + return new PageVO<>(pageable.getPageNumber() + 1, + pageable.getPageSize(), + coursePage.getTotalElements(), + voList); + } + + @OperationLog(module = LogModule.COURSE) + @Transactional(rollbackFor = Exception.class) + public void saveSchCourse(UserContext.UserInfo user, SchDicCourseDTO dto) { + + Integer schId = user.getSchId(); + + // 1. 基础校验 + if (dto == null) { + throw new IllegalArgumentException("课程数据不能为空"); + } + + if (StringUtils.isBlank(dto.getName())) { + throw new IllegalArgumentException("课程名称不能为空"); + } + + // 2. VO → Entity 映射 + SchDicCourse entity = ModelMapperUtil.map(dto, SchDicCourse.class); + + // 3. 名称唯一性校验 + boolean isNew = (entity.getId() == null || entity.getId() == 0); + boolean nameExists = isNew ? + schDicCourseRepository.existsBySchIdAndName(schId, entity.getName()) : + schDicCourseRepository.existsBySchIdAndNameAndIdNot(schId, entity.getName(), entity.getId()); + if (nameExists) { + throw new IllegalArgumentException("课程名称已存在:" + entity.getName()); + } + SchDicCourse oldEntity = null; + Set oldMajors = null; + Set oldDivisions = null; + // 4. 执行保存(新增或更新) + if (isNew) { + OtherUtil.setBaseEntityValue(user, entity); // 设置创建/更新审计字段 + entity = schDicCourseRepository.save(entity); + } else { + SchDicCourse existing = schDicCourseRepository.findById(dto.getId()) + .orElseThrow(() -> new IllegalArgumentException("课程不存在,ID=" + dto.getId())); + + oldEntity=OtherUtil.deepCopy(existing,SchDicCourse.class); + oldMajors = loadMajorsIdSet(dto.getId(),user.getSchId()); + oldDivisions = loadDivisionsIdSet(dto.getId(),user.getSchId()); + + // 复制允许修改的字段(忽略 id, schId, 创建审计字段) + OtherUtil.setBaseEntityValue(user, entity); // 设置创建/更新审计字段 + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + // 更新时需单独设置 updateDate / updateUserId(假设 setBaseEntityValue 已处理) + entity = schDicCourseRepository.save(existing); + } + + // 5. 维护关联关系(删除旧关联 → 添加新关联) + Integer courseId = entity.getId(); + + // 5.1 删除旧的关联 + deleteRelations(courseId, schId); + + // 5.2 保存新的关联 + saveRelations(courseId, schId, dto); + + // 6. 清除缓存 + String cacheKey = RedisConstants.SCHOOL_COURSE + "_" + schId; + redisUtil.del(cacheKey); + + { + String description = buildCourseLogDescription(entity, isNew, oldEntity, dto, + oldMajors, oldDivisions, + schDicMajorsService.toIdAndNameMap(user.getSchId()), + schDicDivisionService.toIdAndNameMap(user.getSchId())); + LogContextHolder.setDescription(description); + } + } + /** + * 构建课程操作的详细日志描述 + */ + private String buildCourseLogDescription(SchDicCourse newEntity, boolean isNew, + SchDicCourse oldEntity, SchDicCourseDTO dto, + Set oldMajors, Set oldDivisions, + Map majorsNameMap, + Map divisionNameMap) { + + try { + List parts = new ArrayList<>(); + + // ========== 1. 课程本身的变化 ========== + if (isNew) { + parts.add(String.format("新增课程:%s(编码:%s,类型:%s,别称:%s)", + newEntity.getName(), + newEntity.getCode() != null ? newEntity.getCode() : "无", + CourseType.nameById(newEntity.getType()), + newEntity.getNickname() != null ? newEntity.getNickname() : "无")); + } else { + List changes = new ArrayList<>(); + if (!Objects.equals(oldEntity.getName(), newEntity.getName())) { + changes.add(String.format("名称从 '%s' 修改为 '%s'", oldEntity.getName(), newEntity.getName())); + } + if (!Objects.equals(oldEntity.getCode(), newEntity.getCode())) { + changes.add(String.format("编码从 '%s' 修改为 '%s'", oldEntity.getCode(), newEntity.getCode())); + } + if (!Objects.equals(oldEntity.getNickname(), newEntity.getNickname())) { + changes.add(String.format("别称从 '%s' 修改为 '%s'", oldEntity.getNickname(), newEntity.getNickname())); + } + if (!Objects.equals(oldEntity.getType(), newEntity.getType())) { + changes.add(String.format("类型从 '%s' 修改为 '%s'", + CourseType.nameById(oldEntity.getType()), + CourseType.nameById(newEntity.getType()))); + } + + if (changes.isEmpty()) { + parts.add("课程信息无变更"); + } else { + parts.add("课程变更:" + String.join(";", changes)); + } + } + + // ========== 2. 关联关系变化(专业) ========== + Set newMajors = dto.getMajorsIds(); + if (!isNew && oldMajors != null) { + Set addedMajors = new HashSet<>(newMajors); + addedMajors.removeAll(oldMajors); + Set removedMajors = new HashSet<>(oldMajors); + removedMajors.removeAll(newMajors); + if (!addedMajors.isEmpty()) { + parts.add("绑定专业:" + getNames(addedMajors, majorsNameMap)); + } + if (!removedMajors.isEmpty()) { + parts.add("解绑专业:" + getNames(removedMajors, majorsNameMap)); + } + } else if (isNew && newMajors != null && !newMajors.isEmpty()) { + parts.add("绑定专业:" + getNames(newMajors, majorsNameMap)); + } + + // ========== 3. 关联关系变化(学部) ========== + Set newDivisions = dto.getDivisionIds(); + if (!isNew && oldDivisions != null) { + Set addedDivs = new HashSet<>(newDivisions); + addedDivs.removeAll(oldDivisions); + Set removedDivs = new HashSet<>(oldDivisions); + removedDivs.removeAll(newDivisions); + if (!addedDivs.isEmpty()) { + parts.add("绑定学部:" + getNames(addedDivs, divisionNameMap)); + } + if (!removedDivs.isEmpty()) { + parts.add("解绑学部:" + getNames(removedDivs, divisionNameMap)); + } + } else if (isNew && newDivisions != null && !newDivisions.isEmpty()) { + parts.add("绑定学部:" + getNames(newDivisions, divisionNameMap)); + } + + return String.join(";", parts); + } catch (Exception e) { + // 日志构建失败时返回简短描述,不影响主流程 + log.error("构建课程日志描述失败:{}", e.getMessage()); + return isNew ? "新增课程(日志生成失败)" : "更新课程(日志生成失败)"; + } + } + + /** + * 将 Set 转换为名称字符串(用"、"分隔) + */ + private String getNames(Set ids, Map nameMap) { + if (ids == null || ids.isEmpty()) return "无"; + return ids.stream() + .map(id -> nameMap.getOrDefault(id, String.valueOf(id))) + .collect(Collectors.joining("、")); + } + + @OperationLog(module = LogModule.COURSE) + @Transactional(rollbackFor = Exception.class) + public void delete(UserContext.UserInfo user,Integer id){ + + SchDicCourse entity= schDicCourseRepository.findByIdAndSchId(id,user.getSchId()) + .orElseThrow(() -> new DException( "课程不存在")); + + String cacheKey = RedisConstants.SCHOOL_COURSE + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + deleteRelations(id, user.getSchId()); + schDicCourseRepository.deleteById(id); + + String description = String.format("删除课程:%s(编码:%s,类型:%s)", + entity.getName(), + entity.getCode() != null ? entity.getCode() : "无", + CourseType.nameById(entity.getType())); + LogContextHolder.setDescription(description); + log.debug("操作人:{},删除课程日志:{}", user.getUserName(), JSON.toJSONString(entity)); + } + + + + +// ==================== 私有辅助方法 ==================== + + /** + * 批量删除课程-专业、课程-学部关联 + */ + private void deleteRelations(Integer courseId, Integer schId) { + schDicCourseMajorsRepository.deleteByCourseIdAndSchId(courseId, schId); + schDicCourseDivisionRepository.deleteByCourseIdAndSchId(courseId, schId); + } + + /** + * 批量保存新的课程-专业、课程-学部关联 + */ + private void saveRelations(Integer courseId, Integer schId, SchDicCourseDTO dto) { + // 保存专业关联 + if (CollectionUtils.isNotEmpty(dto.getMajorsIds())) { + List majorsList = dto.getMajorsIds().stream() + .filter(Objects::nonNull) + .map(id -> { + SchDicCourseMajors rel = new SchDicCourseMajors(); + rel.setCourseId(courseId); + rel.setMajorsId(id); + rel.setSchId(schId); + return rel; + }) + .collect(Collectors.toList()); + if (!majorsList.isEmpty()) { + schDicCourseMajorsRepository.saveAll(majorsList); + } + } + + // 保存学部关联 + if (CollectionUtils.isNotEmpty(dto.getDivisionIds())) { + List divisionList = dto.getDivisionIds().stream() + .filter(Objects::nonNull) + .map(id -> { + SchDicCourseDivision rel = new SchDicCourseDivision(); + rel.setCourseId(courseId); + rel.setDivisionId(id); + rel.setSchId(schId); + return rel; + }) + .collect(Collectors.toList()); + if (!divisionList.isEmpty()) { + schDicCourseDivisionRepository.saveAll(divisionList); + } + } + } + + + /** + * 批量加载课程-专业关联关系,并按 courseId 分组 + */ + private Map> loadMajorsGroup(List courseIds, Integer schId) { + if (courseIds.isEmpty()) { + return Collections.emptyMap(); + } + return schDicCourseMajorsRepository.findByCourseIdInAndSchId(courseIds, schId) + .stream() + .collect(Collectors.groupingBy(SchDicCourseMajors::getCourseId)); + } + + /** + * 加载指定课程关联的专业列表(单个) + */ + private List loadMajorsList(Integer courseId, Integer schId) { + if (courseId == null) { + return Collections.emptyList(); + } + return schDicCourseMajorsRepository.findByCourseIdAndSchId(courseId, schId); + } + + /** + * 加载指定课程关联的专业ID集合(用于日志) + */ + private Set loadMajorsIdSet(Integer courseId, Integer schId) { + return loadMajorsList(courseId, schId).stream() + .map(SchDicCourseMajors::getMajorsId) + .collect(Collectors.toSet()); + } + + + + /** + * 批量加载课程-学部关联关系,并按 courseId 分组 + */ + private Map> loadDivisionGroup(List courseIds, Integer schId) { + if (courseIds.isEmpty()) { + return Collections.emptyMap(); + } + return schDicCourseDivisionRepository.findByCourseIdInAndSchId(courseIds, schId) + .stream() + .collect(Collectors.groupingBy(SchDicCourseDivision::getCourseId)); + } + + private List loadDivisionsList(Integer courseId, Integer schId) { + if (courseId == null) { + return Collections.emptyList(); + } + return schDicCourseDivisionRepository.findByCourseIdAndSchId(courseId, schId); + } + + private Set loadDivisionsIdSet(Integer courseId, Integer schId) { + return loadDivisionsList(courseId, schId).stream() + .map(SchDicCourseDivision::getDivisionId) + .collect(Collectors.toSet()); + } + + /** + * 将单个课程实体转换为 VO,并填充关联列表 + */ + private SchDicCourseVO convertToVO(SchDicCourse course, + Map> majorsGroup, + Map> divisionGroup, + Map majorsEntityMap, + Map divisionEntityMap) { + // 使用 ModelMapperUtil 复制基础字段 + SchDicCourseVO vo = ModelMapperUtil.map(course, SchDicCourseVO.class); + if (vo == null&& course != null) throw new DException("数据转换失败"); + + + // 填充 typeName + vo.setTypeName(CourseType.nameById(course.getType())); + + // 填充 majorsList + List majorsRel = majorsGroup.getOrDefault(course.getId(), Collections.emptyList()); + List majors = majorsRel.stream() + .map(rel -> majorsEntityMap.get(rel.getMajorsId())) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 按 sort 升序,null 值排在最后 + majors.sort(Comparator.comparing(SchDicMajors::getSort, Comparator.nullsLast(Comparator.naturalOrder()))); + + vo.setMajorsList(majors); + + // 填充 divisionList + List divisionRel = divisionGroup.getOrDefault(course.getId(), Collections.emptyList()); + List divisions = divisionRel.stream() + .map(rel -> divisionEntityMap.get(rel.getDivisionId())) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 按 sort 升序,null 值排在最后 + divisions.sort(Comparator.comparing(SchDicDivision::getSort, Comparator.nullsLast(Comparator.naturalOrder()))); + + vo.setDivisionList(divisions); + + return vo; + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicDivisionService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicDivisionService.java new file mode 100644 index 0000000..9932e04 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicDivisionService.java @@ -0,0 +1,221 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.SchDicDivisionRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchDicDivision; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicDivisionService; +import com.bestsch.bschclassmanage.utils.*; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchDicDivisionService implements ISchDicDivisionService { + + @Autowired + private SchDicDivisionRepository schDicDivisionRepository; + + @Autowired + private RedisUtil redisUtil; + + + public List getSchDicDivisionList(Integer schId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schDicDivisionRepository.findAll(spec); + } + + // 获取学校院校列表(带缓存) + public List getSchDicDivisionCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_DICISION + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + // 注意:返回副本或不可变列表,避免外部修改影响缓存 + return redisUtil.getList(cacheKey,SchDicDivision.class); + } + // 同步查询数据库,防止缓存击穿 + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey,SchDicDivision.class); + } + List list = getSchDicDivisionList(schId); + + list.sort(Comparator.comparing(SchDicDivision::getSort, + Comparator.nullsLast(Comparator.naturalOrder()))); + + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + return list; + } + } + + @OperationLog(module = LogModule.DIVISION) + @Transactional(rollbackFor = Exception.class) + public void saveSchDivision(UserContext.UserInfo user,SchDicDivision entity) { + + Integer schId=user.getSchId(); + + boolean isNew=entity.getId() == null || entity.getId() == 0; + + // 参数校验 + if (entity.getName() == null || entity.getName().trim().isEmpty()) + throw new DException("学部名称不能为空"); + + SchDicDivision oldEntity=null; + + boolean nameExists; + if (isNew) { + // 新增:检查是否存在同名 + nameExists = schDicDivisionRepository.existsBySchIdAndName(schId, entity.getName()); + if (nameExists) { + throw new DException("学部名称已存在:" + entity.getName()); + } + + OtherUtil.setBaseEntityValue(user, entity); + + schDicDivisionRepository.save(entity); + } else { + // 更新:排除自身,检查其他记录是否有同名 + nameExists = schDicDivisionRepository.existsBySchIdAndNameAndIdNot(schId, entity.getName(), entity.getId()); + if (nameExists) { + throw new DException("学部名称已存在:" + entity.getName()); + } + Integer entityId=entity.getId(); + SchDicDivision existing = schDicDivisionRepository.findById(entityId) + .orElseThrow(() -> new DException("学部不存在,ID=" + entityId)); + + oldEntity=OtherUtil.deepCopy(existing,SchDicDivision.class); + + OtherUtil.setBaseEntityValue(user, entity); + + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.code, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + + entity= schDicDivisionRepository.save(existing); + } + + // 清除缓存 + String cacheKey = RedisConstants.SCHOOL_DICISION + "_" + schId; + redisUtil.del(cacheKey); + + { + String description = buildDivisionLogDescription(entity,isNew,oldEntity); + LogContextHolder.setDescription(description); + } + } + + /** + * 构建学部操作的详细日志描述 + */ + private String buildDivisionLogDescription(SchDicDivision newEntity,boolean isNew,SchDicDivision oldEntity) { + if (isNew) { + return String.format("新增学部:%s(序号:%d)", + newEntity.getName(), + newEntity.getSort() != null ? newEntity.getSort() : 0); + } else { + List changes = new ArrayList<>(); + if (!Objects.equals(oldEntity.getName(), newEntity.getName())) { + changes.add(String.format("名称从 '%s' 修改为 '%s'", oldEntity.getName(), newEntity.getName())); + } + if (!Objects.equals(oldEntity.getSort(), newEntity.getSort())) { + changes.add(String.format("序号从 %d 修改为 %d", oldEntity.getSort(), newEntity.getSort())); + } + if (changes.isEmpty()) { + return "更新学部:无实际变更"; + } + return "更新学部:" + String.join(";", changes); + } + } + + + @OperationLog(module = LogModule.DIVISION) //使用专业管理模块 + @Transactional(rollbackFor = Exception.class) + public void sortSchDivision(UserContext.UserInfo user,List ids) + { + List divisionList = getSchDicDivisionCacheList(user.getSchId()); + Map divistionMap = divisionList.stream() + .collect(Collectors.toMap(SchDicDivision::getId, Function.identity())); + + Date now = new Date(); + // 1. 按传入顺序更新 sort 值 + int sortOrder = 1; + for (Integer id : ids) { + SchDicDivision division = divistionMap.get(id); + if (division != null) { + division.setSort(sortOrder++); + division.setUpdateDate(now); + division.setUpdateUserId(user.getUserId()); + } + } + + // 2. 处理未出现在排序列表中的校区(设置 sort = null 或一个大值) + for (SchDicDivision campus : divisionList) { + if (!ids.contains(campus.getId())) { + campus.setSort(null); // 或者设置一个最大值,比如 999 + campus.setUpdateDate(now); + campus.setUpdateUserId(user.getUserId()); + } + } + // 批量保存 + schDicDivisionRepository.saveAll(divisionList); + String cacheKey = RedisConstants.SCHOOL_DICISION + "_" + user.getSchId(); + redisUtil.del(cacheKey); + { + String names = ids.stream() + .map(id -> { + SchDicDivision m = divistionMap.get(id); + return m != null ? m.getName() : String.valueOf(id); + }) + .collect(Collectors.joining("、")); + String description = String.format("调整系部排序:共 %d 个专业(列表:%s)", ids.size(), names); + LogContextHolder.setDescription(description); + } + } + + @OperationLog(module = LogModule.DIVISION) //使用专业管理模块 + @Transactional(rollbackFor = Exception.class) + public void delete(UserContext.UserInfo user,Integer id){ + + SchDicDivision schDicDivision= schDicDivisionRepository.findByIdAndSchId(id,user.getSchId()) + .orElseThrow(() -> new DException( "系部不存在")); + + String cacheKey = RedisConstants.SCHOOL_DICISION + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + schDicDivisionRepository.deleteById(id); + + LogContextHolder.setDescription("删除系部:"+schDicDivision.getName()); + log.debug("操作人:{},删除专业日志:{}", user.getUserName(), JSON.toJSONString(schDicDivision)); + } + + + public List select(Integer schId) { + List list = getSchDicDivisionCacheList(schId); + return ModelMapperUtil.toSelectIntVOList(list, SchDicDivision::getId, SchDicDivision::getName); + } + + public Map toIdAndNameMap(Integer schId) { + List list = getSchDicDivisionCacheList(schId); + return ModelMapperUtil.toMap(list, SchDicDivision::getId, SchDicDivision::getName); + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicMajorsService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicMajorsService.java new file mode 100644 index 0000000..9433582 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicMajorsService.java @@ -0,0 +1,231 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.SchDicMajorsRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchDicMajors; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchDicMajorsService; +import com.bestsch.bschclassmanage.utils.*; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchDicMajorsService implements ISchDicMajorsService { + + @Autowired + private SchDicMajorsRepository schDicMajorsRepository; + + @Autowired + private RedisUtil redisUtil; + + public List getSchDicMajorsList(Integer schId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schDicMajorsRepository.findAll(spec); + } + + // 获取学校专业列表(带缓存) + public List getSchDicMajorsCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_MAJORS + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey,SchDicMajors.class); + } + // 同步查询数据库,防止缓存击穿 + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey,SchDicMajors.class); + } + List list = getSchDicMajorsList(schId); + + list.sort(Comparator.comparing(SchDicMajors::getSort, + Comparator.nullsLast(Comparator.naturalOrder()))); + + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + return list; + } + } + + public List getSchDicMajorsList(Integer schId, String keyword) { + List list = getSchDicMajorsCacheList(schId); + if (StringUtils.isNotBlank(keyword)) { + list = list.stream() + .filter(s -> s.getName() != null && s.getName().contains(keyword)) + .collect(Collectors.toList()); + } + return list; + } + + @OperationLog(module = LogModule.MAJORS) + @Transactional(rollbackFor = Exception.class) + public void saveSchMajors(UserContext.UserInfo user, SchDicMajors entity) { + + if (entity.getName() == null || entity.getName().trim().isEmpty()) + throw new DException("专业名称不能为空"); + + Integer schId=user.getSchId(); + SchDicMajors oldEntity = null; + boolean isNew = (entity.getId() == null || entity.getId() == 0); + + // 检查名称是否已存在(同一学校下) + boolean nameExists; + if (isNew) { + // 新增:检查是否存在同名专业 + nameExists = schDicMajorsRepository.existsBySchIdAndName(schId, entity.getName()); + if (nameExists) { + throw new DException ("专业名称已存在:" + entity.getName()); + } + OtherUtil.setBaseEntityValue(user, entity); + // 新增操作 + schDicMajorsRepository.save(entity); + } else { + // 更新:排除自身,检查其他记录是否有同名 + nameExists = schDicMajorsRepository.existsBySchIdAndNameAndIdNot(schId, entity.getName(), entity.getId()); + if (nameExists) { + throw new DException ("专业名称已存在:" + entity.getName()); + } + SchDicMajors existing = schDicMajorsRepository.findById(entity.getId()) + .orElseThrow(() -> new DException ("专业不存在,ID=" + entity.getId())); + + oldEntity= OtherUtil.deepCopy(existing,SchDicMajors.class); + + OtherUtil.setBaseEntityValue(user, entity); + + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.code, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + + schDicMajorsRepository.save(existing); + } + + // 清除缓存 + String cacheKey = RedisConstants.SCHOOL_MAJORS + "_" +schId; + redisUtil.del(cacheKey); + + { + // 4. 构建日志描述(独立方法) + String description = buildMajorsLogDescription(entity, oldEntity, isNew); + // 5. 设置日志上下文 + LogContextHolder.setDescription(description); + } + + } + private String buildMajorsLogDescription(SchDicMajors newEntity, SchDicMajors oldEntity, boolean isNew) { + if (isNew) { + return String.format("新增专业:%s(代码:%s,学制长度:%d,序号:%d)", + newEntity.getName(), + newEntity.getCode() != null ? newEntity.getCode() : "无", + newEntity.getSchsystemLeng() != null ? newEntity.getSchsystemLeng() : 0, + newEntity.getSort() != null ? newEntity.getSort() : 0); + } else { + List changes = new ArrayList<>(); + if (!Objects.equals(oldEntity.getName(), newEntity.getName())) { + changes.add(String.format("名称从 '%s' 修改为 '%s'", oldEntity.getName(), newEntity.getName())); + } + if (!Objects.equals(oldEntity.getCode(), newEntity.getCode())) { + changes.add(String.format("代码从 '%s' 修改为 '%s'", oldEntity.getCode(), newEntity.getCode())); + } + if (!Objects.equals(oldEntity.getSchsystemLeng(), newEntity.getSchsystemLeng())) { + changes.add(String.format("学制长度从 %d 修改为 %d", oldEntity.getSchsystemLeng(), newEntity.getSchsystemLeng())); + } + if (!Objects.equals(oldEntity.getSort(), newEntity.getSort())) { + changes.add(String.format("序号从 %d 修改为 %d", oldEntity.getSort(), newEntity.getSort())); + } + + if (changes.isEmpty()) { + return "更新专业:无实际变更"; + } else { + return "更新专业:" + String.join(";", changes); + } + } + } + + @OperationLog(module = LogModule.MAJORS) //使用专业管理模块 + @Transactional(rollbackFor = Exception.class) + public void sortSchMajors(UserContext.UserInfo user,List ids) + { + List majorsList = getSchDicMajorsCacheList(user.getSchId()); + Map majorsMap = majorsList.stream() + .collect(Collectors.toMap(SchDicMajors::getId, Function.identity())); + + Date now = new Date(); + // 1. 按传入顺序更新 sort 值 + int sortOrder = 1; + for (Integer id : ids) { + SchDicMajors majors = majorsMap.get(id); + if (majors != null) { + majors.setSort(sortOrder++); + majors.setUpdateDate(now); + majors.setUpdateUserId(user.getUserId()); + } + } + + // 2. 处理未出现在排序列表中的校区(设置 sort = null 或一个大值) + for (SchDicMajors majors : majorsList) { + if (!ids.contains(majors.getId())) { + majors.setSort(null); // 或者设置一个最大值,比如 999 + majors.setUpdateDate(now); + majors.setUpdateUserId(user.getUserId()); + } + } + // 批量保存 + schDicMajorsRepository.saveAll(majorsList); + String cacheKey = RedisConstants.SCHOOL_MAJORS + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + { + String names = ids.stream() + .map(id -> { + SchDicMajors m = majorsMap.get(id); + return m != null ? m.getName() : String.valueOf(id); + }) + .collect(Collectors.joining("、")); + String description = String.format("调整专业排序:共 %d 个专业(列表:%s)", ids.size(), names); + LogContextHolder.setDescription(description); + } + } + + @OperationLog(module = LogModule.MAJORS) // 使用专业管理模块 + @Transactional(rollbackFor = Exception.class) + public void delete(UserContext.UserInfo user,Integer id){ + + SchDicMajors schDicMajors= schDicMajorsRepository.findByIdAndSchId(id,user.getSchId()) + .orElseThrow(() -> new DException( "专业不存在")); + + String cacheKey = RedisConstants.SCHOOL_MAJORS + "_" + user.getSchId(); + redisUtil.del(cacheKey); + schDicMajorsRepository.deleteById(id); + LogContextHolder.setDescription("删除专业:"+schDicMajors.getName()); + log.debug("操作人:{},删除专业日志:{}", user.getUserName(), JSON.toJSONString(schDicMajors)); + } + + public List select(Integer schId) { + List list = getSchDicMajorsCacheList(schId); + return ModelMapperUtil.toSelectIntVOList(list, SchDicMajors::getId, SchDicMajors::getName); + } + + public Map toIdAndNameMap(Integer schId) { + List list = getSchDicMajorsCacheList(schId); + return ModelMapperUtil.toMap(list, SchDicMajors::getId, SchDicMajors::getName); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicSubjectService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicSubjectService.java new file mode 100644 index 0000000..32e89c8 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchDicSubjectService.java @@ -0,0 +1,345 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.SchDicSubjectRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.BaseDicSubject; +import com.bestsch.bschclassmanage.entity.SchDicSubject; +import com.bestsch.bschclassmanage.enums.Source; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.service.ISchBinSchsystemService; +import com.bestsch.bschclassmanage.service.ISchDicSubjectService; +import com.bestsch.bschclassmanage.utils.*; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +@Slf4j +@Service +public class SchDicSubjectService implements ISchDicSubjectService { + + @Autowired + private SchDicSubjectRepository schDicSubjectRepository; + @Autowired + private BaseDicSubjectService baseDicSubjectService; + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + @Autowired + private RedisUtil redisUtil; + + + // 获取学校学科列表(无缓存) + public List getSchDicSubjectList(Integer schId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schDicSubjectRepository.findAll(spec); + } + + // 获取学校学科列表(带缓存) + public List getSchDicSubjectCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_SUBJECT + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + // 注意:返回副本或不可变列表,避免外部修改影响缓存 + return redisUtil.getList(cacheKey,SchDicSubject.class); + } + // 同步查询数据库,防止缓存击穿 + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey,SchDicSubject.class); + } + List list = getSchDicSubjectList(schId); + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + return list; + } + } + + public List getSchDicSubjectCacheList(Integer schId,Integer schSystemId) + { + if (schSystemId == null) { + return getSchDicSubjectCacheList(schId); // 返回全部 + } + return getSchDicSubjectCacheList(schId).stream() + .filter(s -> schSystemId.equals(s.getSchSystemId())) // 此时 schSystemId 非 null + .collect(Collectors.toList()); + } + + // 获取学校学科列表(包含未启用的基础学科) + public List getSchSubList(Integer schId,Integer schSystemId) { + + // 获取学校已有学科(缓存版本,返回的是副本) + List schDicSubjectList =getSchDicSubjectCacheList(schId,schSystemId); + + // 学校已有学科编码集合 + Set existingCodes = schDicSubjectList.stream() + .map(SchDicSubject::getCode) + .collect(Collectors.toSet()); + + // 获取系统基础学科 + List baseDicSubjectList = baseDicSubjectService.getSysSubjectList(); + + if(baseDicSubjectList.stream() + .anyMatch(sub -> !existingCodes.contains(sub.getCode()))) + { + initialization(baseDicSubjectList,existingCodes,schId,schSystemId); + schDicSubjectList =getSchDicSubjectCacheList(schId,schSystemId); + } + + // 创建新列表,避免修改原始缓存列表 + List result = new ArrayList<>(schDicSubjectList); + + // 根据 sort 字段升序排序,null 值排在最后 + result.sort(Comparator.comparing(SchDicSubject::getSort, + Comparator.nullsLast(Comparator.naturalOrder()))); + + return result; + } + + public void initialization(List baseDicSubjectList,Set existingCodes,Integer schId,Integer schSystemId) + { + Date date=new Date(); + // 需要添加的学科(学校未有的) + List toAdd = baseDicSubjectList.stream() + .filter(sub -> !existingCodes.contains(sub.getCode())) + .map(sub -> { + SchDicSubject schSub = new SchDicSubject(); + schSub.setId(0); // 或 null,取决于数据库策略 + schSub.setCode(sub.getCode()); + schSub.setName(sub.getName()); + schSub.setSchSystemId(schSystemId); + schSub.setEnable(false); + schSub.setSource(Source.SYSTEM.getId()); + schSub.setSort(sub.getSort()); + schSub.setSchId(schId); + schSub.setCreateDate(date); + schSub.setCreateUserId(0); + return schSub; + }) + .collect(Collectors.toList()); + + if(toAdd.size()>0) + { + schDicSubjectRepository.saveAll(toAdd); + String cacheKey = RedisConstants.SCHOOL_SUBJECT + "_" + schId; + redisUtil.del(cacheKey); + } + } + + @OperationLog(module = LogModule.SUBJECT) + @Transactional(rollbackFor = Exception.class) + public void saveSchSub(UserContext.UserInfo user, SchDicSubject entity) { + + Integer schId=user.getSchId(); + entity.setSort(Source.SCHOOL.getId()); + + // 1. 参数校验 + if (entity.getSchSystemId() == null || entity.getSchSystemId() == 0) { + throw new IllegalArgumentException("学制ID不能为空"); + } + if (StringUtils.isBlank(entity.getName())) { + throw new IllegalArgumentException("学科名称不能为空"); + } + SchDicSubject oldEntity = null; + + // 2. 判断新增还是更新 + boolean isNew = (entity.getId() == null || entity.getId() == 0); + + List schDicSubjectList =getSchDicSubjectCacheList(schId,entity.getSchSystemId()); + + // 3. 名称唯一性校验(同一学校 + 同一学制下,学科名称不能重复) + boolean exists; + if (isNew) { + exists = schDicSubjectList != null && schDicSubjectList.stream() + .anyMatch(s -> entity.getName().equals(s.getName())); + } else { + exists = schDicSubjectList != null && schDicSubjectList.stream() + .anyMatch(s -> !s.getId().equals(entity.getId()) && entity.getName().equals(s.getName())); + } + if (exists) { + throw new IllegalArgumentException("该学制下学科名称已存在:" + entity.getName()); + } + + // 4. 设置默认值(新增时) + if (entity.getEnable() == null) + entity.setEnable(true); + + // 5. 执行保存 + if (isNew) { + String newCode = generateUniqueSubjectCode(schId); + entity.setCode(newCode); + OtherUtil.setBaseEntityValue(user, entity); + schDicSubjectRepository.save(entity); + } else { + // 更新:加载现有记录,只复制允许修改的字段 + SchDicSubject existing = schDicSubjectRepository.findById(entity.getId()) + .orElseThrow(() -> new IllegalArgumentException("学科不存在,ID=" + entity.getId())); + + oldEntity=OtherUtil.deepCopy(existing,SchDicSubject.class); + + OtherUtil.setBaseEntityValue(user, entity); + + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.code, + EntityFieldNames.schId, + EntityFieldNames.schSystemId, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + + schDicSubjectRepository.save(existing); + } + + // 6. 清除缓存 + String cacheKey = RedisConstants.SCHOOL_SUBJECT + "_" +schId; + redisUtil.del(cacheKey); + + { + String content = saveSchSubLog(user,entity,isNew,oldEntity); + LogContextHolder.setDescription(content); + } + + } + private String saveSchSubLog(UserContext.UserInfo user, SchDicSubject entity, boolean isNew, SchDicSubject oldEntity) { + try { + Map schsystemMap= schBinSchsystemService.getSchBinSchsystemMap(user.getSchId()); + String schsystemName= schsystemMap.get(entity.getSchSystemId()); + if (isNew) { + String content = String.format("新增学科:%s(学制:%d)", entity.getName(), schsystemName); + return content; + } else { + // 对比旧实体与新实体 + StringBuilder detail = new StringBuilder("更新学科:"); + if (oldEntity != null) { + if (!Objects.equals(oldEntity.getName(), entity.getName())) { + detail.append(String.format("名称从 '%s' 修改为 '%s';", oldEntity.getName(), entity.getName())); + } + if (!Objects.equals(oldEntity.getEnable(), entity.getEnable())) { + detail.append(String.format("启用状态从 %s 修改为 %s;", oldEntity.getEnable(), entity.getEnable())); + } + // 若有其他可修改字段,同样处理 + } else { + // 如果oldEntity为空,直接记录新名称(但更新时一定会有oldEntity) + detail.append(String.format("%s(学制:%d)", entity.getName(), schsystemName)); + } + if (detail.length() == "更新学科:".length()) { + detail.append("无实际变更"); + } + return detail.toString(); + // logService.saveLog(user, MODULE_SUBJECT, detail.toString()); + } + + } catch (Exception e) { + // 使用专门的日志记录器(或直接打印错误) + log.error("保存学科日志失败:user={}, entityId={}", user.getUserId(), entity.getId(), e); + return isNew?"添加学科日志失败":"更新学科日志失败"; + } + + } + + @OperationLog(module = LogModule.SUBJECT) + @Transactional(rollbackFor = Exception.class) + public void schSubSort(UserContext.UserInfo user,List subIds,Integer schSystemId) { + Date date=new Date(); + + // 获取学校已有的学科列表(从数据库查询,不包含临时补充的) + List existingSubjects = getSchSubList(user.getSchId(),schSystemId); // 注意:这个方法返回的是数据库中的实体,不包含临时补充的 + + // 将列表转为 Map,方便按 code 查找 + Map subjectMap = existingSubjects.stream() + .collect(Collectors.toMap(SchDicSubject::getCode, Function.identity())); + + // 遍历传入的排序列表,按顺序设置 sort + int sortOrder = 1; + + for (String code : subIds) { + SchDicSubject subject = subjectMap.get(code); + if (subject != null) { + subject.setSort(sortOrder++); + } + } + + // 对于不在排序列表中的学科,可以设置 sort 为 null 或较大的值(可选) + for (SchDicSubject subject : existingSubjects) { + if (!subIds.contains(subject.getCode())) { + subject.setSort(null); //或设置为 999 + } + if ((subject.getId() == null || subject.getId() == 0)&&subject.getSource().equals(0)) { + subject.setSchId(user.getSchId()); + subject.setCreateDate(date); + subject.setCreateUserId(user.getUserId()); + }else { + subject.setUpdateDate(date); + subject.setUpdateUserId(user.getUserId()); + } + } + // 批量保存 + schDicSubjectRepository.saveAll(existingSubjects); + String cacheKey = RedisConstants.SCHOOL_SUBJECT + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + { + String names = subIds.stream() + .map(id -> { + SchDicSubject m = subjectMap.get(id); + return m != null ? m.getName() : String.valueOf(id); + }) + .collect(Collectors.joining("、")); + String description = String.format("调整学科排序:共 %d 个学科(列表:%s)", subIds.size(), names); + LogContextHolder.setDescription(description); + } + } + + private synchronized String generateUniqueSubjectCode(Integer schId) { + Integer maxNum = schDicSubjectRepository.findMaxSubjectCodeNumber(schId); + int newNum = (maxNum == null) ? 1001 : maxNum + 1; + return "SUB" + newNum; + } + + @OperationLog(module = LogModule.SUBJECT) + @Transactional(rollbackFor = Exception.class) + public void delSchSub(UserContext.UserInfo user,Integer id) { + + SchDicSubject entity = schDicSubjectRepository.findByIdAndSchId(id, user.getSchId()) + .orElseThrow(() -> new DException("学科不存在")); + + Map schsystemMap= schBinSchsystemService.getSchBinSchsystemMap(user.getSchId()); + LogContextHolder.setDescription("删除学科:" + entity.getName() + " 学制:" +schsystemMap.get(entity.getSchSystemId()) + ")"); + + String cacheKey = RedisConstants.SCHOOL_SUBJECT + "_" + user.getSchId(); + redisUtil.del(cacheKey); + + schDicSubjectRepository.deleteById(id); + log.debug("操作人:{},删除学科日志:{}", user.getUserName(), JSON.toJSONString(entity)); + } + + + public List select(Integer schId, Integer schsystemId) { + List list = getSchDicSubjectCacheList(schId, schsystemId); + // 按 code 去重,保留顺序(若需要保持原顺序,可用 LinkedHashSet 包装) + list = list.stream() + .collect(Collectors.collectingAndThen( + Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SchDicSubject::getCode))), + ArrayList::new + )); + return ModelMapperUtil.toSelectStrVOList(list, SchDicSubject::getCode, SchDicSubject::getName); + } + + public Map toIdAndNameMap(Integer schId, Integer schsystemId) + { + List list = getSchDicSubjectCacheList(schId,schsystemId); + return ModelMapperUtil.toMap(list, SchDicSubject::getCode, SchDicSubject::getName); + } +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchInfoService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchInfoService.java new file mode 100644 index 0000000..31613ea --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchInfoService.java @@ -0,0 +1,106 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.SchInfoRepository; +import com.bestsch.bschclassmanage.entity.SchInfo; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.model.vo.oa.SchInfoVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchInfoService; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class SchInfoService implements ISchInfoService { + + @Autowired + private SchInfoRepository schInfoRepository; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private RedisUtil redisUtil; + + public List getSchList(){ + return schInfoRepository.findAll(); + } + + public List getSchVOList(String SchIDArr) { + List schlist = getSchList(); + List schlist2 = comSchTreeService.getSchoolList(); + + // 将 schlist 转换为 Map,以 schId 为 key,方便查找 + Map schInfoMap = schlist.stream() + .collect(Collectors.toMap(SchInfo::getSchId, Function.identity())); + + // 1. 构建完整的 SchInfoVO 列表(包括可能无 schSerId 的项) + List schInfoVOList = schlist2.stream() + .map(select -> { + SchInfo schInfo = schInfoMap.get(select.getId()); + if (schInfo == null) { + // 如果没匹配到,仍然返回一个只有 userSchSerId 和 schName 的对象 + // (但后续过滤时可能会被排除,取决于是否需要) + return SchInfoVO.builder() + .userSchSerId(select.getId()) + .schName(select.getName()) + .build(); + } + return SchInfoVO.builder() + .schSerId(schInfo.getSchSerId()) + .userSchSerId(select.getId()) + .schName(select.getName()) + .build(); + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + // 2. 如果传入了 SchIDArr,则根据 schSerId 过滤 + if (StringUtils.isNotBlank(SchIDArr)) { + // 将逗号分隔的字符串转为小写列表(忽略大小写匹配) + List targetSchSerIds = Arrays.stream(SchIDArr.split(",")) + .map(String::trim) + .map(s -> s.toLowerCase(Locale.ROOT)) // 统一转为小写 + .collect(Collectors.toList()); + + schInfoVOList = schInfoVOList.stream() + .filter(vo -> { + // 如果 vo 的 schSerId 为 null,则不过滤(保留?)根据业务决定,建议过滤掉 + if (vo.getSchSerId() == null) { + return false; // 或者根据需求决定 + } + // 将当前 schSerId 转小写后判断是否在目标列表中 + return targetSchSerIds.contains(vo.getSchSerId().toLowerCase(Locale.ROOT)); + }) + .collect(Collectors.toList()); + } + + return schInfoVOList; + } + + public SchInfoVO GetSchFirst(String SchID) { + return schInfoRepository.findBySchSerId(SchID) + .map(schInfo -> SchInfoVO.builder() + .userSchSerId(schInfo.getId()) + .schSerId(schInfo.getSchSerId()) + .schName(schInfo.getName()) + .build()) + .orElse(null); // 如果不存在返回 null + } + + public SchInfoVO GetSchFirst(Integer schId) { + return schInfoRepository.findBySchId(schId) + .map(schInfo -> SchInfoVO.builder() + .userSchSerId(schInfo.getId()) + .schSerId(schInfo.getSchSerId()) + .schName(schInfo.getName()) + .build()) + .orElse(null); // 如果不存在返回 null + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchStudentService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchStudentService.java new file mode 100644 index 0000000..f0664ca --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchStudentService.java @@ -0,0 +1,143 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.dto.StuAbnormalStatusDTO; +import com.bestsch.bschclassmanage.model.dto.StuTransferClassDTO; +import com.bestsch.bschclassmanage.model.vo.PageVO; +import com.bestsch.bschclassmanage.model.vo.SchStudentVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.ISchStudentService; +import com.bestsch.bschclassmanage.service.impl.student.*; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 学生服务门面(对外接口实现) + * 职责:实现 ISchStudentService,委托给各子服务 + */ +@Slf4j +@Service +public class SchStudentService implements ISchStudentService { + + // ==================== 子服务 ==================== + @Autowired + private SchStudentCacheService cacheService; + + @Autowired + private SchStudentQueryService queryService; + + @Autowired + private SchStudentInfoService infoService; + + @Autowired + private SchStudentStatusService statusService; + + @Autowired + private SchStudentTransferService transferService; + + @Autowired + private SchStudentImportService importService; + + // ==================== 查询方法(委托) ==================== + + @Override + public List getSchGradeClassStudentCacheList(Integer schId, Integer schsystemId, Integer gradeId, Integer classId) { + return cacheService.getSchGradeClassStudentCacheList(schId, schsystemId, gradeId, classId); + } + + @Override + public PageVO searchBaseSchStudentVO(Integer schId, Integer schsystemId, Integer gradeId, Integer classId, + String keyword, boolean abnormalStatus_NORMAL, Pageable pageable) { + return queryService.searchBaseSchStudentVO(schId, schsystemId, gradeId, classId, keyword, abnormalStatus_NORMAL, pageable); + } + + @Override + public PageVO searchHigherSchStudentVO(Integer schId, Integer gradeId, Integer classId, + String keyword, boolean abnormalStatus_NORMAL, Pageable pageable) { + return queryService.searchHigherSchStudentVO(schId, gradeId, classId, keyword, abnormalStatus_NORMAL, pageable); + } + + @Override + public PageVO searchTransferOutStudent(Integer schId, Integer gradeId, Integer classId, + String keyword, Pageable pageable) { + return queryService.searchTransferOutStudent(schId, gradeId, classId, keyword, pageable); + } + + @Override + public List searchSchClassStudentVO(Integer schId, Integer gradeId, Integer classId, boolean onlyNormal){ + return queryService.searchSchClassStudentVO(schId, gradeId, classId, null, onlyNormal,null); + } + + @Override + public List transferOutSchSelect() { + return queryService.transferOutSchSelect(); + } + + // ==================== 写操作(事务 + 日志) ==================== + + @OperationLog(module = LogModule.STUDENT) + @Transactional(rollbackFor = Exception.class) + @Override + public void saveStudent(UserContext.UserInfo user, SchStudentVO entityVO) { + infoService.saveStudent(user, entityVO); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void deleteStudent(UserContext.UserInfo user, String ids) { + infoService.deleteStudent(user, ids); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void transferClass(UserContext.UserInfo user, StuTransferClassDTO model) { + transferService.transferClass(user, model); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void setAbnormalStatus(UserContext.UserInfo user, StuAbnormalStatusDTO model) { + statusService.setAbnormalStatus(user, model); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void setTransferOut(UserContext.UserInfo user, String ids) { + transferService.setTransferOut(user, ids); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void setTransferIn(UserContext.UserInfo user, StuTransferClassDTO model) { + transferService.setTransferIn(user, model); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void importStudents(UserContext.UserInfo user, MultipartFile file) { + importService.importStudents(user, file); + } + + @Override + public void studentClassNoTemplate(HttpServletResponse response, Integer schId, Integer systemId, Integer gradeId, Integer classId) { + importService.studentClassNoTemplate(response,schId,systemId,gradeId,classId); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void importStudentClassNo(UserContext.UserInfo user, MultipartFile file, Integer schsystemId, Integer gradeId,Integer classId) { + importService.importStudentClassNo(user, file, schsystemId, gradeId,classId); + } + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/SchTeacherService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchTeacherService.java new file mode 100644 index 0000000..dcd089b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/SchTeacherService.java @@ -0,0 +1,327 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.annotation.OperationLog; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.dto.SchTeacherDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferGroupDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferInGroupDTO; +import com.bestsch.bschclassmanage.model.tool.BaseTree; +import com.bestsch.bschclassmanage.model.vo.*; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.service.impl.teacher.*; +import com.bestsch.bschclassmanage.utils.ModelMapperUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 教师服务门面(对外接口实现) + * 职责:实现 ISchTeacherService,委托给各子服务 + */ +@Slf4j +@Service +public class SchTeacherService implements ISchTeacherService { + + // ==================== 子服务 ==================== + @Autowired + private SchTeacherCacheService cacheService; + + @Autowired + private SchTeacherInfoService infoService; + + @Autowired + private SchTeacherRelationService relationService; + + @Autowired + private SchTeacherImportService importService; + + // ==================== 必备 Repository(用于查询) ==================== + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private IComSchTreeService comSchTreeService; + + + // ==================== 查询方法 ==================== + + @Override + public List getSchTeacherList(Integer schId) { + return cacheService.getSchTeacherList(schId); + } + + @Override + public List getSchTeacherCacheList(Integer schId) { + return cacheService.getSchTeacherCacheList(schId); + } + + @Override + public PageVO searchSchTeacher(Integer schId, Integer groupId, String keyword, Pageable pageable) { + if (!pageable.getSort().isSorted()) { + Sort defaultSort = Sort.by(Sort.Order.asc("name"), Sort.Order.asc("tea_id")); + pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), defaultSort); + } + + Page page = schTeacherRepository.searchTeachersBySchIdAndGroupId(schId, groupId, keyword, pageable); + + if (page.isEmpty()) { + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), 0, Collections.emptyList()); + } + + List teaIds = page.getContent().stream() + .map(SchTeacher::getTeaId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + List groupRelations = schTeacherGroupRepository.findByTeaIdIn(teaIds); + Map> groupMap = groupRelations.stream() + .collect(Collectors.groupingBy(SchTeacherGroup::getTeaId)); + + List voList = page.getContent().stream() + .map(entity -> { + SchTeacherVO vo = new SchTeacherVO(); + BeanUtils.copyProperties(entity, vo); + vo.setStatusName(UserStatus.nameById(entity.getStatus())); + + List groups = groupMap.getOrDefault(entity.getTeaId(), Collections.emptyList()); + List groupSelectList = groups.stream() + .map(g -> { + SelectIntVO select = new SelectIntVO(); + select.setId(g.getGroupId()); + String groupName = comSchTreeService.getTeaGroupName(schId, g.getGroupId()); + select.setName(groupName); + return select; + }) + .collect(Collectors.toList()); + + if (groupId != null && groupId > 0) { + groupSelectList = groupSelectList.stream() + .filter(s -> s.getId().equals(groupId)) + .collect(Collectors.toList()); + } + vo.setGroupList(groupSelectList); + return vo; + }) + .collect(Collectors.toList()); + + return new PageVO<>( + pageable.getPageNumber() + 1, + pageable.getPageSize(), + page.getTotalElements(), + voList + ); + } + + @Override + public PageVO searchTransferOutTeacher(Integer schId, Integer groupId, String keyword, Pageable pageable) { + if (!pageable.getSort().isSorted()) { + Sort defaultSort = Sort.by(Sort.Order.asc("teaName")); + pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), defaultSort); + } + + Page page = schTeacherRepository.searchTransferredOutTeachers(schId, groupId, keyword, pageable); + + if (page.isEmpty()) { + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), 0, Collections.emptyList()); + } + + List teaIds = page.getContent().stream() + .map(TeacherSchVO::getTeaId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + List groupRelations = schTeacherGroupRepository.findByTeaIdIn(teaIds); + Map> groupMap = groupRelations.stream() + .collect(Collectors.groupingBy(SchTeacherGroup::getTeaId)); + + List voList = page.getContent().stream() + .map(entity -> { + SchTeacherTOutVO vo = new SchTeacherTOutVO(); + BeanUtils.copyProperties(entity, vo); + + List groupIds = groupMap.getOrDefault(entity.getTeaId(), Collections.emptyList()) + .stream() + .filter(s -> s.getSchId().equals(entity.getSchId())) + .map(SchTeacherGroup::getGroupId) + .distinct() + .collect(Collectors.toList()); + + List groupNames = groupIds.stream() + .map(s -> comSchTreeService.getTeaGroupName(entity.getSchId(), s)) + .collect(Collectors.toList()); + vo.setGroupNames(String.join(",", groupNames)); + vo.setName(entity.getTeaName()); + vo.setSchName(comSchTreeService.getSchoolName(entity.getSchId())); + return vo; + }) + .collect(Collectors.toList()); + + return new PageVO<>( + pageable.getPageNumber() + 1, + pageable.getPageSize(), + page.getTotalElements(), + voList + ); + } + + + @Override + public Map toIdAndNameMap(Integer schId) { + List list = getSchTeacherCacheList(schId); + return ModelMapperUtil.toMap(list, SchTeacher::getTeaId, SchTeacher::getName); + } + + @Override + public List toIdAndNameSelect(Integer groupId, Integer schId) { + List teaIdsInSchool = schTeacherGroupRepository.findTeaIdsBySchId(schId); + if (teaIdsInSchool.isEmpty()) { + return Collections.emptyList(); + } + + List filteredTeaIds; + if (groupId != null && groupId > 0) { + List groupRelations = schTeacherGroupRepository.findByGroupIdAndSchId(groupId, schId); + filteredTeaIds = groupRelations.stream() + .map(SchTeacherGroup::getTeaId) + .distinct() + .collect(Collectors.toList()); + filteredTeaIds.retainAll(teaIdsInSchool); + } else { + filteredTeaIds = teaIdsInSchool; + } + + if (filteredTeaIds.isEmpty()) { + return Collections.emptyList(); + } + + List teachers = schTeacherRepository.findByTeaIdIn(filteredTeaIds); + if (teachers.isEmpty()) { + return Collections.emptyList(); + } + + return teachers.stream() + .map(t -> { + SelectIntVO vo = new SelectIntVO(); + vo.setId(t.getTeaId()); + vo.setName(t.getName()); + return vo; + }) + .collect(Collectors.toList()); + } + + @Override + public List transferOutSchSelect() { + List schIds = schTeacherGroupRepository.findSchoolIdsByTransferOut(); + return comSchTreeService.getSchoolList().stream() + .filter(s -> schIds.contains(s.getId())) + .collect(Collectors.toList()); + } + + @Override + public List toTeacherGroupSelect(Integer schId) { + List groupIds = schTeacherGroupRepository.findGroupIdsBySchId(schId); + if (groupIds.isEmpty()) { + return Collections.emptyList(); + } + + BaseTree teacherGroupTree = comSchTreeService.getTeaTree(schId); + if (teacherGroupTree == null) { + return Collections.emptyList(); + } + + List allNodes = flattenTree(teacherGroupTree); + + return allNodes.stream() + .filter(node -> groupIds.contains(node.getId())) + .map(node -> { + SelectIntVO vo = new SelectIntVO(); + vo.setId(node.getId()); + vo.setName(node.getName()); + return vo; + }) + .collect(Collectors.toList()); + } + + // ==================== 写操作(委托给子服务) ==================== + + @OperationLog(module = LogModule.TEACHER) + @Transactional(rollbackFor = Exception.class) + @Override + public void saveTeacher(UserContext.UserInfo user, SchTeacherDTO dto) { + infoService.saveTeacher(user, dto); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteTeacher(UserContext.UserInfo user, String ids) { + infoService.deleteTeacher(user, ids); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void setTeacherStatus(UserContext.UserInfo user, String ids, Integer status) { + infoService.setTeacherStatus(user, ids, status); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void setTransferOut(UserContext.UserInfo user, String ids) { + relationService.setTransferOut(user, ids); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void setTransferIn(UserContext.UserInfo user, TeaTransferInGroupDTO model) { + relationService.setTransferIn(user, model); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void moveGroup(UserContext.UserInfo user, TeaTransferGroupDTO model) { + relationService.moveGroup(user, model); + } + + @Transactional(rollbackFor = Exception.class) + public void importTeachers(UserContext.UserInfo user, MultipartFile file) { + importService.importTeachers(user, file); + } + + // ==================== 私有辅助方法 ==================== + + /** + * 递归扁平化树,返回所有节点列表(包括根节点) + */ + private List flattenTree(BaseTree root) { + List result = new ArrayList<>(); + if (root == null) { + return result; + } + result.add(root); + if (root.getChildren() != null) { + for (BaseTree child : root.getChildren()) { + result.addAll(flattenTree(child)); + } + } + return result; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/StudentClassHistoryService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/StudentClassHistoryService.java new file mode 100644 index 0000000..5339cbf --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/StudentClassHistoryService.java @@ -0,0 +1,63 @@ +package com.bestsch.bschclassmanage.service.impl; + +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.vo.HistorySchClassVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.ModelMapperUtil; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import com.yunhai.platform.utils.exception.DException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; +import java.util.Optional; + +@Service +public class StudentClassHistoryService implements IStudentClassHistoryService { + + @Autowired + private ISchClassService schClassService; + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchDicDivisionService schDicDivisionService; + + @Autowired + private ISchDicMajorsService schDicMajorsService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private RedisUtil redisUtil; + + + public HistorySchClassVO GetClassFirst(Integer schId, Integer gradeId, Integer classId) { + + Optional classInfo= schClassService.getSchClassCacheFilter(schId,gradeId,classId).stream().findFirst(); + if(!classInfo.isPresent()) throw new DException("班级未找到!"); + HistorySchClassVO vo = ModelMapperUtil.map(classInfo.get(), HistorySchClassVO.class); + vo.setSchType(schBinSchsystemService.getSchType(schId)); + if(vo.getSchType().equals(SchType.VOCATIONALEDUCATION.getKey())){ + Map majorssNameMap = schDicMajorsService.toIdAndNameMap(schId); + vo.setMajorsName(majorssNameMap.get(vo.getMajorsId())); + vo.setGradeName(vo.getGradeId()+"级"); + }else { + Integer schsystemId= baseSchsystemGradeService.getSchsystemIdByGradeId(schId,gradeId); + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, vo.getGradeId()); + vo.setGradeName(gradeNameMap.get(vo.getGradeId())); + } + return vo; + } + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassCacheService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassCacheService.java new file mode 100644 index 0000000..7d7d04b --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassCacheService.java @@ -0,0 +1,114 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.Predicate; +import java.util.*; + +@Slf4j +@Service +public class SchClassCacheService { + +// @Autowired +// private SchClassQueryService queryService; + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private RedisUtil redisUtil; + + // ---------- 基础查询(直接 DB) ---------- + public List getSchClassList(Integer schId,Boolean graduate) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + + if(graduate!=null){ + predicates.add(cb.equal(root.get(EntityFieldNames.graduate), graduate)); + } + + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schClassRepository.findAll(spec); + } + + /** + * 获取学校所有班级(带缓存)(不含毕业班级) + */ + public List getSchClassCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_CLASS + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchClass.class); + } + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchClass.class); + } + List list = getSchClassList(schId,false); + Comparator comparator = Comparator + .comparing(SchClass::getGradeId, Comparator.nullsLast(Integer::compareTo)) + .thenComparing(SchClass::getSort, Comparator.nullsLast(Integer::compareTo)); + list.sort(comparator); + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_1H); + return list; + } + } + + /** + * 获取学校所有班级(带缓存)(不含毕业班级) + */ + public List getSchGradeateClassCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_CLASS + "_gradeate_" + schId; + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchClass.class); + } + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchClass.class); + } + List list = getSchClassList(schId,true); + Comparator comparator = Comparator + .comparing(SchClass::getGradeId, Comparator.nullsLast(Integer::compareTo)) + .thenComparing(SchClass::getSort, Comparator.nullsLast(Integer::compareTo)); + list.sort(comparator); + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_1H); + return list; + } + } + + /** + * 获取学校所有班级(带缓存)(含毕业班级) + */ + public List getSchAllClassCacheList(Integer schId) { + List list = getSchClassCacheList(schId); + list.addAll(getSchGradeateClassCacheList(schId)); + return list; + } + + + /** + * 清除学校班级缓存 + */ + public void clearClassCache(Integer schId) { + if (schId == null) return; + String cacheKey = RedisConstants.SCHOOL_CLASS + "_" + schId; + redisUtil.del(cacheKey); + log.debug("清除班级缓存:schId={}", schId); + } + + public void clearGradeateClassCache(Integer schId) { + if (schId == null) return; + String cacheKey = RedisConstants.SCHOOL_CLASS + "_gradeate_" + schId; + redisUtil.del(cacheKey); + log.debug("清除班级缓存:schId={}", schId); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassHigherService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassHigherService.java new file mode 100644 index 0000000..c5313fa --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassHigherService.java @@ -0,0 +1,137 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchClassHigherService { + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private SchClassCacheService cacheService; + + @Autowired + private SchClassLogService logService; + + public void saveHigherSchClass(UserContext.UserInfo user, SchClass entity) { + Integer schId = user.getSchId(); + Integer schType = schBinSchsystemService.getSchType(schId); + if (!schType.equals(SchType.VOCATIONALEDUCATION.getKey())) { + throw new IllegalArgumentException("学校类型不符合,请重新选择学制!"); + } + Integer schsystemId = schBinSchsystemService.getSchBinSchsystemIds(schId).stream().findFirst() + .orElseThrow(() -> new DException("请选择学制!")); + + if (entity.getEnrollYear() == null) { + throw new IllegalArgumentException("请选择年份(级)!"); + } + if (StringUtils.isBlank(entity.getName())) { + throw new IllegalArgumentException("班级名称不能为空"); + } + + boolean isNew = (entity.getId() == null || entity.getId() == 0); + if (isNew) { + boolean exists = schClassRepository.existsBySchIdAndGroupIdAndName(schId, entity.getGroupId(), entity.getName()); + if (exists) { + throw new IllegalArgumentException("该年级组下班级名称已存在:" + entity.getName()); + } + } else { + boolean exists = schClassRepository.existsBySchIdAndGroupIdAndNameAndIdNot(schId, entity.getGroupId(), entity.getName(), entity.getId()); + if (exists) { + throw new IllegalArgumentException("该年级组下班级名称已存在:" + entity.getName()); + } + } + + OtherUtil.setBaseEntityValue(user, entity); + entity.setGradeId(entity.getEnrollYear()); + + SchClass oldSchClass = null; + if (isNew) { + // 同步组ID + List gradeGroupList = comSchTreeService.getSchGroupTypeList(schId, NodeType.GRADE.getId()).get(schsystemId); + if (gradeGroupList == null || gradeGroupList.isEmpty()) { + throw new IllegalArgumentException("该学制下没有年级组,请先同步年级组数据!"); + } + Map gradeNameToIdMap = gradeGroupList.stream() + .collect(Collectors.toMap(SelectIntVO::getName, SelectIntVO::getId, (a, b) -> a)); + List classGroupList = comSchTreeService.getSchGroupTypeList(schId, NodeType.CLASS.getId()).get(schsystemId); + Map classNameToIdMap = new HashMap<>(); + if (classGroupList != null && !classGroupList.isEmpty()) { + classNameToIdMap = classGroupList.stream() + .collect(Collectors.toMap(SelectIntVO::getName, SelectIntVO::getId, (a, b) -> a)); + } + + Integer groupId = gradeNameToIdMap.get(entity.getEnrollYear().toString()); + if (groupId == null || groupId < 1) { + throw new IllegalArgumentException(entity.getEnrollYear() + "该年级组不存在,请检查年级组名称!"); + } + entity.setGroupId(groupId); + + Integer classId = classNameToIdMap.get(entity.getName()); + if (classId == null || classId < 1) { + throw new IllegalArgumentException("同步班级组失败,请检查班级组数据!"); + } + entity.setClassId(classId); + entity.setGraduate(false); + schClassRepository.save(entity); + } else { + final Integer entityId = entity.getId(); + SchClass existing = schClassRepository.findById(entityId) + .orElseThrow(() -> new IllegalArgumentException("班级不存在,ID=" + entityId)); + oldSchClass = OtherUtil.deepCopy(existing, SchClass.class); + + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.groupId, + EntityFieldNames.createDate, + EntityFieldNames.createUserId, + EntityFieldNames.gradeId, + EntityFieldNames.classId, + EntityFieldNames.graduate, + EntityFieldNames.enrollYear); + schClassRepository.save(existing); + entity = existing; + } + + cacheService.clearClassCache(schId); + + String content = logService.buildSaveHigherClassLog(user, entity, isNew, oldSchClass); + LogContextHolder.setDescription(content); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassImportService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassImportService.java new file mode 100644 index 0000000..d3dd77e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassImportService.java @@ -0,0 +1,377 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.model.excel.ErrorExcelColumn; +import com.bestsch.bschclassmanage.model.excel.SchClassExcelColumn; +import com.bestsch.bschclassmanage.model.excel.SchHeightClassExcelColumn; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.bestsch.bschclassmanage.utils.ValidationUtil; +import com.yunhai.platform.utils.exception.DException; +import com.yunhai.platform.utils.exception.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchClassImportService { + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private SchClassCacheService cacheService; + + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchDicDivisionService schDicDivisionService; + + @Autowired + private ISchDicMajorsService schDicMajorsService; + + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private SchClassLogService logService; + + + public void importClasses(UserContext.UserInfo user, MultipartFile file) { + List errorMsgArr = new ArrayList<>(); + ImportParams params = new ImportParams(); + params.setTitleRows(1); + params.setHeadRows(1); + Date now = new Date(); + + Map> schGradeGroupMap = comSchTreeService.getSchGroupTypeList(user.getSchId(), NodeType.GRADE.getId()); + if (schGradeGroupMap.isEmpty()) { + throw new IllegalArgumentException("该学制下没有年级组,请先同步年级组数据!"); + } + Map> schClassGroupMap = comSchTreeService.getSchGroupTypeList(user.getSchId(), NodeType.CLASS.getId()); + + try (InputStream is = file.getInputStream()) { + List schTeacherList = schTeacherService.getSchTeacherList(user.getSchId()); + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), null, null); + List schClassList = cacheService.getSchClassCacheList(user.getSchId()); + + List list; + try { + list = ExcelImportUtil.importExcel(is, SchClassExcelColumn.class, params); + } catch (Exception e) { + log.error("Excel解析失败", e); + throw new DException("Excel 数据格式有误,请检查所有单元格类型是否正确。错误详情:" + e.getMessage()); + } + if (list == null || list.isEmpty()) { + throw new DException("上传的 Excel 中没有有效数据行,请检查后重新上传!"); + } + + List saveClassList = new ArrayList<>(); + int currentRow = params.getTitleRows() + params.getHeadRows() + 1; + for (SchClassExcelColumn item : list) { + SchClass clazz = new SchClass(); + // 年级 + Optional gradeIdOpt = gradeList.stream() + .filter(vo -> vo.getName().equals(item.getGradeName())) + .map(SelectIntVO::getId) + .findFirst(); + if (!gradeIdOpt.isPresent()) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), SchClassExcelColumn.GRADE_NAME + "不存在!")); + continue; + } + Integer gradeId = gradeIdOpt.get(); + clazz.setGradeId(gradeId); + + Integer schsystemId = baseSchsystemGradeService.getSchsystemIdByGradeId(user.getSchId(), gradeId); + Map nowYearGradeMap = baseSchsystemGradeService.getNowYearGradeMap(user.getSchId(), schsystemId); + List gradeGroupList = schGradeGroupMap.get(schsystemId); + List classGroupList = schClassGroupMap.get(schsystemId); + + Integer year = nowYearGradeMap.get(gradeId); + Integer sort = OtherUtil.extractClassNumber(item.getClazzName()); + String clazzName = sort + "班"; + + Optional classOpt = schClassList.stream() + .filter(vo -> vo.getGradeId().equals(gradeId) && vo.getName().equals(clazzName)) + .findFirst(); + if (classOpt.isPresent()) { + BeanUtils.copyProperties(classOpt.get(), clazz); + clazz.setUpdateDate(now); + clazz.setUpdateUserId(user.getUserId()); + } else { + if (sort <= 0) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), SchClassExcelColumn.CLAZZ_NAME + "格式不正确!")); + continue; + } + clazz.setCreateDate(now); + clazz.setCreateUserId(user.getUserId()); + clazz.setSchId(user.getSchId()); + clazz.setSort(sort); + String code = year.toString() + String.format("%02d", sort); + clazz.setCode(code); + clazz.setName(clazzName); + clazz.setGraduate(false); + clazz.setEnrollYear(year); + clazz.setGroupId(0); + clazz.setClassId(0); + + Map gradeNameToIdMap = gradeGroupList.stream() + .collect(Collectors.toMap(SelectIntVO::getName, SelectIntVO::getId, (a, b) -> a)); + Map classNameToIdMap = classGroupList.stream() + .collect(Collectors.toMap(SelectIntVO::getName, SelectIntVO::getId, (a, b) -> a)); + clazz.setGroupId(gradeNameToIdMap.getOrDefault(year.toString(), 0)); + clazz.setClassId(classNameToIdMap.getOrDefault(clazz.getCode(), 0)); + } + + clazz.setCname(item.getClazzCName()); + + // 班主任 + if (StringUtils.isNotBlank(item.getBzr())) { + Optional teacherOpt = schTeacherList.stream() + .filter(s -> s.getName().equals(item.getBzr())).findFirst(); + if (teacherOpt.isPresent()) { + clazz.setFirstTeacherId(teacherOpt.get().getTeaId()); + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getBzr(), SchClassExcelColumn.BZR + "未找到教师!")); + continue; + } + } else { + clazz.setFirstTeacherId(null); + } + // 副班主任 + if (StringUtils.isNotBlank(item.getFbzr())) { + Optional teacherOpt = schTeacherList.stream() + .filter(s -> s.getName().equals(item.getFbzr())).findFirst(); + if (teacherOpt.isPresent()) { + clazz.setSecondTeacherId(teacherOpt.get().getTeaId()); + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getFbzr(), SchClassExcelColumn.FBZR + "未找到教师!")); + continue; + } + } else { + clazz.setSecondTeacherId(null); + } + + List validateMsgs = ValidationUtil.validateMsgs(clazz); + if (validateMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, "错误", String.join(",", validateMsgs))); + continue; + } + saveClassList.add(clazz); + currentRow++; + } + + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + saveClassList = schClassRepository.saveAll(saveClassList); + for (SchClass clazz : saveClassList) { + if (clazz.getClassId().equals(0)) { + clazz.setClassId(clazz.getId()); + } + } + schClassRepository.saveAll(saveClassList); + cacheService.clearClassCache(user.getSchId()); + logService.importLogs(user, saveClassList); + + } catch (DException e) { + throw e; + } catch (Exception e) { + log.error("导入班级时发生系统异常,操作人:" + user.getUserName(), e); + throw new DException(ErrorCode.CUSTOM,"导入失败,请联系管理员",null,e); + } + } + + + public void importHeightClasses(UserContext.UserInfo user, MultipartFile file) { + List errorMsgArr = new ArrayList<>(); + ImportParams params = new ImportParams(); + params.setTitleRows(1); + params.setHeadRows(1); + Date now = new Date(); + + Map> schGradeGroupMap = comSchTreeService.getSchGroupTypeList(user.getSchId(), NodeType.GRADE.getId()); + if (schGradeGroupMap.isEmpty()) { + throw new IllegalArgumentException("该学制下没有学级,请先同步年级组数据!"); + } + //Map> schClassGroupMap = comSchTreeService.getSchGroupTypeList(user.getSchId(), NodeType.CLASS.getId()); + + try (InputStream is = file.getInputStream()) { + List schTeacherList = schTeacherService.getSchTeacherList(user.getSchId()); + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), null, null); + List schClassList = cacheService.getSchClassCacheList(user.getSchId()); + + Map campusToIdMap = schDicCampusService.toIdAndNameMap(user.getSchId()).entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, (a, b) -> a)); + + Map divisionToIdMap = schDicDivisionService.toIdAndNameMap(user.getSchId()).entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, (a, b) -> a)); + + Map majorsToIdMap = schDicMajorsService.toIdAndNameMap(user.getSchId()).entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey, (a, b) -> a)); + + List list; + try { + list = ExcelImportUtil.importExcel(is, SchHeightClassExcelColumn.class, params); + } catch (Exception e) { + log.error("Excel解析失败", e); + throw new DException("Excel 数据格式有误,请检查所有单元格类型是否正确。错误详情:" + e.getMessage()); + } + if (list == null || list.isEmpty()) { + throw new DException("上传的 Excel 中没有有效数据行,请检查后重新上传!"); + } + + List saveClassList = new ArrayList<>(); + int currentRow = params.getTitleRows() + params.getHeadRows() + 1; + for (SchHeightClassExcelColumn item : list) { + SchClass clazz = new SchClass(); + // 年级 + Optional gradeIdOpt = gradeList.stream() + .filter(vo -> vo.getName().equals(item.getGradeName())) + .map(SelectIntVO::getId) + .findFirst(); + if (!gradeIdOpt.isPresent()) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), SchHeightClassExcelColumn.GRADE_NAME + "不存在!")); + continue; + } + Integer gradeId = gradeIdOpt.get(); + clazz.setGradeId(gradeId); + + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(user.getSchId(), gradeId); + List gradeGroupList = schGradeGroupMap.get(schsystemId); + + Optional gradeGroupOpt= gradeGroupList.stream().filter(s->s.getName().equals(gradeId.toString())).findFirst(); + if(gradeGroupOpt.isPresent()) + { + clazz.setGroupId(gradeGroupOpt.get().getId()); + }else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), "年级组不存在!")); + continue; + } + + clazz.setName(item.getClazzName()); + clazz.setCname(item.getClazzCName()); + Optional classOpt = schClassList.stream() + .filter(vo -> vo.getGradeId().equals(gradeId) && vo.getName().equals(clazz.getName())) + .findFirst(); + + + + if (classOpt.isPresent()) { + BeanUtils.copyProperties(classOpt.get(), clazz); + clazz.setUpdateDate(now); + clazz.setUpdateUserId(user.getUserId()); + } else { + clazz.setCreateDate(now); + clazz.setCreateUserId(user.getUserId()); + clazz.setSchId(user.getSchId()); + clazz.setCode(item.getClazzCode()); + clazz.setGraduate(false); + clazz.setEnrollYear(gradeId); + clazz.setGroupId(0); + clazz.setClassId(0); + } + + clazz.setCname(item.getClazzCName()); + + if(StringUtils.isNotBlank(item.getCampus())){ + + if(campusToIdMap.get(item.getCampus())==null) + { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getCampus(), SchHeightClassExcelColumn.CAMPUS + "不存在!")); + continue; + } + clazz.setCampusId(campusToIdMap.get(item.getCampus())); + } + { + if(divisionToIdMap.get(item.getDivistion())==null) + { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getDivistion(), SchHeightClassExcelColumn.DIVISION + "不存在!")); + continue; + } + clazz.setDivisionId(divisionToIdMap.get(item.getDivistion())); + } + { + if(majorsToIdMap.get(item.getMajors())==null) + { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getMajors(), SchHeightClassExcelColumn.MAJORS + "不存在!")); + continue; + } + clazz.setMajorsId(majorsToIdMap.get(item.getMajors())); + } + + // 班主任 + if (StringUtils.isNotBlank(item.getBzr())) { + Optional teacherOpt = schTeacherList.stream() + .filter(s -> s.getName().equals(item.getBzr())).findFirst(); + if (teacherOpt.isPresent()) { + clazz.setFirstTeacherId(teacherOpt.get().getTeaId()); + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getBzr(), SchClassExcelColumn.BZR + "未找到教师!")); + continue; + } + } else { + clazz.setFirstTeacherId(null); + } + + List validateMsgs = ValidationUtil.validateMsgs(clazz); + if (validateMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, "错误", String.join(",", validateMsgs))); + continue; + } + saveClassList.add(clazz); + currentRow++; + } + + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + saveClassList = schClassRepository.saveAll(saveClassList); + for (SchClass clazz : saveClassList) { + if (clazz.getClassId().equals(0)) { + clazz.setClassId(clazz.getId()); + } + } + schClassRepository.saveAll(saveClassList); + cacheService.clearClassCache(user.getSchId()); + logService.importLogs(user, saveClassList); + + } catch (DException e) { + throw e; + } catch (Exception e) { + log.error("导入班级时发生系统异常,操作人:" + user.getUserName(), e); + throw new DException(ErrorCode.CUSTOM,"导入失败,请联系管理员",null,e); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassInfoService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassInfoService.java new file mode 100644 index 0000000..2998ad0 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassInfoService.java @@ -0,0 +1,193 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchClassInfoService { + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private SchClassCacheService cacheService; + + @Autowired + private SchClassQueryService queryService; + + @Autowired + private SchClassLogService logService; + + // ---------- 新增 K12 班级 ---------- + public void addBaseSchClass(UserContext.UserInfo user, Integer gradeId, Integer number) { + if (gradeId == null || gradeId == 0) throw new IllegalArgumentException("年级ID不能为空"); + if (number == null || number <= 0) throw new IllegalArgumentException("新增班级数量必须大于0"); + + Integer schId = user.getSchId(); + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(schId, gradeId); + + // 获取当前最大排序 + Integer maxSort = schClassRepository.findMaxCodeNumber(gradeId, schId); + int startSort = (maxSort == null) ? 1 : maxSort + 1; + + Map nowYearGradeMap = baseSchsystemGradeService.getNowYearGradeMap(schId, schsystemId); + Integer year = nowYearGradeMap.get(gradeId); + + List gradeGroupList = comSchTreeService.getSchGroupTypeList(schId, NodeType.GRADE.getId()).get(schsystemId); + if (gradeGroupList == null || gradeGroupList.isEmpty()) { + throw new IllegalArgumentException("该学制下没有年级组,请先同步年级组数据!"); + } + Map gradeNameToIdMap = gradeGroupList.stream() + .collect(Collectors.toMap(SelectIntVO::getName, SelectIntVO::getId, (a, b) -> a)); + + List classGroupList = comSchTreeService.getSchGroupTypeList(schId, NodeType.CLASS.getId()).get(schsystemId); + Map classNameToIdMap = new HashMap<>(); + if (classGroupList != null && !classGroupList.isEmpty()) { + classNameToIdMap = classGroupList.stream() + .collect(Collectors.toMap(SelectIntVO::getName, SelectIntVO::getId, (a, b) -> a)); + } + + List schClassList = new ArrayList<>(number); + for (int i = 0; i < number; i++) { + int sort = startSort + i; + SchClass clazz = new SchClass(); + clazz.setSchId(schId); + clazz.setGradeId(gradeId); + clazz.setSort(sort); + String code = year.toString() + String.format("%02d", sort); + clazz.setCode(code); + clazz.setName(sort + "班"); + + Integer groupId = gradeNameToIdMap.get(year.toString()); + if (groupId == null) { + throw new IllegalArgumentException("年级组 '" + year + "' 不存在,请检查年级组名称或同步树结构!"); + } + clazz.setGroupId(groupId); + + Integer classId = classNameToIdMap.get(code); + if (classId == null) { + throw new IllegalArgumentException("班级组 '" + code + "' 不存在,请检查班级组数据或同步树结构!"); + } + clazz.setClassId(classId); + + clazz.setGraduate(false); + clazz.setEnrollYear(year); + OtherUtil.setBaseEntityValue(user, clazz); + schClassList.add(clazz); + } + + schClassRepository.saveAll(schClassList); + cacheService.clearClassCache(schId); + + String content = logService.buildAddBaseClassLog(user, schsystemId, gradeId, schClassList); + LogContextHolder.setDescription(content); + } + + // ---------- 编辑班级别名 ---------- + public void editClassName(UserContext.UserInfo user, Integer id, String cname) { + Integer schId = user.getSchId(); + SchClass schClass = schClassRepository.findByIdAndSchId(id, schId) + .orElseThrow(() -> new DException("班级不存在")); + String oldCname = schClass.getCname(); + schClass.setCname(cname); + OtherUtil.setBaseEntityValue(user, schClass); + schClassRepository.save(schClass); + cacheService.clearClassCache(schId); + + String content = logService.buildEditClassNameLog(user, schClass, oldCname, cname); + LogContextHolder.setDescription(content); + } + + // ---------- 编辑班主任 ---------- + public void editClassFirstTeacher(UserContext.UserInfo user, Integer id, Integer firstTeacherId) { + Integer schId = user.getSchId(); + SchClass schClass = schClassRepository.findByIdAndSchId(id, schId) + .orElseThrow(() -> new DException("班级不存在")); + Integer oldId = schClass.getFirstTeacherId(); + schClass.setFirstTeacherId(firstTeacherId); + OtherUtil.setBaseEntityValue(user, schClass); + schClassRepository.save(schClass); + cacheService.clearClassCache(schId); + + String content = logService.buildEditFirstTeacherLog(user, schClass, oldId, firstTeacherId); + LogContextHolder.setDescription(content); + } + + // ---------- 编辑副班主任 ---------- + public void editClassSecondTeacher(UserContext.UserInfo user, Integer id, Integer secondTeacherId) { + Integer schId = user.getSchId(); + SchClass schClass = schClassRepository.findByIdAndSchId(id, schId) + .orElseThrow(() -> new DException("班级不存在")); + Integer oldId = schClass.getSecondTeacherId(); + schClass.setSecondTeacherId(secondTeacherId); + OtherUtil.setBaseEntityValue(user, schClass); + schClassRepository.save(schClass); + cacheService.clearClassCache(schId); + + String content = logService.buildEditSecondTeacherLog(user, schClass, oldId, secondTeacherId); + LogContextHolder.setDescription(content); + } + + // ---------- 编辑校区 ---------- + public void editClassCampus(UserContext.UserInfo user, Integer id, Integer campusId) { + Integer schId = user.getSchId(); + SchClass schClass = schClassRepository.findByIdAndSchId(id, schId) + .orElseThrow(() -> new DException("班级不存在")); + Integer oldCampusId = schClass.getCampusId(); + schClass.setCampusId(campusId); + OtherUtil.setBaseEntityValue(user, schClass); + schClassRepository.save(schClass); + cacheService.clearClassCache(schId); + + String content = logService.buildEditCampusLog(user, schClass, oldCampusId, campusId); + LogContextHolder.setDescription(content); + } + + // ---------- 删除班级 ---------- + public void deleteSchClass(UserContext.UserInfo user, Integer id, Integer schId) { + SchClass schClass = schClassRepository.findByIdAndSchId(id, schId) + .orElseThrow(() -> new DException("班级不存在")); + if (Boolean.TRUE.equals(schClass.getGraduate())) { + throw new DException("已毕业班级不能删除"); + } + // 可选:检查班级下是否有学生 + // long count = studentRepository.countByClassId(id); + // if (count > 0) throw new DException("班级下还有学生"); + schClassRepository.deleteById(id); + cacheService.clearClassCache(schId); + + String content = logService.buildDeleteClassLog(schId, schClass); + LogContextHolder.setDescription(content); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassLogService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassLogService.java new file mode 100644 index 0000000..c0d6744 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassLogService.java @@ -0,0 +1,241 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchClassLogService { + + @Autowired + private ILogService logService; + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private IComSchTreeService comSchTreeService; + + private static final String MODULE_CLASS = LogModule.CLASS; + + // ---------- 同步构建日志描述 ---------- + public String buildAddBaseClassLog(UserContext.UserInfo user, Integer schsystemId, Integer gradeId, List schClassList) { + try { + String schsystemName = schBinSchsystemService.selectSchBinSchsystem(user.getSchId()).stream() + .filter(s -> s.getId().equals(schsystemId)) + .map(SelectIntVO::getName) + .findFirst() + .orElse("未知学制"); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), schsystemId, gradeId); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + List classNameList = schClassList.stream() + .map(SchClass::getName) + .collect(Collectors.toList()); + String classNames; + if (classNameList.size() <= 10) { + classNames = String.join("、", classNameList); + } else { + classNames = String.join("、", classNameList.subList(0, 10)) + "等" + classNameList.size() + "个班级"; + } + return String.format("新增班级:学制[%s]年级[%s]新增%d个班级,班级列表:[%s]", + schsystemName, gradeName, schClassList.size(), classNames); + } catch (Exception e) { + log.error("记录新增班级日志失败", e); + return "新增班级日志失败"; + } + } + + public String buildEditClassNameLog(UserContext.UserInfo user, SchClass schClass, String oldCname, String newCname) { + try { + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(user.getSchId(), schClass.getGradeId()); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), schsystemId, schClass.getGradeId()); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + String classDesc = gradeName + schClass.getName() + "(" + schClass.getCode() + ")"; + String oldDisplay = StringUtils.isNotBlank(oldCname) ? oldCname : "无"; + String newDisplay = StringUtils.isNotBlank(newCname) ? newCname : "无"; + return String.format("修改班级[%s]的自定义名称:%s -> %s", classDesc, oldDisplay, newDisplay); + } catch (Exception e) { + log.error("记录修改班级自定义名称日志失败", e); + return "修改班级自定义名称" + newCname + "日志失败"; + } + } + + public String buildEditFirstTeacherLog(UserContext.UserInfo user, SchClass schClass, Integer oldTeacherId, Integer newTeacherId) { + try { + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(user.getSchId(), schClass.getGradeId()); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), schsystemId, schClass.getGradeId()); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + String classDesc = gradeName + schClass.getName(); + Map teacherMap = schTeacherService.toIdAndNameMap(user.getSchId()); + String oldName = (oldTeacherId != null) ? teacherMap.getOrDefault(oldTeacherId, "未知教师") : "无"; + String newName = (newTeacherId != null) ? teacherMap.getOrDefault(newTeacherId, "未知教师") : "无"; + return String.format("修改班级[%s]的班主任:%s -> %s", classDesc, oldName, newName); + } catch (Exception e) { + log.error("记录修改班级班主任日志失败", e); + return "修改班级班主任日志失败"; + } + } + + public String buildEditSecondTeacherLog(UserContext.UserInfo user, SchClass schClass, Integer oldTeacherId, Integer newTeacherId) { + // 类似 buildEditFirstTeacherLog,将“班主任”改为“副班主任” + try { + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(user.getSchId(), schClass.getGradeId()); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), schsystemId, schClass.getGradeId()); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + String classDesc = gradeName + schClass.getName(); + Map teacherMap = schTeacherService.toIdAndNameMap(user.getSchId()); + String oldName = (oldTeacherId != null) ? teacherMap.getOrDefault(oldTeacherId, "未知教师") : "无"; + String newName = (newTeacherId != null) ? teacherMap.getOrDefault(newTeacherId, "未知教师") : "无"; + return String.format("修改班级[%s]的副班主任:%s -> %s", classDesc, oldName, newName); + } catch (Exception e) { + log.error("记录修改班级副班主任日志失败", e); + return "修改班级副班主任日志失败"; + } + } + + public String buildEditCampusLog(UserContext.UserInfo user, SchClass schClass, Integer oldCampusId, Integer newCampusId) { + try { + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(user.getSchId(), schClass.getGradeId()); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), schsystemId, schClass.getGradeId()); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + String classDesc = gradeName + schClass.getName() + "(" + schClass.getCode() + ")"; + Map campusMap = schDicCampusService.toIdAndNameMap(user.getSchId()); + String oldName = (oldCampusId != null) ? campusMap.getOrDefault(oldCampusId, "未知校区") : "无"; + String newName = (newCampusId != null) ? campusMap.getOrDefault(newCampusId, "未知校区") : "无"; + return String.format("修改班级[%s]的校区:%s -> %s", classDesc, oldName, newName); + } catch (Exception e) { + log.error("记录修改班级校区日志失败", e); + return "修改班级校区日志失败"; + } + } + + public String buildDeleteClassLog(Integer schId, SchClass schClass) { + try { + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(schId, schClass.getGradeId()); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(schId, schsystemId, schClass.getGradeId()); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + String codeSuffix = StringUtils.isNotBlank(schClass.getCode()) ? "(" + schClass.getCode() + ")" : ""; + String classDesc = gradeName + schClass.getName() + codeSuffix; + return String.format("删除班级[%s]成功", classDesc); + } catch (Exception e) { + log.error("记录删除班级日志失败", e); + return "删除班级日志失败"; + } + } + + public String buildSaveHigherClassLog(UserContext.UserInfo user, SchClass schClass, boolean isNew, SchClass oldSchClass) { + try { + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(user.getSchId(), schClass.getGradeId()); + String schsystemName = schBinSchsystemService.selectSchBinSchsystem(user.getSchId()).stream() + .filter(s -> s.getId().equals(schsystemId)) + .map(SelectIntVO::getName) + .findFirst() + .orElse("未知学制"); + String gradeName = "未知年级"; + List gradeList = baseSchsystemGradeService.getGradeSelect(user.getSchId(), schsystemId, schClass.getGradeId()); + if (!gradeList.isEmpty()) { + gradeName = gradeList.get(0).getName(); + } + String className = StringUtils.isNotBlank(schClass.getCname()) ? schClass.getCname() : schClass.getName(); + String classDesc = gradeName + className + "(" + schClass.getCode() + ")"; + Map teacherMap = schTeacherService.toIdAndNameMap(user.getSchId()); + String newTeacherName = (schClass.getFirstTeacherId() != null) ? teacherMap.getOrDefault(schClass.getFirstTeacherId(), "未知教师") : "无"; + Map campusMap = schDicCampusService.toIdAndNameMap(user.getSchId()); + String newCampusName = (schClass.getCampusId() != null) ? campusMap.getOrDefault(schClass.getCampusId(), "未知校区") : "无"; + + if (isNew) { + return String.format("新增班级:学制[%s]年级[%s],班级[%s],班主任[%s],校区[%s]", + schsystemName, gradeName, classDesc, newTeacherName, newCampusName); + } else { + String oldTeacherName = "无"; + if (oldSchClass != null && oldSchClass.getFirstTeacherId() != null) { + oldTeacherName = teacherMap.getOrDefault(oldSchClass.getFirstTeacherId(), "未知教师"); + } + String oldCampusName = "无"; + if (oldSchClass != null && oldSchClass.getCampusId() != null) { + oldCampusName = campusMap.getOrDefault(oldSchClass.getCampusId(), "未知校区"); + } + boolean teacherChanged = !oldTeacherName.equals(newTeacherName); + boolean campusChanged = !oldCampusName.equals(newCampusName); + String changeDesc = ""; + if (teacherChanged && campusChanged) { + changeDesc = String.format(",班主任:%s -> %s,校区:%s -> %s", + oldTeacherName, newTeacherName, oldCampusName, newCampusName); + } else if (teacherChanged) { + changeDesc = String.format(",班主任:%s -> %s", oldTeacherName, newTeacherName); + } else if (campusChanged) { + changeDesc = String.format(",校区:%s -> %s", oldCampusName, newCampusName); + } + return String.format("修改班级[%s]信息%s", classDesc, changeDesc); + } + } catch (Exception e) { + log.error("记录保存职业教育班级日志失败", e); + return "保存职业教育班级日志失败"; + } + } + + // ---------- 异步日志 ---------- + @Async("logExecutor") + public void importLogs(UserContext.UserInfo user, List classList) { + try { + LocalDateTime now = LocalDateTime.now(); + Map gradeMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null); + String schName = comSchTreeService.getSchoolName(user.getSchId()); + List logs = new ArrayList<>(); + for (SchClass clazz : classList) { + String content = "导入班级[" + schName + + gradeMap.get(clazz.getGradeId()) + clazz.getName() + + "]成功,用户信息:" + JSON.toJSONString(clazz); + OperationLogRecord log = logService.buildLogRecord(user, MODULE_CLASS, content, now); + logs.add(log); + } + if (!logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + log.debug("操作人:{},班级导入日志成功: {}", user.getUserName(), JSON.toJSONString(classList)); + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",班级导入日志失败: {}", e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassQueryService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassQueryService.java new file mode 100644 index 0000000..669c117 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassQueryService.java @@ -0,0 +1,235 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.entity.BaseSchsystemGrade; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.*; +import com.bestsch.bschclassmanage.service.*; +import com.bestsch.bschclassmanage.utils.ModelMapperUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@Slf4j +@Service +public class SchClassQueryService { + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchDicCampusService schDicCampusService; + + @Autowired + private ISchDicDivisionService schDicDivisionService; + + @Autowired + private ISchDicMajorsService schDicMajorsService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private SchClassCacheService cacheService; + + + + + // ---------- 缓存版查询(委托给 CacheService) ---------- + public List getSchClassCacheList(Integer schId) { + return cacheService.getSchClassCacheList(schId); + } + + public List getSchGradeateClassCacheList(Integer schId) { + return cacheService.getSchGradeateClassCacheList(schId); + } + + public List getSchAllClassCacheList(Integer schId) { + return cacheService.getSchAllClassCacheList(schId); + } + + + + // ---------- 过滤查询(基于缓存) ---------- + public List getSchClassCacheFilter(Integer schId, List gradeIds, Integer classId) { + List list = getSchClassCacheList(schId); + if (schId != null && schId > 0) + list = list.stream().filter(s -> s.getSchId().equals(schId)).collect(Collectors.toList()); + if (gradeIds != null && !gradeIds.isEmpty()) + list = list.stream().filter(s -> gradeIds.contains(s.getGradeId())).collect(Collectors.toList()); + if (classId != null && classId > 0) + list = list.stream().filter(s -> classId.equals(s.getClassId())).collect(Collectors.toList()); + return list; + } + + public List getSchClassCacheFilter(Integer schId, Integer gradeId, Integer classId) { + List list = getSchClassCacheList(schId); + if (schId != null && schId > 0) + list = list.stream().filter(s -> s.getSchId().equals(schId)).collect(Collectors.toList()); + if (gradeId != null && gradeId > 0) + list = list.stream().filter(s -> gradeId.equals(s.getGradeId())).collect(Collectors.toList()); + if (classId != null && classId > 0) + list = list.stream().filter(s -> classId.equals(s.getClassId())).collect(Collectors.toList()); + return list; + } + + public List getSchAllClassCacheFilter(Integer schId, List gradeIds, Integer classId) { + List list = getSchAllClassCacheList(schId); + if (schId != null && schId > 0) + list = list.stream().filter(s -> s.getSchId().equals(schId)).collect(Collectors.toList()); + if (gradeIds != null && !gradeIds.isEmpty()) + list = list.stream().filter(s -> gradeIds.contains(s.getGradeId())).collect(Collectors.toList()); + if (classId != null && classId > 0) + list = list.stream().filter(s -> classId.equals(s.getClassId())).collect(Collectors.toList()); + return list; + } + + public List getSchAllClassCacheFilter(Integer schId, Integer gradeId, Integer classId) { + List list = getSchAllClassCacheList(schId); + if (schId != null && schId > 0) + list = list.stream().filter(s -> s.getSchId().equals(schId)).collect(Collectors.toList()); + if (gradeId != null && gradeId > 0) + list = list.stream().filter(s -> gradeId.equals(s.getGradeId())).collect(Collectors.toList()); + if (classId != null && classId > 0) + list = list.stream().filter(s -> classId.equals(s.getClassId())).collect(Collectors.toList()); + return list; + } + + + // ---------- K12 查询 ---------- + public List searchBaseSchClass(Integer schId, List gradeIds, Integer classId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + predicates.add(cb.equal(root.get(EntityFieldNames.graduate), false)); + predicates.add(cb.notEqual(root.get(EntityFieldNames.gradeId), root.get(EntityFieldNames.enrollYear))); + if (gradeIds != null && !gradeIds.isEmpty()) { + predicates.add(root.get(EntityFieldNames.gradeId).in(gradeIds)); + } + if (classId != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.classId), classId)); + } + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schClassRepository.findAll(spec); + } + + public List searcBaseSchClass(Integer schId, Integer schsystemId, Integer gradeId, Integer classId) { + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, gradeId); + Map campusNameMap = schDicCampusService.toIdAndNameMap(schId); + Map teacherNameMap = schTeacherService.toIdAndNameMap(schId); + + List gradeIds = new ArrayList<>(gradeNameMap.keySet()); + List classList = searchBaseSchClass(schId, gradeIds, classId); + + List voList = IntStream.range(0, classList.size()) + .mapToObj(i -> { + SchClass clazz = classList.get(i); + BaseSchClassVO vo = convertBaseSchClassToVO(clazz, gradeNameMap, campusNameMap, teacherNameMap); + vo.setDisableDel(i != classList.size() - 1); + return vo; + }) + .collect(Collectors.toList()); + return voList; + } + + private BaseSchClassVO convertBaseSchClassToVO(SchClass clazz, + Map gradeNameMap, + Map campusNameMap, + Map teacherNameMap) { + BaseSchClassVO vo = ModelMapperUtil.map(clazz, BaseSchClassVO.class); + vo.setGradeName(gradeNameMap.get(clazz.getGradeId())); + vo.setCampusName(campusNameMap.get(clazz.getCampusId())); + vo.setFirstTeacherName(teacherNameMap.get(clazz.getFirstTeacherId())); + vo.setSecondTeacherName(teacherNameMap.get(clazz.getSecondTeacherId())); + return vo; + } + + // ---------- 职业教育查询 ---------- + public PageVO searcHigherSchClass(Integer schId, Integer year, Integer campusId, + Integer divisionId, Integer majorsId, Pageable pageable) { + List years = new ArrayList<>(); + if (year != null && year > 0) years.add(year); + years = years.isEmpty() ? null : years; + + Page classPage = schClassRepository.findClassesByConditions(schId, campusId, divisionId, majorsId, years, pageable); + if (classPage.isEmpty()) { + return PageVO.empty(pageable.getPageSize()); + } + + List classList = classPage.getContent(); + Map campusNameMap = schDicCampusService.toIdAndNameMap(schId); + Map divisionsNameMap = schDicDivisionService.toIdAndNameMap(schId); + Map majorssNameMap = schDicMajorsService.toIdAndNameMap(schId); + + List voList = classList.stream() + .map(clazz -> convertHigherSchClassToVO(clazz, campusNameMap, divisionsNameMap, majorssNameMap)) + .collect(Collectors.toList()); + + return new PageVO<>(pageable.getPageNumber() + 1, + pageable.getPageSize(), + classPage.getTotalElements(), + voList); + } + + private HigherSchClassVO convertHigherSchClassToVO(SchClass clazz, + Map campusNameMap, + Map divisionsNameMap, + Map majorssNameMap) { + HigherSchClassVO vo = ModelMapperUtil.map(clazz, HigherSchClassVO.class); + vo.setCampusName(campusNameMap.get(clazz.getCampusId())); + vo.setDivisionName(divisionsNameMap.get(clazz.getDivisionId())); + vo.setMajorsName(majorssNameMap.get(clazz.getMajorsId())); + vo.setFirstTeacherName(null); + vo.setSecondTeacherName(null); + return vo; + } + + // ---------- 下拉列表 ---------- + public List getClassSelect(Integer schId, Integer gradeId) { + List schClassList = getSchClassCacheFilter(schId, gradeId, null); + if (schClassList == null || schClassList.isEmpty()) { + return Collections.emptyList(); + } + return schClassList.stream() + .filter(cls -> cls.getClassId() != null) + .map(cls -> new SelectIntVO(cls.getClassId(), cls.getName())) + .sorted(Comparator.comparingInt(SelectIntVO::getId)) + .collect(Collectors.toList()); + } + + /** + * 获取指定学校、指定学制下所有班级的最小入学年份 + * @param schId 学校ID + * @param schsystemId 学制ID(基础学制ID) + * @return 最小入学年份,若无班级则返回 null + */ + public Integer getMinEnrollYearBySchsystem(Integer schId, Integer schsystemId) { + // 1. 获取该学制下的年级列表 + List gradeList = baseSchsystemGradeService.getSchGradeCacheList(schId, schsystemId, null); + if (CollectionUtils.isEmpty(gradeList)) { + return null; + } + List gradeIds = gradeList.stream() + .map(BaseSchsystemGrade::getGradeId) + .collect(Collectors.toList()); + + return schClassRepository.findMinEnrollYear(schId,gradeIds); + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassUpgradeService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassUpgradeService.java new file mode 100644 index 0000000..a3b07c1 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/classes/SchClassUpgradeService.java @@ -0,0 +1,155 @@ +package com.bestsch.bschclassmanage.service.impl.classes; + +import com.bestsch.bschclassmanage.Repository.*; +import com.bestsch.bschclassmanage.entity.*; +import com.bestsch.bschclassmanage.enums.SchType; +import com.bestsch.bschclassmanage.model.tool.YearTerm; +import com.bestsch.bschclassmanage.service.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchClassUpgradeService { + + @Autowired + private SchClassCacheService schClassCacheService; + + @Autowired + private SchClassQueryService queryService; + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private ISchBinSchsystemService schBinSchsystemService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private IBaseYearTermService baseYearTermService; + + @Autowired + private UpgradeLogRepository upgradeLogRepository; + + @Autowired + private JdbcTemplate jdbcTemplate; + + + public void upgradeAllClasses() { + Date now = new Date(); + // 获取当前学年学期 + YearTerm yearTerm = baseYearTermService.getCurrentYearTerm(); + int currentYear = yearTerm.getYear(); + + List schoolIds = schBinSchsystemService.getSchIds(); + + for (Integer schId : schoolIds) { + // ----- 2. 获取该校所有学制 ----- + List schsystemIds = schBinSchsystemService.getSchBinSchsystemIds(schId); + Integer schType = schBinSchsystemService.getSchType(schId); + for (Integer sysId : schsystemIds) { + Boolean status=true; + if (upgradeLogRepository.existsBySchIdAndSysIdAndYearAndStatus(schId, sysId, currentYear,status)) { + log.info("学校{}学制{}学年{}学期已升级,跳过", schId, sysId, currentYear); + continue; // 直接返回,不做任何操作 + } + try { + upgradeSingleSystem(schId,schType,sysId,now); + log.info("学校{} 学制{} 学年{} 升级执行成功", schId, sysId, currentYear); + } catch (Exception e) { + log.error("学校{}学制{}升级失败,已跳过,不影响其他学制", schId, sysId, e); + status=false; + } + upgradeLogRepository.save(new UpgradeLog(schId, sysId, currentYear,now,status)); + } + // 清除该校缓存 + schClassCacheService.clearClassCache(schId); + } + } + + //升级业务逻辑 + @Transactional(propagation = Propagation.REQUIRES_NEW) + protected void upgradeSingleSystem(Integer schId,Integer schType, Integer sysId, Date now) { + // 1. 检查是否已升级(利用数据库唯一索引防并发) + // 2. 执行升级逻辑 + // 3. 插入升级日志 + + Map gradeMap = baseSchsystemGradeService.getGradeNameMap(schId, sysId, null); + List gradeIds = new ArrayList<>(gradeMap.keySet()); + Collections.sort(gradeIds); + if (gradeIds.isEmpty()) return; + + Integer maxGrade = gradeIds.get(gradeIds.size() - 1); + + // ----- 3. 升级非最高年级 ----- + for (Integer gradeId : gradeIds) { + if (gradeId.equals(maxGrade)) continue; + List classList = queryService.getSchClassCacheFilter(schId, gradeId, null); + if (classList.isEmpty()) continue; + + // 执行升级 + for (SchClass clazz : classList) { + if(schType.equals(SchType.BASICEDUCATION.getKey())) { + clazz.setGradeId(gradeId + 1);//基础教育年级+1 + } + clazz.setUpdateDate(now); + clazz.setUpdateUserId(0); + } + schClassRepository.saveAll(classList); + } + + // ----- 4. 处理最高年级(毕业) ----- + List graduateClassList = queryService.getSchClassCacheFilter(schId, maxGrade, null); + if (!graduateClassList.isEmpty()) { + for (SchClass clazz : graduateClassList) { + clazz.setGraduate(true); + clazz.setUpdateDate(now); + clazz.setUpdateUserId(0); + } + schClassRepository.saveAll(graduateClassList); + } + + } + + + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void backupAllSnapshot() { + YearTerm yearTerm = baseYearTermService.getCurrentYearTerm(); + if (yearTerm == null) { + log.error("当前学年学期未配置,无法备份"); + return; + } + int year = yearTerm.getYear(); + int term = yearTerm.getTerm(); + + String countSql = "SELECT COUNT(*) FROM sch_class_history WHERE year = ? AND term = ?"; + int count = jdbcTemplate.queryForObject(countSql, Integer.class, year, term); + if (count > 0) { + log.info("学年{}学期{}已有备份记录,跳过全量备份", year, term); + return; + } + // 班级快照 + String classSql = "INSERT INTO sch_class_history (code, group_grade_id, group_class_id, name, cname, first_teacher_id, second_teacher_id, grade_id, campus_id, division_id, majors_id, enroll_year, graduate, sort, year, term, create_date, update_date, create_user_id, update_user_id, sch_id) SELECT IFNULL(code, ''), group_grade_id, group_class_id, name, IFNULL(cname, ''), first_teacher_id, second_teacher_id, grade_id, campus_id, division_id, majors_id, IFNULL(enroll_year, 0), graduate, sort, ?, ?, create_date, update_date, 0, 0, sch_id FROM sch_class WHERE graduate = 0"; + jdbcTemplate.update(classSql, year, term); + + // 任教快照 + String teachSql = "INSERT INTO sch_class_teach_history (year, term, grade_id, sub_id, class_id, tea_id, create_date, update_date, create_user_id, update_user_id, sch_id) SELECT ?, ?, c.grade_id, t.sub_id, t.class_id, t.tea_id, t.create_date, t.update_date, 0, 0, c.sch_id FROM sch_class_teach t INNER JOIN sch_class c ON t.class_id = c.group_class_id WHERE c.graduate = 0"; + jdbcTemplate.update(teachSql, year, term); + + // 学生快照 + String stuSql = "INSERT INTO sch_student_history (year, term, stu_id, account, stu_class_no, name, gender, id_card, group_id, class_id, grade_id, status, abnormal_status, abnormal_date, transfer_status, invitation_code, sort, create_date, update_date, create_user_id, update_user_id, sch_id) SELECT ?, ?, s.stu_id, s.account, s.stu_class_no, s.name, s.gender, s.id_card, s.group_id, s.class_id, c.grade_id, s.status, s.abnormal_status, s.abnormal_date, s.transfer_status, s.invitation_code, s.sort, s.create_date, s.update_date, 0, 0, c.sch_id FROM sch_student s INNER JOIN sch_class c ON s.class_id = c.group_class_id WHERE c.graduate = 0"; + jdbcTemplate.update(stuSql, year, term); + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentCacheService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentCacheService.java new file mode 100644 index 0000000..4c145d2 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentCacheService.java @@ -0,0 +1,112 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchStudentCacheService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private RedisUtil redisUtil; + + /** + * 获取单个班级的学生(带缓存) + */ + public List getClassStudentCacheList(Integer schId, Integer classId) { + String cacheKey = RedisConstants.SCHOOL_CLASS_STUDENT + "_" + schId + "_" + classId; + List cached = redisUtil.getList(cacheKey, SchStudent.class); + if (cached != null) { + return cached; + } + synchronized (this) { + cached = redisUtil.getList(cacheKey, SchStudent.class); + if (cached != null) { + return cached; + } + List list = schStudentRepository.findBySchIdAndClassId(schId, classId); + if (list == null) list = Collections.emptyList(); + list.sort(Comparator.comparingInt(s -> Optional.ofNullable(s.getSort()).orElse(9999))); + redisUtil.set(cacheKey, list, RedisConstants.CACHE_EXPIRE_1H); + return list; + } + } + + /** + * 获取年级/学制下的学生(合并多个班级缓存) + */ + public List getSchGradeClassStudentCacheList(Integer schId, Integer schsystemId, Integer gradeId, Integer classId) { + if (schId == null) { + throw new IllegalArgumentException("schId不能为空"); + } + + // 如果指定了班级,直接获取该班级的学生 + if (classId != null && classId > 0) { + return getClassStudentCacheList(schId, classId); + } + + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, gradeId); + + List gradeIds = new ArrayList<>(gradeNameMap.keySet()); + if (gradeIds == null || gradeIds.isEmpty()) { + return Collections.emptyList(); + } + + // 否则获取全校所有班级的学生(按班级分别缓存,合并返回) + + List classIds = schClassService.getSchClassCacheList(schId).stream() + .filter(s -> gradeIds.contains(s.getGradeId()) + ).map(s -> s.getClassId()).collect(Collectors.toList()); + + if (classIds == null || classIds.isEmpty()) { + return Collections.emptyList(); + } + + List result = new ArrayList<>(); + for (Integer clazzId : classIds) { + result.addAll(getClassStudentCacheList(schId, clazzId)); + } + return result; + } + + /** + * 清除单个班级缓存 + */ + public void clearClassStudentCache(Integer schId, Integer classId) { + if (schId == null || classId == null) return; + String cacheKey = RedisConstants.SCHOOL_CLASS_STUDENT + "_" + schId + "_" + classId; + redisUtil.del(cacheKey); + log.debug("清除学生缓存:schId={}, classId={}", schId, classId); + } + + + /** + * 批量清除多个班级缓存 + */ + public void clearClassStudentCaches(Integer schId, Set classIds) { + if (schId == null || classIds == null || classIds.isEmpty()) return; + for (Integer classId : classIds) { + clearClassStudentCache(schId, classId); + } + log.debug("批量清除学生缓存:schId={}, classIds={}", schId, classIds); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentImportService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentImportService.java new file mode 100644 index 0000000..77e917e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentImportService.java @@ -0,0 +1,507 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.enums.StuAbnormalStatus; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.enums.UserGender; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.excel.ErrorExcelColumn; +import com.bestsch.bschclassmanage.model.excel.StudentClassNoExcelColumn; +import com.bestsch.bschclassmanage.model.excel.StudentExcelColumn; +import com.bestsch.bschclassmanage.model.vo.BaseSchClassVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.utils.EasyPoiUtils; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.bestsch.bschclassmanage.utils.ValidateUtil; +import com.bestsch.bschclassmanage.utils.ValidationUtil; +import com.yunhai.platform.utils.exception.DException; +import com.yunhai.platform.utils.exception.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 学生导入服务(内部实现,无接口) + * 职责:处理Excel学生数据导入 + */ +@Slf4j +@Service +public class SchStudentImportService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private SchStudentCacheService cacheService; + + @Autowired + private SchStudentLogService logService; + + /** + * 导入学生数据 + */ + public void importStudents(UserContext.UserInfo user, MultipartFile file) { + List errorMsgArr = new ArrayList<>(); + ImportParams params = new ImportParams(); + params.setTitleRows(1); + params.setHeadRows(1); + Integer schId = user.getSchId(); + Integer userId = user.getUserId(); + + Date now = new Date(); + // 使用 try-with-resources 确保流关闭 + try (InputStream is = file.getInputStream()) { + // 1. 加载基础数据(放在 try 内,若加载失败也回滚) + List gradeList = baseSchsystemGradeService.getGradeSelect(schId, null, null); + List schClassList = schClassService.getSchClassCacheList(schId); + Set classIds = new HashSet<>(); + + // 2. 解析 Excel(可能抛出异常) + List list; + try { + list = ExcelImportUtil.importExcel(is, StudentExcelColumn.class, params); + } catch (Exception e) { + // 解析异常:可能是文件格式错误、数据转换错误等 + log.error("Excel解析失败", e); + String msg = e.getMessage(); + throw new DException("Excel 数据格式有误,请检查所有单元格类型是否正确。错误详情:" + msg); + } + + // 3. 空数据检查 + if (list == null || list.isEmpty()) { + throw new DException("上传的 Excel 中没有有效数据行,请检查后重新上传!"); + } + + // Excel数据重复验证 + { + List validateDuplicatesMsgs = validateDuplicates(list); + if (validateDuplicatesMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(0, "数据重复", String.join("\r\n", validateDuplicatesMsgs))); + } + } + + // 4. 业务校验与转换 + List saveStudentList = new ArrayList<>(); + int currentRow = params.getTitleRows() + params.getHeadRows() + 1; // 从第3行开始 + + for (StudentExcelColumn item : list) { + Integer oldClassId = 0; + // Excel数据验证 + { + List validateMsgs = ValidationUtil.validateMsgs(item); + if (validateMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, "导入规则", String.join("\r\n", validateMsgs))); + continue; + } + } + SchStudent stu = new SchStudent(); + + // 账号 + { + Optional accountOpt = schStudentRepository.findByAccount(item.getAccount()); + if (accountOpt.isPresent()) { + if (!accountOpt.get().getSchId().equals(schId) && accountOpt.get().getTransferStatus().equals(TransferStatus.IN)) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getStuName(), + "禁止将" + comSchTreeService.getSchoolName(accountOpt.get().getSchId()) + "正常学生导入!")); + continue; + } else { + BeanUtils.copyProperties(accountOpt.get(), stu); + stu.setUpdateDate(now); + stu.setUpdateUserId(userId); + oldClassId = accountOpt.get().getClassId(); + } + } else { + stu.setId(0); + stu.setCreateDate(now); + stu.setCreateUserId(userId); + stu.setAccount(item.getAccount()); + stu.setStatus(UserStatus.NORMAL.getId()); + stu.setTransferStatus(TransferStatus.IN.getId()); + stu.setAbnormalStatus(StuAbnormalStatus.NORMAL.getId()); + } + } + + Integer gradeId; + // 年级 + { + Optional gradeIdOpt = gradeList.stream() + .filter(vo -> vo.getName().equals(item.getGradeName())) + .map(SelectIntVO::getId) + .findFirst(); + + if (gradeIdOpt.isPresent()) { + gradeId = gradeIdOpt.get(); + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), StudentExcelColumn.GRADE_NAME + "不存在!")); + continue; + } + } + // 班级 + { + Optional schClassOpt = schClassList.stream() + .filter(s -> gradeId.equals(s.getGradeId()) && s.getName().equals(item.getClazzName())) + .findFirst(); + if (schClassOpt.isPresent()) { + stu.setClassId(schClassOpt.get().getClassId()); + stu.setGroupId(schClassOpt.get().getClassId()); + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), StudentExcelColumn.CLAZZ_NAME + "不存在!")); + continue; + } + } + + // 姓名 + { + boolean nameExists = schStudentRepository.existsBySchIdAndClassIdAndNameAndIdNot( + schId, stu.getClassId(), item.getStuName(), stu.getId()); + if (nameExists) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getStuName(), "班级学生名称已存在")); + continue; + } + stu.setName(item.getStuName()); + } + + // 密码(暂时忽略,或可设置默认密码,但原代码无处理) + + // 身份证 + if (StringUtils.isNotBlank(item.getIdCard())) { + if (!ValidateUtil.isValidIdCard(item.getIdCard())) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getIdCard(), ValidateUtil.getValidateMessage(item.getIdCard()))); + continue; + } + stu.setIdCard(item.getIdCard()); + } else { + stu.setIdCard(null); + } + // 学号 + { + stu.setStuClassNo(item.getClazzNo()); + if (StringUtils.isNotBlank(item.getClazzNo())) { + try { + String digits = item.getClazzNo().replaceAll("\\D+", ""); + if (StringUtils.isNotBlank(digits)) { + stu.setSort(Integer.parseInt(digits)); + } + } catch (NumberFormatException e) { + // ignore + } + } + } + // 性别 + { + Integer gender = UserGender.FEMALE.getId(); + if (StringUtils.isNotBlank(item.getGender())) { + if (item.getGender().equals(UserGender.MALE.getName())) { + gender = UserGender.MALE.getId(); + } else if (item.getGender().equals(UserGender.FEMALE.getName())) { + gender = UserGender.FEMALE.getId(); + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGender(), StudentExcelColumn.GENDER + "不存在!")); + continue; + } + } + stu.setGender(gender); + } + // 实体验证 + { + List validateMsgs = ValidationUtil.validateMsgs(stu); + if (validateMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, "数据错误", String.join(",", validateMsgs))); + continue; + } + saveStudentList.add(stu); + classIds.add(stu.getClassId()); + if (oldClassId > 0) { + classIds.add(oldClassId); + } + } + } + + // 5. 若有错误,抛出异常(携带明细) + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + // 6. 批量保存 + schStudentRepository.saveAll(saveStudentList); + + // 7. 异步记录导入日志 + logService.importLogs(user, saveStudentList, gradeList, schClassList); + + // 8. 清除受影响的班级缓存 + cacheService.clearClassStudentCaches(schId, classIds); + + } catch (DException e) { + throw e; + } catch (Exception e) { + // 其他所有未预期的异常(包括数据库、IO等) + log.error("导入班级学生时发生系统异常,操作人:" + user.getUserName(), e); + throw new DException(ErrorCode.INTERNAL_SERVER_ERROR,"导入失败,请联系管理员",null,e); + } + } + + /** + * 校验导入数据中的重复项 + * @param importList 导入数据列表 + * @return 错误信息列表 + */ + private List validateDuplicates(List importList) { + List errors = new ArrayList<>(); + + // 1. 校验 "身份证号" 在本次导入中是否重复 + Map idCountMap = importList.stream() + .filter(dto -> StringUtils.isNotBlank(dto.getIdCard())) + .collect(Collectors.groupingBy( + dto -> dto.getIdCard(), + Collectors.counting() + )); + + idCountMap.entrySet().stream() + .filter(entry -> entry.getValue() > 1) + .forEach(entry -> errors.add( + String.format("身份证号 '%s' 在表格中出现了 %d 次,请检查并去重", + entry.getKey(), entry.getValue()) + )); + + // 2. 校验 "年级 + 班级 + 姓名" 组合是否重复 + Map nameCountMap = importList.stream() + .filter(dto -> StringUtils.isNotBlank(dto.getStuName())) + .collect(Collectors.groupingBy( + dto -> { + String grade = dto.getGradeName() != null ? dto.getGradeName().trim() : ""; + String className = dto.getClazzName() != null ? dto.getClazzName().trim() : ""; + String name = dto.getStuName().trim(); + return grade + "|" + className + "|" + name; + }, + Collectors.counting() + )); + + nameCountMap.entrySet().stream() + .filter(entry -> entry.getValue() > 1) + .forEach(entry -> { + String[] parts = entry.getKey().split("\\|"); + errors.add(String.format( + "年级班级:'%s%s' 中的学生姓名 '%s' 重复了 %d 次", + parts[0], parts[1], parts[2], entry.getValue() + )); + }); + + return errors; + } + + + public void studentClassNoTemplate(HttpServletResponse response, + Integer schId,Integer systemId,Integer gradeId,Integer classId){ + String fileName="学号导入模板"; + List> sheets = new ArrayList<>(); + + List stuExcelList=new ArrayList<>(); + + List schStudentList= cacheService.getSchGradeClassStudentCacheList(schId,systemId,gradeId,classId); + + List schClassdentList= schClassService.searcBaseSchClass(schId,systemId,gradeId,classId); + + + for (SchStudent stu: schStudentList) + { + Optional stuClassOpt= schClassdentList.stream() + .filter(s->s.getClassId().equals(stu.getClassId())).findFirst(); + + + StudentClassNoExcelColumn column=new StudentClassNoExcelColumn(); + column.setGradeName(stuClassOpt.isPresent()?stuClassOpt.get().getGradeName():"未知"); + column.setClazzName(stuClassOpt.isPresent()?stuClassOpt.get().getName():"未知"); + column.setStuName(stu.getName()); + column.setAccount(stu.getAccount()); + column.setClazzNo(stu.getStuClassNo()); + stuExcelList.add(column); + } + + ExportParams params1 = new ExportParams("学号导入",comSchTreeService.getSchoolName(schId)); + + Map sheet1 = new HashMap<>(); + sheet1.put("title",params1); + sheet1.put("entity", StudentClassNoExcelColumn.class); + sheet1.put("data", stuExcelList); + sheets.add(sheet1); + + Workbook workbook = ExcelExportUtil.exportExcel(sheets, ExcelType.HSSF); + EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook); + } + + + public void importStudentClassNo(UserContext.UserInfo user, MultipartFile file, Integer schsystemId, Integer gradeId,Integer classId){ + List errorMsgArr = new ArrayList<>(); + ImportParams params = new ImportParams(); + params.setTitleRows(0); + params.setHeadRows(1); + Integer schId = user.getSchId(); + Integer userId = user.getUserId(); + + Date now = new Date(); + // 使用 try-with-resources 确保流关闭 + try (InputStream is = file.getInputStream()) { + // 1. 加载基础数据(放在 try 内,若加载失败也回滚) + List gradeList = baseSchsystemGradeService.getGradeSelect(schId, schsystemId, gradeId); + List schClassList = schClassService.getSchClassCacheList(schId); + Set classIds = new HashSet<>(); + + // 2. 解析 Excel(可能抛出异常) + List list; + try { + list = ExcelImportUtil.importExcel(is, StudentClassNoExcelColumn.class, params); + } catch (Exception e) { + // 解析异常:可能是文件格式错误、数据转换错误等 + log.error("Excel解析失败", e); + String msg = e.getMessage(); + throw new DException("Excel 数据格式有误,请检查所有单元格类型是否正确。错误详情:" + msg); + } + + // 3. 空数据检查 + if (list == null || list.isEmpty()) { + throw new DException("上传的 Excel 中没有有效数据行,请检查后重新上传!"); + } + + // 4. 业务校验与转换 + List saveStudentList = new ArrayList<>(); + int currentRow = params.getTitleRows() + params.getHeadRows() ; // 从第2行开始 + + for (StudentClassNoExcelColumn item : list) { + // Excel数据验证 + { + List validateMsgs = ValidationUtil.validateMsgs(item); + if (validateMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, "导入规则", String.join("\r\n", validateMsgs))); + continue; + } + } + SchStudent stu = new SchStudent(); + + // 账号 + { + Optional accountOpt = schStudentRepository.findByAccount(item.getAccount()); + if (accountOpt.isPresent()) { + if (!accountOpt.get().getSchId().equals(schId) && accountOpt.get().getTransferStatus().equals(TransferStatus.IN)) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getStuName(), + "禁止将" + comSchTreeService.getSchoolName(accountOpt.get().getSchId()) + "正常学生导入!")); + continue; + } else { + BeanUtils.copyProperties(accountOpt.get(), stu); + stu.setUpdateDate(now); + stu.setUpdateUserId(userId); + } + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getAccount(),item.getStuName()+"学生账号未找到!")); + continue; + } + } + + Integer gradeId2; + // 年级 + { + Optional gradeIdOpt = gradeList.stream() + .filter(vo -> vo.getName().equals(item.getGradeName())) + .map(SelectIntVO::getId) + .findFirst(); + + if (gradeIdOpt.isPresent()) { + gradeId2 = gradeIdOpt.get(); + if(gradeId!=null&&!gradeId2.equals(gradeId)){ + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), StudentExcelColumn.GRADE_NAME + "参数年级与模板年级不一致!")); + continue; + } + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getGradeName(), StudentExcelColumn.GRADE_NAME + "不存在!")); + continue; + } + } + + // 班级 + { + Optional schClassOpt = schClassList.stream() + .filter(s -> gradeId2.equals(s.getGradeId()) && s.getName().equals(item.getClazzName())) + .findFirst(); + if (schClassOpt.isPresent()) { + if(classId!=null){ + if(!schClassOpt.get().getClassId().equals(classId)){ + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), StudentExcelColumn.CLAZZ_NAME + "参数班级与模板班级不一致!")); + continue; + } + + } + } else { + errorMsgArr.add(new ErrorExcelColumn(currentRow, item.getClazzName(), StudentExcelColumn.CLAZZ_NAME + "不存在!")); + continue; + } + } + + // 学号 + { + stu.setStuClassNo(item.getClazzNo()); + if (StringUtils.isNotBlank(item.getClazzNo())) { + try { + String digits = item.getClazzNo().replaceAll("\\D+", ""); + if (StringUtils.isNotBlank(digits)) { + stu.setSort(Integer.parseInt(digits)); + } + } catch (NumberFormatException e) { + // ignore + } + } + } + saveStudentList.add(stu); + } + + // 5. 若有错误,抛出异常(携带明细) + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + // 6. 批量保存 + schStudentRepository.saveAll(saveStudentList); + + // 7. 异步记录导入日志 + logService.importStudentClassNoLogs(user, saveStudentList, gradeList, schClassList); + + // 8. 清除受影响的班级缓存 + cacheService.clearClassStudentCaches(schId, classIds); + + } catch (DException e) { + throw e; + } catch (Exception e) { + // 其他所有未预期的异常(包括数据库、IO等) + log.error("导入班级学生时发生系统异常,操作人:" + user.getUserName(), e); + throw new DException(ErrorCode.CUSTOM,"导入失败,请联系管理员",null,e); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentInfoService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentInfoService.java new file mode 100644 index 0000000..b5b1a8c --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentInfoService.java @@ -0,0 +1,172 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.enums.StuAbnormalStatus; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SchStudentVO; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.ModelMapperUtil; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 学生基本信息 CRUD 服务(内部实现,无接口) + * 职责:新增、修改、删除学生 + */ +@Slf4j +@Service +public class SchStudentInfoService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private SchStudentCacheService cacheService; + + @Autowired + private SchStudentLogService logService; + + // ==================== 保存(新增/修改) ==================== + + /** + * 保存学生信息(新增或修改) + */ + public void saveStudent(UserContext.UserInfo user, SchStudentVO entityVO) { + // 1. 基础校验 + if (entityVO == null) { + throw new DException("学生数据不能为空"); + } + if (StringUtils.isBlank(entityVO.getName())) { + throw new DException("学生名称不能为空"); + } + + Integer schId = user.getSchId(); + String name = entityVO.getName(); + Integer id = entityVO.getId(); + Integer classId = entityVO.getClassId(); + + SchStudent entity = ModelMapperUtil.map(entityVO, SchStudent.class); + + if (StringUtils.isNotBlank(entity.getStuClassNo())) { + try { + String digits = entity.getStuClassNo().replaceAll("\\D+", ""); + if (StringUtils.isNotBlank(digits)) { + entity.setSort(Integer.parseInt(digits)); + } + } catch (NumberFormatException e) { + // ignore + } + } + + // 2. 名称唯一性校验 + boolean isNew = (id == null || id == 0); + boolean nameExists; + SchStudent existingForUpdate = null; + SchStudent oldStudent = null; + if (isNew) { + nameExists = schStudentRepository.existsBySchIdAndClassIdAndName(schId, classId, name); + } else { + // 更新前查询旧实体(用于日志比较) + existingForUpdate = schStudentRepository.findById(id) + .orElseThrow(() -> new DException("学生不存在,ID=" + id)); + if (!existingForUpdate.getSchId().equals(schId)) { + throw new DException("学生不属于当前学校"); + } + nameExists = schStudentRepository.existsBySchIdAndClassIdAndNameAndIdNot(schId, classId, name, id); + } + if (nameExists) { + throw new DException("学生名称已存在:" + name); + } + entity.setGroupId(entity.getClassId()); + entity.setStuId(0); + + // 3. 执行保存 + SchStudent savedEntity; + if (isNew) { + entity.setTransferStatus(TransferStatus.IN.getId()); + entity.setAbnormalStatus(StuAbnormalStatus.NORMAL.getId()); + entity.setStatus(UserStatus.NORMAL.getId()); + OtherUtil.setBaseEntityValue(user, entity); + savedEntity = schStudentRepository.save(entity); + } else { + // 复制允许修改的字段 + oldStudent = OtherUtil.deepCopy(existingForUpdate, SchStudent.class); + OtherUtil.setBaseEntityValue(user, entity); + BeanUtils.copyProperties(entity, existingForUpdate, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.status, + EntityFieldNames.abnormalStatus, + EntityFieldNames.transferStatus, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + savedEntity = schStudentRepository.save(existingForUpdate); + // 将保存后的ID回传给entity(用于返回) + entity.setId(savedEntity.getId()); + } + + // 4. 清除缓存 + cacheService.clearClassStudentCache(schId, classId); + + // 5. 构建日志描述(由 LogService 构建,再设置到 LogContextHolder) + String content = logService.buildSaveStudentLog(schId, savedEntity, isNew, oldStudent); + LogContextHolder.setDescription(content); + } + + // ==================== 删除 ==================== + + /** + * 删除学生(批量) + */ + public void deleteStudent(UserContext.UserInfo user, String ids) { + if (ids == null || ids.isEmpty()) { + throw new DException("参数不合法!"); + } + + // 1. 解析ID列表 + List idList = Arrays.stream(ids.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(Integer::parseInt) + .collect(Collectors.toList()); + if (idList.isEmpty()) { + throw new DException("未提供有效学生ID"); + } + + // 2. 批量查询所有学生(确保属于该学校) + List students = schStudentRepository.findAllByIdInAndSchId(idList, user.getSchId()); + if (students.size() != idList.size()) { + // 找出不存在的ID + Set foundIds = students.stream().map(SchStudent::getId).collect(Collectors.toSet()); + List missing = idList.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下学生不存在: " + missing); + } + + // 3. 收集需要清除缓存的班级ID(去重,排除null) + Set classIds = students.stream() + .map(SchStudent::getClassId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 4. 异步记录删除日志(先记录日志,再删除) + logService.deleteStudentLog(user, students, classIds); + + // 5. 执行批量删除(物理删除) + schStudentRepository.deleteAll(students); + + // 6. 清除每个班级的学生缓存 + cacheService.clearClassStudentCaches(user.getSchId(), classIds); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentLogService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentLogService.java new file mode 100644 index 0000000..b1e2410 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentLogService.java @@ -0,0 +1,469 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.enums.StuAbnormalStatus; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.vo.BaseSchClassVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ILogService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 学生日志服务(内部实现,无接口) + * 职责:构建日志描述、异步保存各类操作日志 + */ +@Slf4j +@Service +public class SchStudentLogService { + + @Autowired + private ILogService logService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private SchClassRepository schClassRepository; + + private static final String MODULE_STUDENT = LogModule.STUDENT; + + // ==================== 同步构建日志描述 ==================== + + /** + * 构建学生保存操作的日志描述(供 saveStudent 同步调用) + */ + public String buildSaveStudentLog(Integer schId, SchStudent savedEntity, boolean isNew, SchStudent oldEntity) { + try { + // 1. 获取班级名称(通过班级ID查询) + String className = "未知班级"; + if (savedEntity.getClassId() != null) { + List classList = schClassService.searcBaseSchClass(schId, null, null, savedEntity.getClassId()); + if (!classList.isEmpty()) { + BaseSchClassVO vo = classList.get(0); + className = vo.getGradeName() + vo.getName(); + } + } + + // 2. 构建日志内容 + String content; + if (isNew) { + content = String.format( + "新增学生[姓名:%s, 班级:%s, 学号:%s]成功", + savedEntity.getName(), className, + StringUtils.isNotBlank(savedEntity.getStuClassNo()) ? savedEntity.getStuClassNo() : "无" + ); + } else { + // 记录变更的字段(比较旧实体与保存后的实体) + StringBuilder changeDesc = new StringBuilder(); + // 比较姓名 + if (!StringUtils.equals(oldEntity.getName(), savedEntity.getName())) { + changeDesc.append("姓名: ").append(oldEntity.getName()) + .append(" -> ").append(savedEntity.getName()).append("; "); + } + // 比较班级(若允许修改) + if (!oldEntity.getClassId().equals(savedEntity.getClassId())) { + changeDesc.append("班级: ").append(oldEntity.getClassId()) + .append(" -> ").append(savedEntity.getClassId()).append("; "); + } + // 比较学号 + if (!StringUtils.equals(oldEntity.getStuClassNo(), savedEntity.getStuClassNo())) { + changeDesc.append("学号: ").append(oldEntity.getStuClassNo()) + .append(" -> ").append(savedEntity.getStuClassNo()).append("; "); + } + // 比较排序(如有) + if (oldEntity.getSort() != null && savedEntity.getSort() != null && + !oldEntity.getSort().equals(savedEntity.getSort())) { + changeDesc.append("序号: ").append(oldEntity.getSort()) + .append(" -> ").append(savedEntity.getSort()).append("; "); + } + // 若无变更,显示无变化 + if (changeDesc.length() == 0) { + changeDesc.append("无内容变更"); + } + + content = String.format( + "修改学生[姓名:%s, 班级:%s]:%s", + oldEntity.getName(), className, changeDesc.toString() + ); + } + + return content; + + } catch (Exception e) { + log.error("记录学生保存日志失败", e); + return isNew ? "添加学生日志失败" : "修改学生日志失败"; + } + } + + // ==================== 异步日志方法 ==================== + + /** + * 批量转班日志(每个学生一条) + */ + @Async("logExecutor") + public void transferClassLogs(UserContext.UserInfo user, List students, + Integer targetClassId, Set affectedClassIds) { + try { + LocalDateTime now = LocalDateTime.now(); + // 1. 批量查询所有涉及的班级信息 + List classList = schClassRepository.findAllById(affectedClassIds); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity())); + + // 2. 获取年级名称映射 (schId, null, null 返回所有年级) + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null); + + // 3. 构建班级全称 (年级+班级名) + Map classNameMap = new HashMap<>(); + for (Integer classId : affectedClassIds) { + SchClass clazz = classMap.get(classId); + if (clazz != null) { + String gradeName = gradeNameMap.getOrDefault(clazz.getGradeId(), "未知年级"); + classNameMap.put(classId, gradeName + clazz.getName()); + } else { + classNameMap.put(classId, "未知班级(ID:" + classId + ")"); + } + } + + // 4. 获取目标班级名称 + String targetClassName = classNameMap.getOrDefault(targetClassId, "未知班级"); + + // 5. 循环每个学生,生成独立日志记录 + List logs = new ArrayList<>(); + for (SchStudent student : students) { + String stuName = student.getName(); + String stuNo = student.getStuClassNo(); + String oldClassName = classNameMap.getOrDefault(student.getClassId(), "未知班级"); + String display = stuName + (StringUtils.isNotBlank(stuNo) ? "(" + stuNo + ")" : ""); + + String content = String.format("学生%s从[%s]转班至[%s]", + display, oldClassName, targetClassName); + + OperationLogRecord logRecord = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logs.add(logRecord); + } + + // 6. 批量异步保存所有日志 + if (!logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + + } catch (Exception e) { + log.error("记录批量转班日志失败", e); + } + } + + /** + * 批量修改异常状态日志(每个学生一条) + */ + @Async("logExecutor") + public void setAbnormalStatusLogs(UserContext.UserInfo user, List students, + Integer newStatusId, Set affectedClassIds) { + try { + LocalDateTime now = LocalDateTime.now(); + // 1. 批量查询班级名称 + List classList = schClassRepository.findAllById(affectedClassIds); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity())); + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null); + Map classNameMap = new HashMap<>(); + for (Integer classId : affectedClassIds) { + SchClass clazz = classMap.get(classId); + if (clazz != null) { + String gradeName = gradeNameMap.getOrDefault(clazz.getGradeId(), "未知年级"); + classNameMap.put(classId, gradeName + clazz.getName()); + } else { + classNameMap.put(classId, "未知班级(ID:" + classId + ")"); + } + } + + // 2. 循环每个学生,生成独立日志 + List logRecords = new ArrayList<>(); + for (SchStudent student : students) { + String stuName = student.getName(); + String stuNo = student.getStuClassNo(); + Integer oldStatusId = student.getAbnormalStatus(); // 更新前的状态 + String oldStatusName = StuAbnormalStatus.nameById(oldStatusId); + if (oldStatusName == null) oldStatusName = "未知状态(" + oldStatusId + ")"; + String newStatusName = StuAbnormalStatus.nameById(newStatusId); + if (newStatusName == null) newStatusName = "未知状态(" + newStatusId + ")"; + + String display = stuName + (StringUtils.isNotBlank(stuNo) ? "(" + stuNo + ")" : ""); + String className = classNameMap.getOrDefault(student.getClassId(), "未知班级"); + + String content = String.format("学生%s(%s)异常状态从[%s]更改为[%s]", + display, className, oldStatusName, newStatusName); + + OperationLogRecord logRecord = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logRecords.add(logRecord); + } + + // 3. 批量异步保存日志 + if (!logRecords.isEmpty()) { + logService.saveAllLogAsync(logRecords); + } + + } catch (Exception e) { + log.error("记录批量修改异常状态日志失败", e); + } + } + + /** + * 批量设置转出日志(每个学生一条) + */ + @Async("logExecutor") + public void setTransferOutLog(UserContext.UserInfo user, List students, + Set affectedClassIds) { + try { + LocalDateTime now = LocalDateTime.now(); + // 1. 批量查询班级名称 + List classList = schClassRepository.findAllById(affectedClassIds); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity())); + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null); + Map classNameMap = new HashMap<>(); + for (Integer classId : affectedClassIds) { + SchClass clazz = classMap.get(classId); + if (clazz != null) { + String gradeName = gradeNameMap.getOrDefault(clazz.getGradeId(), "未知年级"); + classNameMap.put(classId, gradeName + clazz.getName()); + } else { + classNameMap.put(classId, "未知班级(ID:" + classId + ")"); + } + } + + // 2. 获取“转出”状态名称 + String outStatusName = TransferStatus.getById(TransferStatus.OUT.getId()).getName(); + if (outStatusName == null) outStatusName = "转出"; + + // 3. 循环每个学生,生成独立日志 + List logRecords = new ArrayList<>(); + for (SchStudent student : students) { + String stuName = student.getName(); + String stuNo = student.getStuClassNo(); + Integer oldTransferStatus = student.getTransferStatus(); // 更新前的状态 + String oldStatusName = TransferStatus.getById(oldTransferStatus).getName(); + if (oldStatusName == null) oldStatusName = "未知状态(" + oldTransferStatus + ")"; + + String display = stuName + (StringUtils.isNotBlank(stuNo) ? "(" + stuNo + ")" : ""); + String className = classNameMap.getOrDefault(student.getClassId(), "未知班级"); + + String content = String.format("学生%s(%s)转学状态从[%s]更改为[%s]", + display, className, oldStatusName, outStatusName); + + OperationLogRecord logRecord = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logRecords.add(logRecord); + } + + // 4. 批量异步保存日志 + if (!logRecords.isEmpty()) { + logService.saveAllLogAsync(logRecords); + } + + } catch (Exception e) { + log.error("记录批量设置转出日志失败", e); + } + } + + /** + * 批量转入日志(每个学生一条) + */ + @Async("logExecutor") + public void setTransferInLog(UserContext.UserInfo user, List toUpdateStudents, + Integer targetSchId, Integer targetClassId) { + try { + String schName = comSchTreeService.getSchoolName(user.getSchId()); + LocalDateTime now = LocalDateTime.now(); + + // 1. 获取目标班级名称(本校) + String targetClassName = "未知班级"; + List targetClassList = schClassService.searcBaseSchClass( + targetSchId, null, null, targetClassId); + if (!targetClassList.isEmpty()) { + BaseSchClassVO vo = targetClassList.get(0); + targetClassName = vo.getGradeName() + vo.getName(); + } + + // 2. 循环每个学生,生成独立日志 + List logRecords = new ArrayList<>(); + for (SchStudent student : toUpdateStudents) { + String stuName = student.getName(); + String stuNo = student.getStuClassNo(); + Integer originalSchId = student.getSchId(); + Integer originalClassId = student.getClassId(); + String originalSchName = comSchTreeService.getSchoolName(originalSchId); + Map gradeMap = baseSchsystemGradeService.getGradeNameMap(originalSchId, null, null); + + // 查询原班级名称(可能跨校) + String originalClassName = "未知班级"; + if (originalSchId != null && originalClassId != null) { + SchClass originalClass = schClassRepository.findByIdAndSchId(originalClassId, originalSchId).orElse(null); + if (originalClass != null) { + originalClassName = gradeMap.get(originalClass.getGradeId()) + originalClass.getName(); + } + } + + String display = stuName + (StringUtils.isNotBlank(stuNo) ? "(" + stuNo + ")" : ""); + String content = String.format("学生%s 从学校[%s]班级[%s] 转入 学校[%s]班级[%s]", + display, originalSchName, originalClassName, schName, targetClassName); + + OperationLogRecord logRecord = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logRecords.add(logRecord); + } + + // 3. 批量异步保存 + if (!logRecords.isEmpty()) { + logService.saveAllLogAsync(logRecords); + } + + } catch (Exception e) { + log.error("记录批量转入日志失败", e); + } + } + + /** + * 批量删除学生日志(每个学生一条) + */ + @Async("logExecutor") + public void deleteStudentLog(UserContext.UserInfo user, List students, + Set affectedClassIds) { + try { + LocalDateTime now = LocalDateTime.now(); + // 1. 批量查询班级名称 + List classList = schClassRepository.findAllById(affectedClassIds); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity())); + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(user.getSchId(), null, null); + Map classNameMap = new HashMap<>(); + for (Integer classId : affectedClassIds) { + SchClass clazz = classMap.get(classId); + if (clazz != null) { + String gradeName = gradeNameMap.getOrDefault(clazz.getGradeId(), "未知年级"); + classNameMap.put(classId, gradeName + clazz.getName()); + } else { + classNameMap.put(classId, "未知班级(ID:" + classId + ")"); + } + } + + // 2. 循环每个学生,生成独立日志 + List logRecords = new ArrayList<>(); + for (SchStudent student : students) { + String stuName = student.getName(); + String stuNo = student.getStuClassNo(); + String display = stuName + (StringUtils.isNotBlank(stuNo) ? "(" + stuNo + ")" : ""); + String className = classNameMap.getOrDefault(student.getClassId(), "未知班级"); + + String content = String.format("删除学生%s(%s)", display, className); + + OperationLogRecord logRecord = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logRecords.add(logRecord); + } + + // 3. 批量异步保存 + if (!logRecords.isEmpty()) { + logService.saveAllLogAsync(logRecords); + } + log.debug("操作人:{},删除学生日志:{}", user.getUserName(), JSON.toJSONString(students)); + } catch (Exception e) { + log.error("记录批量删除学生日志失败", e); + } + } + + /** + * 导入学生日志(每个学生一条) + */ + @Async("logExecutor") + public void importLogs(UserContext.UserInfo user, List saveStudentList, + List gradeList, List schClassList) { + try { + LocalDateTime now = LocalDateTime.now(); + List logs = new ArrayList<>(); + for (SchStudent stu : saveStudentList) { + String content = ""; + Optional schClassOpt = schClassList.stream() + .filter(s -> s.getClassId().equals(stu.getClassId())) + .findFirst(); + if (schClassOpt.isPresent()) { + Integer gradeId = schClassOpt.get().getGradeId(); + String gradeName = gradeList.stream() + .filter(g -> g.getId().equals(gradeId)) + .map(SelectIntVO::getName) + .findFirst() + .orElse("未知年级"); + content = "导入学生[" + stu.getName() + "]成功,用户信息:" + JSON.toJSONString(stu) + + ",所在年级班级:" + gradeName + schClassOpt.get().getName(); + } else { + content = "导入学生[" + stu.getName() + "]成功,用户信息:" + JSON.toJSONString(stu) + ",班级:未知"; + } + OperationLogRecord log = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logs.add(log); + } + if (!logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + log.debug("操作人:{},学生导入日志成功: {}", user.getUserName(), JSON.toJSONString(saveStudentList)); + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",学生导入日志失败: {}", e.getMessage(), e); + } + } + + /** + * 导入学生学号日志(每个学生一条) + */ + @Async("logExecutor") + public void importStudentClassNoLogs(UserContext.UserInfo user, List saveStudentList, + List gradeList, List schClassList) { + try { + LocalDateTime now = LocalDateTime.now(); + List logs = new ArrayList<>(); + for (SchStudent stu : saveStudentList) { + String content = ""; + Optional schClassOpt = schClassList.stream() + .filter(s -> s.getClassId().equals(stu.getClassId())) + .findFirst(); + if (schClassOpt.isPresent()) { + Integer gradeId = schClassOpt.get().getGradeId(); + String gradeName = gradeList.stream() + .filter(g -> g.getId().equals(gradeId)) + .map(SelectIntVO::getName) + .findFirst() + .orElse("未知年级"); + content = "导入学生[" + stu.getName() + "]学号["+stu.getStuClassNo()+"]】成功,用户信息:" + + ",所在年级班级:" + gradeName + schClassOpt.get().getName(); + } + OperationLogRecord log = logService.buildLogRecord(user, MODULE_STUDENT, content, now); + logs.add(log); + } + if (!logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",学生学号导入日志失败: {}", e.getMessage(), e); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentQueryService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentQueryService.java new file mode 100644 index 0000000..aa8af23 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentQueryService.java @@ -0,0 +1,375 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.enums.StuAbnormalStatus; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.*; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class SchStudentQueryService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private IComSchTreeService comSchTreeService; + + // ==================== 公共查询方法 ==================== + + /** + * 通用分页查询(支持年级过滤、班级过滤、关键词、异常状态) + * + * @param schId 学校ID(必填) + * @param gradeIds 年级ID列表(若为null或空,则不过滤年级) + * @param classId 班级ID(若指定且gradeIds非空,则进一步过滤班级) + * @param keyword 关键词(姓名、账号、身份证) + * @param onlyNormal 是否仅查询正常状态(true: 仅正常;false: 非正常) + * @param pageable 分页参数 + * @return 分页结果 + */ + private Page queryStudentsByCondition(Integer schId, List gradeIds, Integer classId, + String keyword, boolean onlyNormal, Pageable pageable) { + // 1. 获取班级ID列表 + List classIds = Collections.emptyList(); + if (gradeIds != null && !gradeIds.isEmpty()) { + classIds = schClassService.getSchClassCacheFilter(schId, gradeIds, classId) + .stream().map(SchClass::getClassId).collect(Collectors.toList()); + if (classIds.isEmpty()) { + return new PageImpl<>(Collections.emptyList(), pageable, 0); + } + } + + // 2. 设置默认排序 + if (!pageable.getSort().isSorted()) { + Sort defaultSort = Sort.by(Sort.Order.asc(EntityFieldNames.groupId), + Sort.Order.asc(EntityFieldNames.classId), + Sort.Order.asc(EntityFieldNames.sort)); + pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), defaultSort); + } + + // 3. 构建查询条件 + Specification spec = buildStudentSpecification(schId, classIds, keyword, onlyNormal, + TransferStatus.IN.getId(), null); + return schStudentRepository.findAll(spec, pageable); + } + + /** + * 构建通用的 Student Specification + * + * @param schId 学校ID + * @param classIds 班级ID列表(可为空或null,若为空则条件为 false) + * @param keyword 搜索关键词 + * @param onlyNormal 是否仅正常状态 + * @param transferStatus 学籍状态(IN/OUT) + * @param abnormalStatus 可指定具体异常状态(若指定则覆盖 onlyNormal 逻辑) + * @return Specification + */ + private Specification buildStudentSpecification(Integer schId, List classIds, + String keyword, boolean onlyNormal, + Integer transferStatus, Integer abnormalStatus) { + return (root, query, cb) -> { + List predicates = new ArrayList<>(); + + // 学校ID必填 + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + + // 学籍状态 + if (transferStatus != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.transferStatus), transferStatus)); + } + + // 异常状态 + if (abnormalStatus != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.abnormalStatus), abnormalStatus)); + } else { + if (onlyNormal) { + predicates.add(cb.equal(root.get(EntityFieldNames.abnormalStatus), StuAbnormalStatus.NORMAL.getId())); + } else { + predicates.add(cb.notEqual(root.get(EntityFieldNames.abnormalStatus), StuAbnormalStatus.NORMAL.getId())); + } + } + + // 班级过滤 + if (classIds != null && !classIds.isEmpty()) { + predicates.add(root.get(EntityFieldNames.classId).in(classIds)); + } else { + // 如果classIds为空,增加永假条件保证无结果 + predicates.add(cb.isNull(root.get(EntityFieldNames.classId))); + } + + // 关键词搜索 + if (keyword != null && !keyword.isEmpty()) { + String likePattern = "%" + keyword + "%"; + Predicate namePredicate = cb.like(root.get(EntityFieldNames.name), likePattern); + Predicate accountPredicate = cb.like(root.get(EntityFieldNames.account), likePattern); + Predicate idCardPredicate = cb.like(root.get(EntityFieldNames.idCard), likePattern); + predicates.add(cb.or(namePredicate, accountPredicate, idCardPredicate)); + } + + return cb.and(predicates.toArray(new Predicate[0])); + }; + } + + // ==================== 基础分页查询(正常/异常,支持年级体系) ==================== + + public PageVO searchBaseSchStudentVO(Integer schId, Integer schsystemId, Integer gradeId, Integer classId, + String keyword, boolean onlyNormal, Pageable pageable) { + // 1. 获取年级ID列表 + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, gradeId); + if (gradeNameMap == null || gradeNameMap.isEmpty()) { + return buildEmptyPageVO(pageable); + } + List gradeIds = new ArrayList<>(gradeNameMap.keySet()); + + // 2. 执行分页查询 + Page page = queryStudentsByCondition(schId, gradeIds, classId, keyword, onlyNormal, pageable); + if (page.isEmpty()) { + return buildEmptyPageVO(pageable); + } + + // 3. 获取班级Map + List classList = schClassService.getSchClassCacheFilter(schId, gradeIds, classId); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity(), (a, b) -> a)); + + // 4. 转换VO + List voList = page.getContent().stream() + .map(entity -> convertToStudentVO(entity, classMap, gradeNameMap, null)) + .collect(Collectors.toList()); + + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), page.getTotalElements(), voList); + } + + + // ==================== 高级查询(职校班,按年级直接查询) ==================== + + public PageVO searchHigherSchStudentVO(Integer schId, Integer gradeId, Integer classId, + String keyword, boolean onlyNormal, Pageable pageable) { + // 1. 若指定了年级或班级,获取班级ID列表 + List gradeIds = (gradeId != null) ? Collections.singletonList(gradeId) : null; + Page page = queryStudentsByCondition(schId, gradeIds, classId, keyword, onlyNormal, pageable); + if (page.isEmpty()) { + return buildEmptyPageVO(pageable); + } + + // 2. 获取班级Map(用于填充年级名称,从班级的enrollYear生成) + List classList = schClassService.getSchClassCacheFilter(schId, gradeId, classId); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity(), (a, b) -> a)); + + // 3. 转换VO(此处年级名称由班级的enrollYear决定,无需年级名称Map) + List voList = page.getContent().stream() + .map(entity -> convertToStudentVO(entity, classMap, null, null)) + .collect(Collectors.toList()); + + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), page.getTotalElements(), voList); + } + + // ==================== 查询(班级学生列表) ==================== + /** + * 无分页查询(支持自定义排序) + */ + public List searchSchClassStudentVO(Integer schId, Integer gradeId, Integer classId, + String keyword, boolean onlyNormal, Sort sort) { + List gradeIds = (gradeId != null) ? Collections.singletonList(gradeId) : null; + // 构建无分页查询,使用Pageable.ofSize(最大条数)?这里直接使用 findAll(spec, sort) + if (sort == null || !sort.isSorted()) { + sort = Sort.by(Sort.Order.asc(EntityFieldNames.groupId), + Sort.Order.asc(EntityFieldNames.classId), + Sort.Order.asc(EntityFieldNames.sort)); + } + // 获取班级ID列表 + List classIds = Collections.emptyList(); + if (gradeIds != null && !gradeIds.isEmpty()) { + classIds = schClassService.getSchClassCacheFilter(schId, gradeIds, classId) + .stream().map(SchClass::getClassId).collect(Collectors.toList()); + } + Specification spec = buildStudentSpecification(schId, classIds, keyword, onlyNormal, + TransferStatus.IN.getId(), null); + List studentList = schStudentRepository.findAll(spec, sort); + + // 转换 + List classList = schClassService.getSchClassCacheFilter(schId, gradeId, classId); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity(), (a, b) -> a)); + return studentList.stream() + .map(entity -> convertToStudentVO(entity, classMap, null, null)) + .collect(Collectors.toList()); + } + + // ==================== 转出学生查询 ==================== + + public PageVO searchTransferOutStudent(Integer schId, Integer gradeId, Integer classId, + String keyword, Pageable pageable) { + // 1. 构建Specification(转出状态,且只查正常异常?业务上只查 normal) + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.transferStatus), TransferStatus.OUT.getId())); + predicates.add(cb.equal(root.get(EntityFieldNames.abnormalStatus), StuAbnormalStatus.NORMAL.getId())); + + if (schId != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + } + if (gradeId != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.gradeId), gradeId)); + } + if (classId != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.classId), classId)); + } + if (keyword != null && !keyword.isEmpty()) { + String likePattern = "%" + keyword + "%"; + Predicate namePredicate = cb.like(root.get(EntityFieldNames.name), likePattern); + Predicate accountPredicate = cb.like(root.get(EntityFieldNames.account), likePattern); + predicates.add(cb.or(namePredicate, accountPredicate)); + } + return cb.and(predicates.toArray(new Predicate[0])); + }; + + // 设置默认排序 + if (!pageable.getSort().isSorted()) { + Sort defaultSort = Sort.by(Sort.Order.asc(EntityFieldNames.groupId), + Sort.Order.asc(EntityFieldNames.classId), + Sort.Order.asc(EntityFieldNames.sort)); + pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), defaultSort); + } + + Page page = schStudentRepository.findAll(spec, pageable); + if (page.isEmpty()) { + return buildEmptyPageVO(pageable); + } + + // 2. 批量加载数据:所有学校的班级和年级映射(避免循环查询) + // 先收集所有涉及的学校ID + Set schoolIds = page.getContent().stream() + .map(SchStudent::getSchId) + .collect(Collectors.toSet()); + + // 一次性获取所有学校的班级列表(可优化为按学校批量查询,但这里假设数据量不大) + Map> schoolClassMap = schoolIds.stream() + .collect(Collectors.toMap(Function.identity(), + sid -> schClassService.getSchClassCacheList(sid))); + + // 一次性获取所有学校的年级名称映射(可能需要schsystemId,若无则传null) + Map> schoolGradeNameMap = schoolIds.stream() + .collect(Collectors.toMap(Function.identity(), + sid -> baseSchsystemGradeService.getGradeNameMap(sid, null, null))); + + // 获取学校名称映射 + List schList = comSchTreeService.getSchoolList(); + Map schNameMap = schList.stream() + .collect(Collectors.toMap(SelectIntVO::getId, SelectIntVO::getName)); + + // 3. 转换VO + List voList = page.getContent().stream() + .map(entity -> { + // 获取该校的班级Map + List classList = schoolClassMap.getOrDefault(entity.getSchId(), Collections.emptyList()); + Map classMap = classList.stream() + .collect(Collectors.toMap(SchClass::getClassId, Function.identity(), (a, b) -> a)); + // 获取该校的年级名称Map + Map gradeNameMap = schoolGradeNameMap.getOrDefault(entity.getSchId(), Collections.emptyMap()); + + SchStudentVO vo = convertToStudentVO(entity, classMap, gradeNameMap, schNameMap); + // 额外设置学校名称(已在convert中设置?没有,需单独设置) + vo.setSchName(schNameMap.getOrDefault(entity.getSchId(), "未知学校")); + return vo; + }) + .collect(Collectors.toList()); + + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), page.getTotalElements(), voList); + } + + // ==================== 工具方法 ==================== + + /** + * 统一VO转换 + * + * @param entity 学生实体 + * @param classMap 班级ID -> 班级实体 + * @param gradeNameMap 年级ID -> 年级名称(若为null,则从班级的enrollYear生成) + * @param schNameMap 学校ID -> 学校名称(可选) + * @return SchStudentVO + */ + private SchStudentVO convertToStudentVO(SchStudent entity, Map classMap, + Map gradeNameMap, Map schNameMap) { + SchStudentVO vo = new SchStudentVO(); + BeanUtils.copyProperties(entity, vo); + + SchClass stuClass = classMap != null ? classMap.get(entity.getClassId()) : null; + if (stuClass != null) { + vo.setGradeId(stuClass.getGradeId()); + // 年级名称:优先从gradeNameMap获取,若为空则用enrollYear拼接 + String gradeName = null; + if (gradeNameMap != null && !gradeNameMap.isEmpty()) { + gradeName = gradeNameMap.get(stuClass.getGradeId()); + } + if (StringUtils.isBlank(gradeName)) { + Integer year = stuClass.getEnrollYear(); + gradeName = year != null ? year + "级" : "未知年级"; + } + vo.setGradeName(gradeName); + // 班级名称 + String stuClassName = StringUtils.isBlank(stuClass.getCname()) ? stuClass.getName() : stuClass.getCname(); + vo.setClassName(stuClassName); + } else { + vo.setGradeName("未知年级"); + vo.setClassName("未知班级"); + } + + // 状态名称 + vo.setStatusName(UserStatus.nameById(entity.getStatus())); + // 异常状态名称 + Integer abnormal = entity.getAbnormalStatus(); + vo.setAbnormalStatusName(abnormal != null ? StuAbnormalStatus.nameById(abnormal) : null); + + // 学校名称(如果提供了) + if (schNameMap != null) { + vo.setSchName(schNameMap.getOrDefault(entity.getSchId(), "未知学校")); + } + + return vo; + } + + private PageVO buildEmptyPageVO(Pageable pageable) { + return new PageVO<>(pageable.getPageNumber() + 1, pageable.getPageSize(), 0, Collections.emptyList()); + } + + // ==================== 教师转出学校下拉列表 ==================== + + public List transferOutSchSelect() { + List schIds = schStudentRepository.findDistinctSchIdsByTransferOut(); + return comSchTreeService.getSchoolList().stream() + .filter(s -> schIds.contains(s.getId())) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentStatusService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentStatusService.java new file mode 100644 index 0000000..ad353db --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentStatusService.java @@ -0,0 +1,76 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.model.dto.StuAbnormalStatusDTO; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 学生异常状态管理服务(内部实现,无接口) + * 职责:批量修改学生的异常状态(如:正常、休学、退学等) + */ +@Slf4j +@Service +public class SchStudentStatusService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private SchStudentCacheService cacheService; + + @Autowired + private SchStudentLogService logService; + + /** + * 批量设置学生异常状态 + * @param user 当前操作用户 + * @param model 包含学生ID列表和目标异常状态ID + */ + public void setAbnormalStatus(UserContext.UserInfo user, StuAbnormalStatusDTO model) { + Integer schId = user.getSchId(); + Date now = new Date(); + Integer currentUserId = user.getUserId(); + + // 1. 批量查询学生(确保属于该学校) + List students = schStudentRepository.findAllByIdInAndSchId(model.getStuIds(), schId); + if (students.size() != model.getStuIds().size()) { + Set foundIds = students.stream().map(SchStudent::getId).collect(Collectors.toSet()); + List missing = model.getStuIds().stream() + .filter(id -> !foundIds.contains(id)) + .collect(Collectors.toList()); + throw new DException("以下学生不存在或不属于该校: " + missing); + } + + // 2. 收集受影响的班级ID(用于清除缓存) + Set classIds = students.stream() + .map(SchStudent::getClassId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 3. 执行批量更新异常状态 + int updated = schStudentRepository.batchUpdateAbnormalStatus( + model.getStuIds(), + model.getAbnormalStatus(), + schId, + now, + currentUserId + ); + if (updated != model.getStuIds().size()) { + throw new DException("批量更新失败,请稍后重试"); + } + + // 4. 清除受影响的班级缓存 + cacheService.clearClassStudentCaches(schId, classIds); + + // 5. 异步记录操作日志 + logService.setAbnormalStatusLogs(user, students, model.getAbnormalStatus(), classIds); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentTransferService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentTransferService.java new file mode 100644 index 0000000..73efc57 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/student/SchStudentTransferService.java @@ -0,0 +1,228 @@ +package com.bestsch.bschclassmanage.service.impl.student; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.model.dto.StuTransferClassDTO; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 学生转班、转出、转入服务(内部实现,无接口) + * 职责:处理学生班级调动、转出和转入操作 + */ +@Slf4j +@Service +public class SchStudentTransferService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private SchStudentCacheService cacheService; + + @Autowired + private SchStudentLogService logService; + + @Autowired + private RedisUtil redisUtil; + + // ==================== 转班 ==================== + + /** + * 批量转班 + */ + public void transferClass(UserContext.UserInfo user, StuTransferClassDTO model) { + Integer schId = user.getSchId(); + Integer targetClassId = model.getTransferClassId(); + List stuIds = model.getStuIds(); + Date now = new Date(); + + // 校验目标班级是否存在且属于该校 + if (!schClassRepository.existsBySchIdAndClassId(schId, targetClassId)) { + throw new DException("目标班级不存在或不属于该学校"); + } + + // 查询学生(用于获取旧班级信息) + List students = schStudentRepository.findAllByIdInAndSchId(stuIds, schId); + if (students.size() != stuIds.size()) { + Set foundIds = students.stream().map(SchStudent::getId).collect(Collectors.toSet()); + List missing = stuIds.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下学生不存在或不属于该校: " + missing); + } + + // 如果所有学生已在目标班级,提前返回 + boolean allAlreadyInTarget = students.stream() + .allMatch(s -> targetClassId.equals(s.getClassId())); + if (allAlreadyInTarget) { + return; + } + + // 收集受影响的班级ID(旧班级 + 新班级) + Set affectedClassIds = students.stream() + .map(SchStudent::getClassId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + affectedClassIds.add(targetClassId); + + // 批量更新班级 + int updated = schStudentRepository.batchUpdateClassId( + stuIds, + targetClassId, + schId, + now, + user.getUserId() + ); + if (updated != stuIds.size()) { + throw new DException("批量更新失败,请稍后重试"); + } + + // 清除缓存(新旧班级都要清除) + cacheService.clearClassStudentCaches(schId, affectedClassIds); + + // 异步记录操作日志 + logService.transferClassLogs(user, students, targetClassId, affectedClassIds); + } + + // ==================== 转出 ==================== + + /** + * 批量转出学生(标记为转出状态) + */ + public void setTransferOut(UserContext.UserInfo user, String ids) { + Integer schId = user.getSchId(); + Date now = new Date(); + Integer currentUserId = user.getUserId(); + + if (StringUtils.isBlank(ids)) { + throw new DException("学生ID列表不能为空"); + } + + // 解析ID列表 + List stuIds = Arrays.stream(ids.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(Integer::parseInt) + .collect(Collectors.toList()); + if (stuIds.isEmpty()) { + throw new DException("未提供有效学生ID"); + } + + // 查询学生(确保属于该校) + List students = schStudentRepository.findAllByIdInAndSchId(stuIds, schId); + if (students.size() != stuIds.size()) { + Set foundIds = students.stream().map(SchStudent::getId).collect(Collectors.toSet()); + List missing = stuIds.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下学生不存在或不属于该校: " + missing); + } + + // 收集受影响的班级ID + Set classIds = students.stream() + .map(SchStudent::getClassId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 批量更新转出状态 + int updated = schStudentRepository.batchUpdateTransferStatus( + stuIds, + TransferStatus.OUT.getId(), + schId, + now, + currentUserId + ); + if (updated != stuIds.size()) { + throw new DException("批量更新失败,请稍后重试"); + } + + // 清除缓存 + cacheService.clearClassStudentCaches(schId, classIds); + + // 异步记录操作日志 + logService.setTransferOutLog(user, students, classIds); + } + + // ==================== 转入 ==================== + + /** + * 批量转入学生(将学生从其他学校/班级转入到目标班级) + */ + public void setTransferIn(UserContext.UserInfo user, StuTransferClassDTO model) { + Integer targetSchId = user.getSchId(); + Integer targetClassId = model.getTransferClassId(); + List stuIds = model.getStuIds(); + Date now = new Date(); + + // 校验目标班级是否属于本校 + schClassRepository.findByClassIdAndSchId(targetClassId, targetSchId) + .orElseThrow(() -> new DException("目标班级不存在")); + + // 全局查询所有学生(必须用 findAllById,因为要跨校查) + List students = schStudentRepository.findAllById(stuIds); + if (students.size() != stuIds.size()) { + Set foundIds = students.stream().map(SchStudent::getId).collect(Collectors.toSet()); + List missing = stuIds.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下学生不存在: " + missing); + } + + // 过滤出真正需要更新的学生:排除已在目标学校且已在目标班级的学生 + List toUpdateStudents = students.stream() + .filter(s -> !(s.getSchId().equals(targetSchId) && targetClassId.equals(s.getClassId()))) + .collect(Collectors.toList()); + + if (toUpdateStudents.isEmpty()) { + // 所有学生已在本校目标班级,无需操作 + return; + } + + // 收集受影响的缓存Key(旧班级 + 新班级) + Set cacheKeysToDelete = new HashSet<>(); + for (SchStudent student : toUpdateStudents) { + if (student.getClassId() != null) { + String oldCacheKey = RedisConstants.SCHOOL_CLASS_STUDENT + "_" + + student.getSchId() + "_" + student.getClassId(); + cacheKeysToDelete.add(oldCacheKey); + } + } + // 新班级缓存(目标学校+目标班级) + String newCacheKey = RedisConstants.SCHOOL_CLASS_STUDENT + "_" + + targetSchId + "_" + targetClassId; + cacheKeysToDelete.add(newCacheKey); + + // 执行批量更新(更新学校和班级) + List idsToUpdate = toUpdateStudents.stream() + .map(SchStudent::getId) + .collect(Collectors.toList()); + + int updated = schStudentRepository.batchUpdateSchIdAndClassId( + idsToUpdate, + targetSchId, + targetClassId, + now, + user.getUserId() + ); + if (updated != idsToUpdate.size()) { + throw new DException("批量更新失败,可能部分学生已被删除或修改,请刷新后重试"); + } + + // 清除缓存(直接按Key删除) + for (String cacheKey : cacheKeysToDelete) { + redisUtil.del(cacheKey); + } + + // 异步记录操作日志 + logService.setTransferInLog(user, toUpdateStudents, targetSchId, targetClassId); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/sync/SyncGroupService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/sync/SyncGroupService.java new file mode 100644 index 0000000..a292222 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/sync/SyncGroupService.java @@ -0,0 +1,62 @@ +package com.bestsch.bschclassmanage.service.impl.sync; + +import com.bestsch.bschclassmanage.Repository.SchInfoRepository; +import com.bestsch.bschclassmanage.entity.SchInfo; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.model.tool.BaseGroup; +import com.bestsch.bschclassmanage.service.ISyncGroupService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; +import java.util.UUID; + +@Service +public class SyncGroupService implements ISyncGroupService { + + @Autowired + private SchInfoRepository schInfoRepository; + + + public void syncAddOrUpdate(BaseGroup group) { + + //学校组 年级组 班级组 + if(group.getType().equals(NodeType.SCHOOL.getId())){ + addOrUpdateSchool(group); + } + if(group.getType().equals(NodeType.CLASS.getId())){ + + + //添加班级组 202406 + //添加班级 gradeid ? + + // 获取年级组 2024 获取当前学校学制 >1 获取学段组 初中 高中 + + } + } + + + public void addOrUpdateSchool(BaseGroup group) + { + Optional schOpt=schInfoRepository.findBySchId(group.getId()); + if(schOpt.isPresent()){ + SchInfo schInfo=schOpt.get(); + schInfo.setName(group.getName()); + schInfo.setSort(group.getNo()); + schInfoRepository.save(schInfo); + }else { + String uuid= UUID.randomUUID().toString().toUpperCase(); + SchInfo schInfo=new SchInfo(); + schInfo.setName(group.getName()); + schInfo.setSchId(group.getId()); + schInfo.setSchSerId(uuid); + schInfo.setSort(group.getNo()); + schInfoRepository.save(schInfo); + } + } + + + + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/sync/SyncUserService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/sync/SyncUserService.java new file mode 100644 index 0000000..72d62bb --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/sync/SyncUserService.java @@ -0,0 +1,361 @@ +package com.bestsch.bschclassmanage.service.impl.sync; + +import com.bestsch.bschclassmanage.Repository.SchInfoRepository; +import com.bestsch.bschclassmanage.Repository.SchStudentRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.entity.SchInfo; +import com.bestsch.bschclassmanage.entity.SchStudent; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.NodeType; +import com.bestsch.bschclassmanage.enums.StuAbnormalStatus; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.enums.UserRole; +import com.bestsch.bschclassmanage.model.tool.BaseGroup; +import com.bestsch.bschclassmanage.model.tool.BaseUser; +import com.bestsch.bschclassmanage.model.tool.DeleteUser; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.service.ISyncUserService; +import com.bestsch.bschclassmanage.service.impl.student.SchStudentCacheService; +import com.bestsch.bschclassmanage.service.impl.teacher.SchTeacherCacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class SyncUserService implements ISyncUserService { + + @Autowired + private SchStudentRepository schStudentRepository; + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private SchStudentCacheService schStudentCacheService; + + @Autowired + private SchTeacherCacheService schTeacherCacheService; + + // ==================== 同步入口 ==================== + @Override + @Transactional(rollbackFor = Exception.class) + public void syncAddOrUpdate(List userList) { + if (userList == null || userList.isEmpty()) return; + + // 按角色分组 + List syncStudentList = new ArrayList<>(); + List syncTeacherList = new ArrayList<>(); + + for (BaseUser user : userList) { + if (isStudent(user)) syncStudentList.add(user); + if (isTeacher(user)) syncTeacherList.add(user); + } + + Date now = new Date(); + + if (!syncStudentList.isEmpty()) { + syncStudents(syncStudentList, now); + } + if (!syncTeacherList.isEmpty()) { + syncTeachers(syncTeacherList, now); + } + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteUser(List deleteUserList) { + if (deleteUserList == null || deleteUserList.isEmpty()) return; + + // 提取所有 userId + List allUserIds = deleteUserList.stream() + .map(DeleteUser::getUserId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (allUserIds.isEmpty()) return; + + // ---------- 1. 物理删除学生 ---------- + List studentDeletes = deleteUserList.stream() + .filter(du -> du.getUserId() != null && du.getGroupId() != null) + .collect(Collectors.toList()); + if (!studentDeletes.isEmpty()) { + // 批量查询学生 + List allStudents = schStudentRepository.findByStuIdIn(allUserIds); + Map studentMap = allStudents.stream() + .collect(Collectors.toMap( + s -> buildStudentKey(s.getStuId(), s.getGroupId()), + Function.identity() + )); + List toDelete = new ArrayList<>(); + for (DeleteUser du : studentDeletes) { + String key = buildStudentKey(du.getUserId(), du.getGroupId()); + SchStudent stu = studentMap.get(key); + if (stu != null) { + toDelete.add(stu); + } + } + if (!toDelete.isEmpty()) { + // 先清除缓存(需要 schId,可从学生实体获取或查询) + for (SchStudent stu : toDelete) { + // 假设 SchStudent 有 schId 字段,若没有则需通过 groupId 查询 + Integer schId = stu.getSchId(); // 若没有,调用 service 查询 + if (schId != null) { + schStudentCacheService.clearClassStudentCache(schId, stu.getGroupId()); + } + } + // 物理删除 + schStudentRepository.deleteAll(toDelete); + } + } + + // ---------- 2. 物理删除教师分组(不删教师主体) ---------- + List teacherDeletes = deleteUserList.stream() + .filter(du -> du.getUserId() != null && du.getGroupId() != null) + .collect(Collectors.toList()); + if (!teacherDeletes.isEmpty()) { + // 查询所有涉及的分组 + List allGroups = schTeacherGroupRepository.findByTeaIdIn(allUserIds); + Map groupMap = allGroups.stream() + .collect(Collectors.toMap( + g -> buildTeacherGroupKey(g.getTeaId(), g.getGroupId()), + Function.identity() + )); + List toDeleteGroups = new ArrayList<>(); + for (DeleteUser du : teacherDeletes) { + String key = buildTeacherGroupKey(du.getUserId(), du.getGroupId()); + SchTeacherGroup group = groupMap.get(key); + if (group != null) { + toDeleteGroups.add(group); + } + } + + if (!toDeleteGroups.isEmpty()) { + // 按学校维度分组,用于缓存清除和剩余分组检查 + Map> groupsBySchool = toDeleteGroups.stream() + .collect(Collectors.groupingBy(SchTeacherGroup::getSchId)); + + // 先清除缓存(针对每个分组所属学校) + for (SchTeacherGroup group : toDeleteGroups) { + schTeacherCacheService.clearTeacherCache(group.getSchId()); + } + + // 物理删除分组 + schTeacherGroupRepository.deleteAll(toDeleteGroups); + + } + } + } + + // ==================== 角色判断 ==================== + private boolean isStudent(BaseUser user) { + if (user.getRoleList() == null) return false; + return user.getRoleList().stream() + .anyMatch(r -> r.getRoleId() != null && r.getRoleId().equals(UserRole.STU_USER.getValue())); + } + + private boolean isTeacher(BaseUser user) { + if (user.getRoleList() == null) return false; + return user.getRoleList().stream() + .anyMatch(r -> r.getRoleId() != null && + (r.getRoleId().equals(UserRole.TEACHER_USER.getValue()) || + r.getRoleId().equals(UserRole.SCH_LEADER_USER.getValue()))); + } + + // ==================== 学生同步 ==================== + private void syncStudents(List studentUsers, Date now) { + List stuIds = studentUsers.stream().map(BaseUser::getId).distinct().collect(Collectors.toList()); + + // 已有学生记录 (stuId, groupId) -> SchStudent + Map studentMap = schStudentRepository.findByStuIdIn(stuIds) + .stream() + .collect(Collectors.toMap( + s -> buildStudentKey(s.getStuId(), s.getGroupId()), + Function.identity() + )); + + List saveList = new ArrayList<>(); + + for (BaseUser user : studentUsers) { + if (user.getGroups() == null) continue; + for (BaseUser.GroupInfo group : user.getGroups()) { + Integer groupId = group.getGroupId(); + Integer schId = group.getSchoolId(); + if (groupId == null || schId == null) continue; + + String key = buildStudentKey(user.getId(), groupId); + SchStudent student = studentMap.get(key); + if (student != null) { + updateStudent(student, user, group, now); + } else { + student = createStudent(user, group, now); + } + saveList.add(student); + } + } + + if (!saveList.isEmpty()) { + schStudentRepository.saveAll(saveList); + // 缓存:将学生加入班级缓存(Set结构) +// for (SchStudent stu : saveList) { +// if (stu.getSchId() != null && stu.getGroupId() != null) { +// schStudentCacheService.addClassStudentCache(stu.getSchId(), stu.getGroupId(), stu.getStuId()); +// } +// } + } + } + + private void updateStudent(SchStudent student, BaseUser user, BaseUser.GroupInfo group, Date now) { + student.setAccount(user.getAccount()); + student.setName(user.getName()); + student.setGender(user.getGender()); + student.setIdCard(user.getIdcard()); + student.setStatus(user.getStatus()); + student.setGroupId(group.getGroupId()); + student.setClassId(group.getGroupId()); + student.setSchId(group.getSchoolId()); + student.setStuClassNo(group.getNo() != null ? String.valueOf(group.getNo()) : null); + student.setUpdateDate(now); + } + + private SchStudent createStudent(BaseUser user, BaseUser.GroupInfo group, Date now) { + SchStudent student = new SchStudent(); + student.setStuId(user.getId()); + student.setAccount(user.getAccount()); + student.setName(user.getName()); + student.setGender(user.getGender()); + student.setIdCard(user.getIdcard()); + student.setStatus(user.getStatus()); + student.setGroupId(group.getGroupId()); + student.setClassId(group.getGroupId()); + student.setSchId(group.getSchoolId()); + student.setStuClassNo(group.getNo() != null ? String.valueOf(group.getNo()) : null); + student.setTransferStatus(TransferStatus.IN.getId()); + student.setAbnormalStatus(StuAbnormalStatus.NORMAL.getId()); + student.setCreateDate(now); + student.setUpdateDate(now); + return student; + } + + // ==================== 教师同步 ==================== + private void syncTeachers(List teacherUsers, Date now) { + List teaIds = teacherUsers.stream().map(BaseUser::getId).distinct().collect(Collectors.toList()); + + // 教师主体(唯一) + Map teacherMap = schTeacherRepository.findByTeaIdIn(teaIds) + .stream() + .collect(Collectors.toMap(SchTeacher::getTeaId, Function.identity())); + + // 教师分组 (teaId, groupId, schId) -> SchTeacherGroup + Map groupMap = schTeacherGroupRepository.findByTeaIdIn(teaIds) + .stream() + .collect(Collectors.toMap( + g -> buildTeacherGroupKeyWithSchId(g.getTeaId(), g.getGroupId(), g.getSchId()), + Function.identity() + )); + + List saveTeacherList = new ArrayList<>(); + List saveGroupList = new ArrayList<>(); + + for (BaseUser user : teacherUsers) { + // 教师主体(只存一条) + SchTeacher teacher = teacherMap.get(user.getId()); + if (teacher != null) { + updateTeacher(teacher, user, now); + } else { + teacher = createTeacher(user, now); + } + saveTeacherList.add(teacher); + + // 教师分组(遍历 groups) + if (user.getGroups() == null) continue; + for (BaseUser.GroupInfo group : user.getGroups()) { + Integer groupId = group.getGroupId(); + Integer schId = group.getSchoolId(); + if (groupId == null || schId == null) continue; + + String key = buildTeacherGroupKeyWithSchId(user.getId(), groupId, schId); + SchTeacherGroup tg = groupMap.get(key); + if (tg != null) { + tg.setTransferStatus(TransferStatus.IN.getId()); + // 如有其他字段更新可在此添加 + } else { + tg = createTeacherGroup(user, group, now); + } + saveGroupList.add(tg); + } + } + + if (!saveTeacherList.isEmpty()) { + schTeacherRepository.saveAll(saveTeacherList); + } + if (!saveGroupList.isEmpty()) { + schTeacherGroupRepository.saveAll(saveGroupList); +// // 缓存:更新教师缓存(学校维度) +// // 为简单起见,清除每个涉及的学校缓存,然后重新添加该学校所有教师(但这里我们只添加本次更新的教师,因为Set可重复) +// // 更稳健:清除后重建,但为了减少数据库查询,我们使用 add 方法 +// for (SchTeacherGroup g : saveGroupList) { +// if (g.getSchId() != null) { +// schTeacherCacheService.addSchoolTeacherCache(g.getSchId(), g.getTeaId()); +// } +// } + } + } + + private void updateTeacher(SchTeacher teacher, BaseUser user, Date now) { + teacher.setAccount(user.getAccount()); + teacher.setName(user.getName()); + teacher.setGender(user.getGender()); + teacher.setIdCard(user.getIdcard()); + teacher.setStatus(user.getStatus() != null ? user.getStatus() : 0); + teacher.setTel(user.getPhone()); + teacher.setUpdateDate(now); + } + + private SchTeacher createTeacher(BaseUser user, Date now) { + SchTeacher teacher = new SchTeacher(); + teacher.setTeaId(user.getId()); + teacher.setAccount(user.getAccount()); + teacher.setName(user.getName()); + teacher.setGender(user.getGender()); + teacher.setIdCard(user.getIdcard()); + teacher.setStatus(user.getStatus() != null ? user.getStatus() : 0); + teacher.setTel(user.getPhone()); + teacher.setCreateDate(now); + teacher.setUpdateDate(now); + return teacher; + } + + private SchTeacherGroup createTeacherGroup(BaseUser user, BaseUser.GroupInfo group, Date now) { + SchTeacherGroup tg = new SchTeacherGroup(); + tg.setTeaId(user.getId()); + tg.setGroupId(group.getGroupId()); + tg.setSchId(group.getSchoolId()); + tg.setTransferStatus(TransferStatus.IN.getId()); + return tg; + } + + // ==================== 辅助键生成 ==================== + private String buildStudentKey(Integer stuId, Integer groupId) { + return stuId + "_" + groupId; + } + + private String buildTeacherGroupKey(Integer teaId, Integer groupId) { + return teaId + "_" + groupId; + } + + private String buildTeacherGroupKeyWithSchId(Integer teaId, Integer groupId, Integer schId) { + return teaId + "_" + groupId + "_" + schId; + } + +} diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherCacheService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherCacheService.java new file mode 100644 index 0000000..13eeca4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherCacheService.java @@ -0,0 +1,84 @@ +package com.bestsch.bschclassmanage.service.impl.teacher; + +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * 教师缓存管理服务(内部实现,无接口) + */ +@Slf4j +@Service +public class SchTeacherCacheService { + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private RedisUtil redisUtil; + + /** + * 从数据库获取该校所有教师(关联表 → 教师表) + */ + public List getSchTeacherList(Integer schId) { + List teaIds = schTeacherGroupRepository.findTeaIdsBySchId(schId); + if (teaIds.isEmpty()) { + return Collections.emptyList(); + } + List teachers = schTeacherRepository.findByTeaIdIn(teaIds); + teachers.sort(Comparator.comparing(SchTeacher::getSort, Comparator.nullsLast(Comparator.naturalOrder()))); + return teachers; + } + + /** + * 缓存版:获取该校所有教师 + */ + public List getSchTeacherCacheList(Integer schId) { + String cacheKey = RedisConstants.SCHOOL_TEACHER + "_" + schId; + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchTeacher.class); + } + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchTeacher.class); + } + List list = getSchTeacherList(schId); + redisUtil.set(cacheKey, list, RedisConstants.CACHE_EXPIRE_1H); + return list; + } + } + + /** + * 清除单个学校的教师缓存 + */ + public void clearTeacherCache(Integer schId) { + if (schId == null) return; + String cacheKey = RedisConstants.SCHOOL_TEACHER + "_" + schId; + redisUtil.del(cacheKey); + log.debug("清除教师缓存:schId={}", schId); + } + + /** + * 批量清除多个学校的教师缓存 + */ + public void clearTeacherCaches(Collection schIds) { + if (schIds == null || schIds.isEmpty()) return; + for (Integer schId : schIds) { + clearTeacherCache(schId); + } + log.debug("批量清除教师缓存:{}", schIds); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherImportService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherImportService.java new file mode 100644 index 0000000..195eea4 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherImportService.java @@ -0,0 +1,232 @@ +package com.bestsch.bschclassmanage.service.impl.teacher; + +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.enums.UserGender; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.excel.ErrorExcelColumn; +import com.bestsch.bschclassmanage.model.excel.TeacherExcelColumn; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.bestsch.bschclassmanage.utils.ValidateUtil; +import com.bestsch.bschclassmanage.utils.ValidationUtil; +import com.yunhai.platform.utils.exception.DException; +import com.yunhai.platform.utils.exception.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 教师导入服务(内部实现,无接口) + */ +@Slf4j +@Service +public class SchTeacherImportService { + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private SchTeacherCacheService cacheService; + + @Autowired + private SchTeacherLogService logService; + + public void importTeachers(UserContext.UserInfo user, MultipartFile file) { + List errorMsgArr = new ArrayList<>(); + ImportParams params = new ImportParams(); + params.setTitleRows(1); + params.setHeadRows(1); + Integer schId = user.getSchId(); + Integer userId = user.getUserId(); + + Date now = new Date(); + try { + List teaGroupNameList = comSchTreeService.getTeaGroupNameList(schId, null); + List list = ExcelImportUtil.importExcel(file.getInputStream(), TeacherExcelColumn.class, params); + + List accountList = list.stream().map(TeacherExcelColumn::getAccount).collect(Collectors.toList()); + if (accountList == null || accountList.isEmpty()) + throw new DException("未找到导入教师用户名!"); + + List teachersByAccounts = getTeachersByAccounts(accountList); + List schTeacherList = cacheService.getSchTeacherList(schId); + List teachers = new ArrayList<>(); + int rows = 0; + for (TeacherExcelColumn item : list) { + SchTeacher teacher = new SchTeacher(); + List teacherGroupList = new ArrayList<>(); + + rows += 2; + + //用户名 + { + if (StringUtils.isBlank(item.getAccount())) { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getAccount(), TeacherExcelColumn.ACCOUNT + "不允许为空!")); + continue; + } + Optional schTeacherOpt = teachersByAccounts.stream().filter(s -> s.getAccount().equals(item.getAccount())).findFirst(); + if (schTeacherOpt.isPresent()) { + BeanUtils.copyProperties(schTeacherOpt.get(), teacher); + teacher.setUpdateDate(now); + teacher.setUpdateUserId(userId); + } else { + teacher.setCreateDate(now); + teacher.setCreateUserId(userId); + teacher.setAccount(item.getAccount()); + teacher.setStatus(UserStatus.NORMAL.getId()); + } + } + //姓名 + { + if (StringUtils.isBlank(item.getTeaName())) { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getTeaName(), TeacherExcelColumn.TEA_NAME + "不允许为空!")); + continue; + } + + boolean nameExists = schTeacherList.stream() + .anyMatch(t -> !t.getId().equals(teacher.getId()) && item.getTeaName().equals(t.getName())); + if (nameExists) { + throw new DException("该校下已存在同名教师:" + item.getTeaName()); + } + + teacher.setName(item.getTeaName()); + } + //组名 + { + if (StringUtils.isBlank(item.getGroupName())) { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getGroupName(), TeacherExcelColumn.GROUP_NAME + "不允许为空!")); + continue; + } + + List teaGroupNameArr = Arrays.asList(item.getGroupName().split(",")); + for (String groupName : teaGroupNameArr) { + + Optional groupNameOpt = teaGroupNameList.stream().filter(s -> s.getName().equals(groupName)).findFirst(); + if (!groupNameOpt.isPresent()) { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getGroupName(), TeacherExcelColumn.GROUP_NAME + "不存在!")); + continue; + } + SchTeacherGroup teacherGroup = new SchTeacherGroup(); + teacherGroup.setGroupId(groupNameOpt.get().getId()); + teacherGroup.setTeaId(teacher.getTeaId()); + teacherGroup.setSchId(schId); + teacherGroup.setTransferStatus(TransferStatus.IN.getId()); + teacherGroupList.add(teacherGroup); + } + teacher.setGroupList(teacherGroupList); + } + //身份证 + { + if (StringUtils.isNotBlank(item.getIdCard())) { + if (!ValidateUtil.isValidIdCard(item.getIdCard())) { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getIdCard(), ValidateUtil.getValidateMessage(item.getIdCard()))); + continue; + } + teacher.setIdCard(item.getIdCard()); + } else { + teacher.setIdCard(null); + } + } + //手机号 + { + if (StringUtils.isNotBlank(item.getTel())) { + if (!ValidateUtil.isValidMobile(item.getTel())) { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getTel(), ValidateUtil.getMobileValidateMessage(item.getTel()))); + continue; + } + teacher.setTel(item.getTel()); + } else { + teacher.setTel(null); + } + } + { + Integer gender = UserGender.FEMALE.getId(); + if (StringUtils.isNotBlank(item.getGender())) { + if (item.getGender().equals(UserGender.MALE.getName())) { + gender = UserGender.MALE.getId(); + } else if (item.getGender().equals(UserGender.FEMALE.getName())) { + gender = UserGender.FEMALE.getId(); + } else { + errorMsgArr.add(new ErrorExcelColumn(rows, item.getGender(), TeacherExcelColumn.GENDER + "不存在!")); + continue; + } + } + teacher.setGender(gender); + + } + //实体验证 + { + List validateMsgs = ValidationUtil.validateMsgs(teacher); + if (validateMsgs.size() > 0) { + errorMsgArr.add(new ErrorExcelColumn(rows, "错误", String.join(",", validateMsgs))); + continue; + } + teachers.add(teacher); + } + + } + + // 若有错误,抛出异常(携带明细) + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + List saveList = schTeacherRepository.saveAll(teachers); + + List schTeacherGroupList = new ArrayList<>(); + for (SchTeacher teacher : saveList) { + teacher.setTeaId(teacher.getId()); + for (SchTeacherGroup group : teacher.getGroupList()) { + group.setTeaId(teacher.getId()); + } + schTeacherGroupList.addAll(teacher.getGroupList()); + } + + List teaIdList = saveList.stream().filter(s -> s.getTeaId() > 0).map(SchTeacher::getTeaId).distinct().collect(Collectors.toList()); + + schTeacherGroupRepository.deleteByTeaIdInAndSchId(teaIdList, schId); + + schTeacherRepository.saveAll(saveList); + schTeacherGroupRepository.saveAll(schTeacherGroupList); + + // 异步日志 + logService.importLogs(user, saveList); + + // 清除缓存 + cacheService.clearTeacherCache(schId); + } catch (DException e) { + throw e; + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",导入教师日志失败: {}", e.getMessage(), e); + throw new DException("导入失败,请联系管理员!
错误详情:
" + e.getMessage()); + } + } + + // ==================== 辅助方法 ==================== + + private List getTeachersByAccounts(List accounts) { + if (accounts == null || accounts.isEmpty()) { + return new ArrayList<>(); + } + return schTeacherRepository.findByAccountIn(accounts); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherInfoService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherInfoService.java new file mode 100644 index 0000000..4f30cc1 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherInfoService.java @@ -0,0 +1,249 @@ +package com.bestsch.bschclassmanage.service.impl.teacher; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.dto.SchTeacherDTO; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.lang.reflect.Array; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 教师基本信息 CRUD 服务(内部实现,无接口) + */ +@Slf4j +@Service +public class SchTeacherInfoService { + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private SchTeacherCacheService cacheService; + + @Autowired + private SchTeacherLogService logService; // 用于构建日志描述 + + // ==================== CRUD ==================== + + public void saveTeacher(UserContext.UserInfo user, SchTeacherDTO dto) { + Date now = new Date(); + Integer schId = user.getSchId(); + Integer groupId = dto.getGroupId(); + Integer userId = user.getUserId(); + + String name = dto.getName(); + Integer id = dto.getId(); + boolean isNew = (id == null || id == 0); + + // 校验目标组是否属于该校 + String groupName = comSchTreeService.getTeaGroupName(schId, groupId); + if (groupName == null) { + throw new DException("指定的组不属于当前学校"); + } + + // 获取该校所有教师的 teaId(通过关联表) + List teaIdsInSchool = schTeacherGroupRepository.findTeaIdsBySchId(schId); + List teachersInSchool = Collections.emptyList(); + if (!teaIdsInSchool.isEmpty()) { + teachersInSchool = schTeacherRepository.findByTeaIdIn(teaIdsInSchool); + } + + SchTeacher savedTeacher; + if (isNew) { + // 新增:检查同名 + boolean nameExists = teachersInSchool.stream() + .anyMatch(t -> name.equals(t.getName())); + if (nameExists) { + throw new DException("该校下已存在同名教师:" + name); + } + + dto.setStatus(UserStatus.NORMAL.getId()); + dto.setCreateDate(now); + dto.setCreateUserId(userId); + SchTeacher teacher = new SchTeacher(); + BeanUtils.copyProperties(dto, teacher); + savedTeacher = schTeacherRepository.save(teacher); + Integer generatedId = savedTeacher.getId(); + savedTeacher.setTeaId(generatedId); + savedTeacher = schTeacherRepository.save(savedTeacher); + + // 插入组关联 + SchTeacherGroup newRelation = new SchTeacherGroup(); + newRelation.setTeaId(savedTeacher.getTeaId()); + newRelation.setGroupId(groupId); + newRelation.setSchId(schId); + newRelation.setTransferStatus(TransferStatus.IN.getId()); + schTeacherGroupRepository.save(newRelation); + + LogContextHolder.setDescription("添加教师:" + savedTeacher.getName()); + } else { + // 更新 + SchTeacher existing = schTeacherRepository.findById(id) + .orElseThrow(() -> new DException("教师不存在,ID=" + id)); + + // 检查同名(排除自身) + boolean nameExists = teachersInSchool.stream() + .anyMatch(t -> !t.getId().equals(id) && name.equals(t.getName())); + if (nameExists) { + throw new DException("该校下已存在同名教师:" + name); + } + + // 校验教师属于该校 + boolean belongs = schTeacherGroupRepository.existsByTeaIdAndSchId(existing.getTeaId(), schId); + if (!belongs) { + throw new DException("教师不属于当前学校,无法修改"); + } + + dto.setUpdateDate(now); + dto.setUpdateUserId(userId); + + // 构建日志描述(委托给 LogService) + String diffDesc = logService.buildEditTeacherLog(user, existing, dto); + LogContextHolder.setDescription(diffDesc); + + // 复制允许修改的字段 + BeanUtils.copyProperties(dto, existing, + EntityFieldNames.id, + EntityFieldNames.teaId, + EntityFieldNames.createDate, + EntityFieldNames.createUserId, + EntityFieldNames.status + ); + schTeacherRepository.save(existing); + savedTeacher = existing; + } + + // 清除缓存 + cacheService.clearTeacherCache(schId); + } + + public void deleteTeacher(UserContext.UserInfo user, String ids) { + if (StringUtils.isBlank(ids)) { + throw new DException("教师ID列表不能为空"); + } + + Integer schId = user.getSchId(); + List idList = Arrays.asList(OtherUtil.convertToArray(ids)); + + // 查询教师 + List teachers = schTeacherRepository.findAllById(idList); + if (teachers.size() != idList.size()) { + Set foundIds = teachers.stream().map(SchTeacher::getId).collect(Collectors.toSet()); + List missing = idList.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下教师不存在: " + missing); + } + + // 校验每个教师属于该校 + for (SchTeacher teacher : teachers) { + Integer teaId = teacher.getTeaId(); + if (teaId == null) { + throw new DException("教师 teaId 为空,数据异常,ID=" + teacher.getId()); + } + boolean belongs = schTeacherGroupRepository.existsByTeaIdAndSchId(teaId, schId); + if (!belongs) { + throw new DException("教师 ID=" + teacher.getId() + " 不属于当前学校,无法删除"); + } + } + + // 校验班主任/副班主任 + List teacherIds = teachers.stream().map(SchTeacher::getId).collect(Collectors.toList()); + long classCount = schClassRepository.countByFirstTeacherIdInOrSecondTeacherIdInAndSchId(teacherIds, schId); + if (classCount > 0) { + throw new DException("选中的教师中有 " + classCount + " 个班级的班主任/副班主任,请先更换"); + } + + // 删除关联组关系(先异步日志,再删除) + List teaIds = teachers.stream() + .map(SchTeacher::getTeaId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (!teaIds.isEmpty()) { + // 异步记录删除日志(由 LogService 处理) + logService.deleteTeacherLogs(user, teachers); + schTeacherGroupRepository.deleteByTeaIdIn(teaIds); + } + + // 清除缓存 + cacheService.clearTeacherCache(schId); + } + + public void setTeacherStatus(UserContext.UserInfo user, String ids, Integer status) { + if (StringUtils.isBlank(ids)) { + throw new DException("教师ID列表不能为空"); + } + if (!UserStatus.list().stream().anyMatch(s -> status.equals(s.getId()))) { + throw new DException("状态不正确"); + } + + Integer schId = user.getSchId(); + List idList = Arrays.asList(OtherUtil.convertToArray(ids)); + + // 查询教师 + List teachers = schTeacherRepository.findAllById(idList); + if (teachers.size() != idList.size()) { + Set foundIds = teachers.stream().map(SchTeacher::getId).collect(Collectors.toSet()); + List missing = idList.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下教师不存在: " + missing); + } + + // 校验属于该校 + List teaIds = teachers.stream() + .map(SchTeacher::getTeaId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (teaIds.size() != idList.size()) { + throw new DException("部分教师缺少 teaId,数据异常"); + } + List groups = schTeacherGroupRepository.findByTeaIdInAndSchId(teaIds, schId); + if (groups.size() != teaIds.size()) { + Set validTeaIds = groups.stream().map(SchTeacherGroup::getTeaId).collect(Collectors.toSet()); + List missing = teaIds.stream().filter(id -> !validTeaIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下教师不属于该校: " + missing); + } + + // 异步记录状态变更日志(由 LogService 处理) + logService.setTeacherStatusLog(user, teachers, status); + + // 执行更新 + int updated = schTeacherRepository.batchUpdateStatus( + idList, + status, + new Date(), + user.getUserId() + ); + if (updated != idList.size()) { + throw new DException("设置状态失败"); + } + + // 清除缓存 + cacheService.clearTeacherCache(schId); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherLogService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherLogService.java new file mode 100644 index 0000000..f71881e --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherLogService.java @@ -0,0 +1,209 @@ +package com.bestsch.bschclassmanage.service.impl.teacher; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.UserGender; +import com.bestsch.bschclassmanage.enums.UserStatus; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.dto.SchTeacherDTO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ILogService; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 教师日志服务(内部实现,无接口) + */ +@Slf4j +@Service +public class SchTeacherLogService { + + @Autowired + private ILogService logService; + + @Autowired + private IComSchTreeService comSchTreeService; + + + // ==================== 构建日志描述(同步) ==================== + + /** + * 构建编辑教师的日志描述 + */ + public String buildEditTeacherLog(UserContext.UserInfo user, SchTeacher old, SchTeacherDTO dto) { + try { + StringJoiner joiner = new StringJoiner(","); + if (!Objects.equals(old.getName(), dto.getName())) { + joiner.add("姓名由" + OtherUtil.nullToStr(old.getName()) + "改为" + OtherUtil.nullToStr(dto.getName())); + } + if (!Objects.equals(old.getAccount(), dto.getAccount())) { + joiner.add("用户名由" + OtherUtil.nullToStr(old.getAccount()) + "改为" + OtherUtil.nullToStr(dto.getAccount())); + } + if (!Objects.equals(old.getIdCard(), dto.getIdCard())) { + joiner.add("身份证由" + OtherUtil.nullToStr(old.getIdCard()) + "改为" + OtherUtil.nullToStr(dto.getIdCard())); + } + if (!Objects.equals(old.getTel(), dto.getTel())) { + joiner.add("手机由" + OtherUtil.nullToStr(old.getTel()) + "改为" + OtherUtil.nullToStr(dto.getTel())); + } + Integer oldGender = old.getGender(); + Integer newGender = dto.getGender(); + if (!Objects.equals(oldGender, newGender)) { + String oldName = oldGender == null ? "null" : UserGender.nameById(oldGender); + String newName = newGender == null ? "null" : UserGender.nameById(newGender); + joiner.add("性别由" + oldName + "改为" + newName); + } + + if (joiner.length() == 0) { + return "编辑教师[" + old.getName() + "]用户信息:无变化"; + } + return "编辑教师[" + old.getName() + "]用户信息:" + joiner.toString(); + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",教师编辑日志失败: {}", e.getMessage(), e); + return "编辑教师[" + old.getName() + "](日志生成异常)"; + } + } + + // ==================== 异步日志方法 ==================== + + @Async("logExecutor") + public void setTeacherStatusLog(UserContext.UserInfo user, List teachers, Integer status) { + try { + LocalDateTime now = LocalDateTime.now(); + List opLogs = new ArrayList<>(); + for (SchTeacher teacher : teachers) { + String oldStatus = UserStatus.getById(teacher.getStatus()).getName(); + String newStatus = UserStatus.getById(status).getName(); + String content = "[" + teacher.getName() + "] 教师状态由 " + oldStatus + " 修改为 " + newStatus; + OperationLogRecord oplog = logService.buildLogRecord(user, LogModule.TEACHER, content, now); + opLogs.add(oplog); + } + if (!opLogs.isEmpty()) { + logService.saveAllLogAsync(opLogs); + } + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",教师状态变更日志失败: {}", e.getMessage(), e); + } + } + + @Async("logExecutor") + public void setTransferOutLogs(UserContext.UserInfo user, List teachers) { + try { + List logs = new ArrayList<>(); + LocalDateTime now = LocalDateTime.now(); + for (SchTeacher teacher : teachers) { + OperationLogRecord log = logService.buildLogRecord(user, LogModule.TEACHER, "[" + teacher.getName() + "] 教师转出成功", now); + logs.add(log); + } + if (!logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",教师转出日志失败: {}", e.getMessage(), e); + } + } + + @Async("logExecutor") + public void setTransferInLogs(UserContext.UserInfo user, List teachers, Integer targetGroupId) { + try { + String schName = comSchTreeService.getSchoolName(user.getSchId()); + List logs = new ArrayList<>(); + LocalDateTime now = LocalDateTime.now(); + for (SchTeacher teacher : teachers) { + String content = "将[" + teacher.getName() + "]教师转入" + schName + ":" + comSchTreeService.getTeaGroupName(user.getSchId(), targetGroupId) + "组"; + OperationLogRecord log = logService.buildLogRecord(user, LogModule.TEACHER, content, now); + logs.add(log); + } + if (logs != null && !logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",教师转入日志失败: {}", e.getMessage(), e); + } + } + + @Async("logExecutor") + public void deleteTeacherLogs(UserContext.UserInfo user, List teachers) { + try { + LocalDateTime now = LocalDateTime.now(); + List logs = new ArrayList<>(); + for (SchTeacher teacher : teachers) { + OperationLogRecord log = logService.buildLogRecord(user, LogModule.TEACHER, "删除[" + teacher.getName() + "] 教师成功", now); + logs.add(log); + } + if (logs != null && !logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + log.debug("操作人:{},删除教师日志:{}", user.getUserName(), JSON.toJSONString(teachers)); + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",删除教师日志失败: {}", e.getMessage(), e); + } + } + + @Async("logExecutor") + public void saveMoveGroupLogs(UserContext.UserInfo user, List teachers, + List oldRelations, + List targetGroupIds) { + try { + LocalDateTime now = LocalDateTime.now(); + Map> oldGroupMap = oldRelations.stream() + .collect(Collectors.groupingBy(SchTeacherGroup::getTeaId)); + + List logs = new ArrayList<>(); + for (SchTeacher teacher : teachers) { + Integer teaId = teacher.getTeaId(); + List oldGroupIds = oldGroupMap.getOrDefault(teaId, Collections.emptyList()) + .stream().map(SchTeacherGroup::getGroupId).collect(Collectors.toList()); + List oldGroupNames = comSchTreeService.getTeaGroupNameList(user.getSchId(), oldGroupIds) + .stream().map(SelectIntVO::getName).collect(Collectors.toList()); + List targetGroupNames = comSchTreeService.getTeaGroupNameList(user.getSchId(), targetGroupIds) + .stream().map(SelectIntVO::getName).collect(Collectors.toList()); + + String desc = String.format("将教师 [%s] 从 [%s] 移动到了 [%s]", + teacher.getName(), + String.join("、", oldGroupNames), + String.join("、", targetGroupNames)); + + OperationLogRecord log = logService.buildLogRecord(user, LogModule.TEACHER, desc, now); + logs.add(log); + } + if (logs != null && !logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",移动教师组日志失败: {}", e.getMessage(), e); + } + } + + @Async("logExecutor") + public void importLogs(UserContext.UserInfo user, List teachers) { + try { + LocalDateTime now = LocalDateTime.now(); + List logs = new ArrayList<>(); + for (SchTeacher teacher : teachers) { + List groupIds = teacher.getGroupList().stream().map(s -> s.getGroupId()).collect(Collectors.toList()); + List groupNames = comSchTreeService.getTeaGroupNameList(user.getSchId(), groupIds) + .stream().map(SelectIntVO::getName).collect(Collectors.toList()); + String content = "导入教师[" + teacher.getName() + "]成功,用户信息:" + JSON.toJSONString(teacher) + ",所在组:" + String.join(",", groupNames); + OperationLogRecord log = logService.buildLogRecord(user, LogModule.TEACHER, content, now); + logs.add(log); + } + if (logs != null && !logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + log.error("操作人:" + user.getUserName() + ",教师导入日志成功: {}", JSON.toJSONString(teachers)); + } catch (Exception e) { + log.error("操作人:" + user.getUserName() + ",教师导入日志失败: {}", e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java new file mode 100644 index 0000000..748e65a --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java @@ -0,0 +1,259 @@ +package com.bestsch.bschclassmanage.service.impl.teacher; + +import com.bestsch.bschclassmanage.Repository.SchClassRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherGroupRepository; +import com.bestsch.bschclassmanage.Repository.SchTeacherRepository; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.entity.SchTeacherGroup; +import com.bestsch.bschclassmanage.enums.TransferStatus; +import com.bestsch.bschclassmanage.model.dto.TeaTransferGroupDTO; +import com.bestsch.bschclassmanage.model.dto.TeaTransferInGroupDTO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 教师关联关系服务(转入/转出/移动组)(内部实现,无接口) + */ +@Slf4j +@Service +public class SchTeacherRelationService { + + @Autowired + private SchTeacherRepository schTeacherRepository; + + @Autowired + private SchTeacherGroupRepository schTeacherGroupRepository; + + @Autowired + private SchClassRepository schClassRepository; + + @Autowired + private IComSchTreeService comSchTreeService; + + @Autowired + private SchTeacherCacheService cacheService; + + @Autowired + private SchTeacherLogService logService; // 异步日志 + + // ==================== 转出 ==================== + + public void setTransferOut(UserContext.UserInfo user, String ids) { + if (StringUtils.isBlank(ids)) { + throw new DException("教师ID列表不能为空"); + } + + Integer schId = user.getSchId(); + List idList = Arrays.asList(OtherUtil.convertToArray(ids)); + + // 1. 查询教师 + List teachers = schTeacherRepository.findAllById(idList); + if (teachers.size() != idList.size()) { + Set foundIds = teachers.stream().map(SchTeacher::getId).collect(Collectors.toSet()); + List missing = idList.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下教师不存在: " + missing); + } + + // 2. 校验教师是否属于该校 + List teaIds = teachers.stream() + .map(SchTeacher::getTeaId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (teaIds.size() != teachers.size()) { + throw new DException("部分教师缺少 teaId,数据异常"); + } + + List groups = schTeacherGroupRepository.findByTeaIdIn(teaIds); + Map> groupMap = groups.stream() + .collect(Collectors.groupingBy(SchTeacherGroup::getTeaId)); + + for (SchTeacher teacher : teachers) { + List teacherGroups = groupMap.getOrDefault(teacher.getTeaId(), Collections.emptyList()); + boolean belongs = teacherGroups.stream().anyMatch(g -> g.getSchId().equals(schId)); + if (!belongs) { + throw new DException("教师 " + teacher.getName() + " 不属于当前学校,无法转出"); + } + } + + // 3. 校验班主任/副班主任 + List teacherIds = teachers.stream().map(SchTeacher::getId).collect(Collectors.toList()); + long classCount = schClassRepository.countByFirstTeacherIdInOrSecondTeacherIdInAndSchId(teacherIds, schId); + if (classCount > 0) { + throw new DException("选中的教师中有 " + classCount + " 个班级的班主任/副班主任,请先更换"); + } + + // 4. 更新状态为转出 + int updated = schTeacherGroupRepository.batchUpdateTransferStatus( + idList, + schId, + TransferStatus.OUT.getId() + ); + if (updated != idList.size()) { + throw new DException("转出失败"); + } + + // 5. 异步日志 + logService.setTransferOutLogs(user, teachers); + + // 6. 清除缓存 + cacheService.clearTeacherCache(schId); + } + + // ==================== 转入 ==================== + + public void setTransferIn(UserContext.UserInfo user, TeaTransferInGroupDTO model) { + Integer targetSchId = user.getSchId(); + List schTeaIds = model.getSchTeaIds(); + Integer targetGroupId = model.getTransferGroupId(); + + if (schTeaIds == null || schTeaIds.isEmpty()) { + throw new DException("教师关联列表不能为空"); + } + if (targetGroupId == null || targetGroupId <= 0) { + throw new DException("目标组ID不合法"); + } + + // 校验目标组属于当前学校 + comSchTreeService.validateGroupsBelongToSchool(targetSchId, Collections.singletonList(targetGroupId)); + + // 解析 schTeaIds + List oldRelations = new ArrayList<>(); + List teaIdList = new ArrayList<>(); + + for (String item : schTeaIds) { + String[] parts = item.split("_"); + if (parts.length != 2) { + throw new DException("无效的教师关联格式: " + item + ",应为 'schId_teaId'"); + } + Integer schId, teaId; + try { + schId = Integer.parseInt(parts[0]); + teaId = Integer.parseInt(parts[1]); + } catch (NumberFormatException e) { + throw new DException("教师关联包含非数字字符: " + item); + } + + List relations = schTeacherGroupRepository.findByTeaIdAndSchId(teaId, schId); + if (relations.isEmpty()) { + throw new DException("教师 teaId=" + teaId + " 在学校 schId=" + schId + " 下无关联记录"); + } + oldRelations.addAll(relations); + teaIdList.add(teaId); + } + + teaIdList = teaIdList.stream().distinct().collect(Collectors.toList()); + + // 删除所有旧关联 + if (!oldRelations.isEmpty()) { + schTeacherGroupRepository.deleteAll(oldRelations); + } + + // 插入新关联 + List newRelations = new ArrayList<>(); + for (Integer teaId : teaIdList) { + SchTeacherGroup newRel = new SchTeacherGroup(); + newRel.setTeaId(teaId); + newRel.setGroupId(targetGroupId); + newRel.setSchId(targetSchId); + newRel.setTransferStatus(TransferStatus.IN.getId()); + newRelations.add(newRel); + } + + if (!newRelations.isEmpty()) { + List teachers = schTeacherRepository.findByTeaIdIn(teaIdList); + logService.setTransferInLogs(user, teachers, targetGroupId); + schTeacherGroupRepository.saveAll(newRelations); + } + + // 清除所有涉及学校的缓存 + Set involvedSchIds = new HashSet<>(); + involvedSchIds.add(targetSchId); + oldRelations.forEach(r -> involvedSchIds.add(r.getSchId())); + cacheService.clearTeacherCaches(involvedSchIds); + } + + // ==================== 移动组 ==================== + public void moveGroup(UserContext.UserInfo user, TeaTransferGroupDTO model) { + Integer schId = user.getSchId(); + List ids = model.getIds(); + List targetGroupIds = model.getTransferGroupIds(); + + if (ids == null || ids.isEmpty()) { + throw new DException("教师ID列表不能为空"); + } + if (targetGroupIds == null || targetGroupIds.isEmpty()) { + throw new DException("目标组列表不能为空"); + } + + // 校验目标组 + comSchTreeService.validateGroupsBelongToSchool(schId, targetGroupIds); + + // 查询教师 + List teachers = schTeacherRepository.findAllById(ids); + if (teachers.size() != ids.size()) { + Set foundIds = teachers.stream().map(SchTeacher::getId).collect(Collectors.toSet()); + List missing = ids.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); + throw new DException("以下教师不存在: " + missing); + } + + List teaIdList = teachers.stream() + .map(SchTeacher::getTeaId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (teaIdList.size() != ids.size()) { + throw new DException("部分教师缺少 teaId,数据异常"); + } + + // 校验教师属于该校 + List oldRelations = schTeacherGroupRepository.findByTeaIdInAndSchId(teaIdList, schId); + if (oldRelations.size() != teaIdList.size()) { + Set existingTeaIds = oldRelations.stream() + .map(SchTeacherGroup::getTeaId) + .collect(Collectors.toSet()); + List missingTeaIds = teaIdList.stream() + .filter(id -> !existingTeaIds.contains(id)) + .collect(Collectors.toList()); + List missingTeachers = schTeacherRepository.findByTeaIdIn(missingTeaIds); + String names = missingTeachers.stream() + .map(t -> t.getName() + "(ID:" + t.getId() + ")") + .collect(Collectors.joining(",")); + throw new DException("以下教师不属于当前学校,无法移动: " + names); + } + + // 异步日志 + logService.saveMoveGroupLogs(user, teachers, oldRelations, targetGroupIds); + + // 删除旧关联 + schTeacherGroupRepository.deleteByTeaIdInAndSchId(teaIdList, schId); + + // 插入新关联 + List newRelations = new ArrayList<>(); + for (Integer teaId : teaIdList) { + for (Integer groupId : targetGroupIds) { + SchTeacherGroup rel = new SchTeacherGroup(); + rel.setTeaId(teaId); + rel.setGroupId(groupId); + rel.setSchId(schId); + rel.setTransferStatus(TransferStatus.IN.getId()); + newRelations.add(rel); + } + } + if (!newRelations.isEmpty()) { + schTeacherGroupRepository.saveAll(newRelations); + } + + // 清除缓存 + cacheService.clearTeacherCache(schId); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachCacheService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachCacheService.java new file mode 100644 index 0000000..11bb4f0 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachCacheService.java @@ -0,0 +1,206 @@ +package com.bestsch.bschclassmanage.service.impl.teachs; + +import com.bestsch.bschclassmanage.Repository.SchClassTeachRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.utils.RedisConstants; +import com.bestsch.bschclassmanage.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 任教缓存管理服务(内部实现,无接口) + * 职责:管理任教记录的缓存读写和清除 + */ +@Slf4j +@Service +public class SchClassTeachCacheService { + + @Autowired + private SchClassTeachRepository schClassTeachRepository; + +// @Autowired +// private SchClassTeachQueryService queryService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private RedisUtil redisUtil; + + /** + * 根据学校、年级、班级查询任教记录(直接从数据库) + * + * @param schId 学校ID(必填) + * @param gradeId 年级ID(可选) + * @param classId 班级ID(可选) + * @return 任教记录列表 + */ + public List getSchClassTeachList(Integer schId, Integer gradeId, Integer classId) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + + if (gradeId != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.gradeId), gradeId)); + } + if (classId != null) { + predicates.add(cb.equal(root.get(EntityFieldNames.classId), classId)); + } + + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schClassTeachRepository.findAll(spec); + } + + + /** + * 获取单个班级的任教记录(带缓存) + * 使用双重检查锁防止缓存击穿 + */ + public List getClassTeachList(Integer schId, Integer classId) { + String cacheKey = RedisConstants.SCHOOL_CLASS_TEACH + schId + "_" + classId; + + // 1. 查缓存 + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchClassTeach.class); + } + + // 2. 缓存未命中,同步查询数据库(防止缓存击穿) + synchronized (this) { + if (redisUtil.hasKey(cacheKey)) { + return redisUtil.getList(cacheKey, SchClassTeach.class); + } + + // 从数据库查询 + List list = getSchClassTeachList(schId, null, classId); + if (list == null) { + list = Collections.emptyList(); + } + + // 写入缓存(30天过期,因为任教数据相对稳定) + redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + log.debug("任教缓存已加载:schId={}, classId={}, size={}", schId, classId, list.size()); + return list; + } + } + + /** + * 批量获取多个班级的任教记录 + */ + public Map> getClassTeachBatchMap(Integer schId, List classIds) { + if (classIds == null || classIds.isEmpty()) { + return Collections.emptyMap(); + } + + // 1. 构建所有缓存 Key + List keys = classIds.stream() + .map(cid -> RedisConstants.SCHOOL_CLASS_TEACH + schId + "_" + cid) + .collect(Collectors.toList()); + + // 2. 批量获取缓存 + Map> cacheMap = redisUtil.mgetList(keys, SchClassTeach.class); + + // 3. 提取缺失的班级(缓存未命中) + Set missingClassIds = new HashSet<>(); + Map> resultMap = new HashMap<>(); + + for (Integer cid : classIds) { + String key = RedisConstants.SCHOOL_CLASS_TEACH + schId + "_" + cid; + List cached = cacheMap.get(key); + if (cached != null) { + resultMap.put(cid, cached); + } else { + missingClassIds.add(cid); + } + } + + // 4. 批量查询缺失的班级(从数据库) + if (!missingClassIds.isEmpty()) { + // 使用 IN 查询一次性获取所有缺失班级的任教记录 + List dbList = schClassTeachRepository + .findBySchIdAndClassIdIn(schId, new ArrayList<>(missingClassIds)); + + // 按 classId 分组 + Map> dbMap = dbList.stream() + .collect(Collectors.groupingBy(SchClassTeach::getClassId)); + + // 5. 批量写入缓存 + for (Integer cid : missingClassIds) { + List list = dbMap.getOrDefault(cid, Collections.emptyList()); + String key = RedisConstants.SCHOOL_CLASS_TEACH + schId + "_" + cid; + redisUtil.set(key, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D); + resultMap.put(cid, list); + } + } + + return resultMap; + } + + /** + * 清除单个班级的任教缓存 + * @param schId 学校ID(必填) + * @param classId 班级ID(可选,为null时清除该校所有班级的任教缓存) + */ + public void clearTeachCache(Integer schId, Integer classId) { + if (schId == null) { + log.warn("clearTeachCache: schId is null, skip"); + return; + } + + // 情况1:清除指定班级的任教缓存 + if (classId != null && classId > 0) { + String cacheKey = RedisConstants.SCHOOL_CLASS_TEACH + schId + "_" + classId; + redisUtil.del(cacheKey); + log.debug("清除任教缓存:schId={}, classId={}", schId, classId); + return; + } + + // 情况2:清除该校所有班级的任教缓存 + List classList = schClassService.getSchClassCacheList(schId); + if (classList == null || classList.isEmpty()) { + log.debug("清除任教缓存:该校无班级,schId={}", schId); + return; + } + + // 批量删除所有班级的缓存键 + List keys = new ArrayList<>(classList.size()); + for (SchClass clazz : classList) { + keys.add(RedisConstants.SCHOOL_CLASS_TEACH + schId + "_" + clazz.getClassId()); + } + + redisUtil.del(keys.toArray(new String[0])); + log.debug("批量清除任教缓存:schId={}, 班级数={}", schId, keys.size()); + } + +// /** +// * 批量清除多个班级的任教缓存 +// * @param schId 学校ID +// * @param classIds 班级ID集合 +// */ +// public void clearTeachCaches(Integer schId, Set classIds) { +// if (schId == null || classIds == null || classIds.isEmpty()) { +// return; +// } +// for (Integer classId : classIds) { +// clearTeachCache(schId, classId); +// } +// log.debug("批量清除任教缓存:schId={}, classIds={}", schId, classIds); +// } +// +// public void clearTeachCaches(Integer schId) { +// Set keys = redisUtil.keys(RedisConstants.SCHOOL_CLASS_TEACH + schId + "_*"); +// if (keys != null && !keys.isEmpty()) { +// redisUtil.del(keys.toArray(new String[0])); +// } +// log.debug("批量清除任教缓存:schId={}", schId); +// } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachImportService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachImportService.java new file mode 100644 index 0000000..96650c0 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachImportService.java @@ -0,0 +1,307 @@ +package com.bestsch.bschclassmanage.service.impl.teachs; + +import com.bestsch.bschclassmanage.Repository.SchClassTeachRepository; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.model.excel.ErrorExcelColumn; +import com.bestsch.bschclassmanage.model.vo.BaseSchClassVO; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.service.ISchDicSubjectService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import com.yunhai.platform.utils.exception.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 任教导入服务(内部实现,无接口) + * 职责:处理任教记录的 Excel 导入 + */ +@Slf4j +@Service +public class SchClassTeachImportService { + + @Autowired + private SchClassTeachRepository schClassTeachRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchDicSubjectService schDicSubjectService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private SchClassTeachCacheService cacheService; + + @Autowired + private SchClassTeachQueryService queryService; + + @Autowired + private SchClassTeachLogService logService; + + /** + * 导入任教记录 + * + * @param user 当前操作用户 + * @param file 上传的 Excel 文件 + * @param schsystemId 学制ID(用于过滤年级/学科) + * @param gradeId 年级ID(可选,用于过滤班级) + */ + @Transactional(rollbackFor = Exception.class) + public void importTeach(UserContext.UserInfo user, MultipartFile file, Integer schsystemId, Integer gradeId) { + List errorMsgArr = new ArrayList<>(); + Integer schId = user.getSchId(); + Integer userId = user.getUserId(); + Date now = new Date(); + + // 1. 加载基础数据 + // 1.1 班级列表(按学制和年级过滤) + List schClassList = schClassService.searcBaseSchClass(schId, schsystemId, gradeId, null); + // 1.2 学科列表(按学制过滤) + List schSubList = schDicSubjectService.select(schId, schsystemId); + // 1.3 教师列表(全校) + List schTeacherList = schTeacherService.getSchTeacherList(schId); + // 1.4 已有的任教记录(用于判断新增/更新/删除) + List schClassTeachList = queryService.getSchClassTeachCacheList(schId, gradeId, null); + + // 构建快速查找 Map + // 年级名称 -> 年级VO(用于校验年级是否存在) + Map gradeNameMap = schClassList.stream() + .collect(Collectors.toMap(BaseSchClassVO::getGradeName, Function.identity(), (a, b) -> a)); + + // 年级ID + 班级名称 -> 班级VO(用于校验班级是否存在) + Map classKeyMap = schClassList.stream() + .collect(Collectors.toMap( + vo -> vo.getGradeId() + "_" + vo.getName(), + Function.identity(), + (a, b) -> a + )); + + // 教师姓名 -> 教师实体(用于获取教师ID) + Map teacherNameMap = schTeacherList.stream() + .collect(Collectors.toMap(SchTeacher::getName, Function.identity(), (a, b) -> a)); + + // 学科名称 -> 学科VO(用于获取学科ID) + Map subjectNameMap = schSubList.stream() + .collect(Collectors.toMap(SelectStrVO::getName, Function.identity(), (a, b) -> a)); + + // 已有任教记录的键:年级ID_班级ID_学科ID -> 任教实体 + Map existTeachMap = schClassTeachList.stream() + .collect(Collectors.toMap( + t -> t.getGradeId() + "_" + t.getClassId() + "_" + t.getSubId(), + Function.identity(), + (a, b) -> a + )); + + // 2. 读取 Excel 并校验表头 + try (InputStream is = file.getInputStream()) { + Workbook workbook = WorkbookFactory.create(is); + Sheet sheet = workbook.getSheetAt(0); + Row header = sheet.getRow(0); + if (header == null) { + throw new DException("模板表头为空"); + } + + // 获取所有列名 + List columnNames = new ArrayList<>(); + for (int i = 0; i < header.getLastCellNum(); i++) { + columnNames.add(getCellString(header.getCell(i))); + } + + // 期望的列名:年级、班级 + 所有学科名称 + List expectedHeaders = new ArrayList<>(); + expectedHeaders.add("年级"); + expectedHeaders.add("班级"); + expectedHeaders.addAll(subjectNameMap.keySet()); + + // 校验是否有多余列(不在期望中的列) + List extraColumns = columnNames.stream() + .filter(col -> !expectedHeaders.contains(col)) + .collect(Collectors.toList()); + if (!extraColumns.isEmpty()) { + for (String col : extraColumns) { + errorMsgArr.add(new ErrorExcelColumn(1, "模板", "表头:" + col + "不存在")); + } + // 直接抛出异常,不再继续处理 + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + // 3. 逐行处理数据 + List addTeachList = new ArrayList<>(); + List delTeachList = new ArrayList<>(); + Set classIdSet = new HashSet<>(); + + for (int r = 1; r <= sheet.getLastRowNum(); r++) { + Row row = sheet.getRow(r); + if (row == null) continue; + int currentRow = r + 1; // Excel行号从1开始 + + // 读取年级、班级 + String gradeName = getCellString(row.getCell(0)); + String className = getCellString(row.getCell(1)); + + if (StringUtils.isEmpty(gradeName) || StringUtils.isEmpty(className)) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, gradeName + className, "年级/班级不能为空")); + continue; + } + + // 校验年级是否存在 + BaseSchClassVO gradeVO = gradeNameMap.get(gradeName); + if (gradeVO == null) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, gradeName, "年级不存在")); + continue; + } + Integer gradeIdFromExcel = gradeVO.getGradeId(); + + // 校验班级是否存在(年级+班级名组合) + String classKey = gradeIdFromExcel + "_" + className; + BaseSchClassVO classVO = classKeyMap.get(classKey); + if (classVO == null) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, gradeName + className, "班级不存在")); + continue; + } + Integer classIdVal = classVO.getClassId(); + + // 遍历学科列(从第3列开始) + for (int c = 2; c < columnNames.size(); c++) { + String subName = columnNames.get(c); + if (subName.equals("年级") || subName.equals("班级")) continue; + + // 获取学科ID + SelectStrVO subject = subjectNameMap.get(subName); + if (subject == null) continue; // 理论上不会发生,因为表头已校验 + + // 获取任课教师姓名 + String teaName = getCellString(row.getCell(c)); + Integer teaId = null; + if (StringUtils.isNotBlank(teaName)) { + SchTeacher teacher = teacherNameMap.get(teaName); + if (teacher == null) { + errorMsgArr.add(new ErrorExcelColumn(currentRow, teaName, subName + "任教教师不存在")); + continue; + } + teaId = teacher.getTeaId(); + } + + // 构建唯一键:年级ID_班级ID_学科ID + String teachKey = gradeIdFromExcel + "_" + classIdVal + "_" + subject.getId(); + SchClassTeach existing = existTeachMap.get(teachKey); + + if (existing != null) { + // 已存在记录 + if (teaId == null) { + // 如果教师为空,则删除该记录 + delTeachList.add(existing); + classIdSet.add(classIdVal); + } else { + // 如果教师不为空,则更新 + existing.setTeaId(teaId); + existing.setUpdateDate(now); + existing.setUpdateUserId(userId); + addTeachList.add(existing); + classIdSet.add(classIdVal); + } + } else { + // 不存在记录,且教师不为空 -> 新增 + if (teaId != null) { + SchClassTeach newTeach = new SchClassTeach(); + newTeach.setGradeId(gradeIdFromExcel); + newTeach.setClassId(classIdVal); + newTeach.setTeaId(teaId); + newTeach.setSubId(subject.getId()); + newTeach.setCreateDate(now); + newTeach.setCreateUserId(userId); + newTeach.setSchId(schId); + addTeachList.add(newTeach); + classIdSet.add(classIdVal); + } + } + } + } + + // 4. 如果有错误,抛出异常(携带明细) + if (!errorMsgArr.isEmpty()) { + throw new DException(ErrorCode.CUSTOM,"导入失败,请检查错误列表",errorMsgArr); + } + + // 5. 批量保存/删除 + if (!addTeachList.isEmpty()) { + schClassTeachRepository.saveAll(addTeachList); + } + if (!delTeachList.isEmpty()) { + schClassTeachRepository.deleteAll(delTeachList); + } + + // 6. 清除受影响的班级缓存 + for (Integer cid : classIdSet) { + cacheService.clearTeachCache(schId, cid); + } + + // 7. 记录操作日志(异步) + logService.importLogs(user, addTeachList, delTeachList, schClassList, schSubList, schTeacherList); + + } catch (DException e) { + throw e; + } catch (Exception e) { + log.error("导入任教失败", e); + throw new DException("导入失败:" + e.getMessage()); + } + } + + /** + * 获取单元格字符串值(兼容多种类型) + * + * @param cell Excel 单元格 + * @return 单元格内容的字符串表示 + */ + private String getCellString(Cell cell) { + if (cell == null) return ""; + switch (cell.getCellType()) { + case STRING: + return cell.getStringCellValue().trim(); + case NUMERIC: + // 如果是日期或数字,转为字符串 + if (DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue().toString(); + } else { + // 避免科学计数法 + double val = cell.getNumericCellValue(); + if (val == (long) val) { + return String.valueOf((long) val); + } else { + return String.valueOf(val); + } + } + case BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case FORMULA: + try { + return cell.getStringCellValue(); + } catch (Exception e) { + return String.valueOf(cell.getNumericCellValue()); + } + default: + return ""; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachInfoService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachInfoService.java new file mode 100644 index 0000000..a0f5b4f --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachInfoService.java @@ -0,0 +1,214 @@ +package com.bestsch.bschclassmanage.service.impl.teachs; + +import com.bestsch.bschclassmanage.Repository.SchClassTeachRepository; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.service.IBaseSchsystemGradeService; +import com.bestsch.bschclassmanage.utils.LogContextHolder; +import com.bestsch.bschclassmanage.utils.OtherUtil; +import com.bestsch.bschclassmanage.utils.UserContext; +import com.yunhai.platform.utils.exception.DException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 任教信息管理服务(内部实现,无接口) + * 职责:任教记录的增删改操作 + */ +@Slf4j +@Service +public class SchClassTeachInfoService { + + @Autowired + private SchClassTeachRepository schClassTeachRepository; + + @Autowired + private SchClassTeachCacheService cacheService; + + @Autowired + private SchClassTeachQueryService queryService; + + @Autowired + private SchClassTeachLogService logService; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + // ==================== 保存 ==================== + + /** + * 保存任教记录(新增或修改) + * + * @param user 当前操作用户 + * @param entity 任教实体 + */ + public void saveTeach(UserContext.UserInfo user, SchClassTeach entity) { + Integer schId = user.getSchId(); + + // 1. 参数校验 + if (entity == null) { + throw new DException("任教记录不能为空"); + } + if (entity.getClassId() == null || entity.getClassId() <= 0) { + throw new DException("班级ID无效"); + } + if (StringUtils.isBlank(entity.getSubId())) { + throw new DException("学科ID不能为空"); + } + + // 2. 根据业务键查询是否存在 + SchClassTeach existing = schClassTeachRepository + .findBySchIdAndClassIdAndSubId(schId, entity.getClassId(), entity.getSubId()) + .orElse(null); + + SchClassTeach savedEntity; + boolean isNew = (existing == null); + Integer oldTeaId = null; + + if (isNew) { + // 新增 + OtherUtil.setBaseEntityValue(user, entity); + savedEntity = schClassTeachRepository.save(entity); + } else { + // 更新:记录旧教师ID + oldTeaId = existing.getTeaId(); + existing.setTeaId(entity.getTeaId()); + OtherUtil.setBaseEntityValue(user, entity); + BeanUtils.copyProperties(entity, existing, + EntityFieldNames.id, + EntityFieldNames.schId, + EntityFieldNames.createDate, + EntityFieldNames.createUserId); + savedEntity = schClassTeachRepository.save(existing); + } + + // 3. 清除缓存(精确清除该班级的任教缓存) + cacheService.clearTeachCache(schId, entity.getClassId()); + + // 4. 构建日志描述(委托给 LogService) + String description = logService.buildTeachLogDescription(schId, savedEntity, isNew, oldTeaId); + LogContextHolder.setDescription(description); + } + + // ==================== 删除单个 ==================== + + /** + * 根据ID删除任教记录 + * + * @param user 当前操作用户 + * @param id 任教记录ID + */ + public void delTeachById(UserContext.UserInfo user, Integer id) { + Integer schId = user.getSchId(); + + // 1. 查询待删除记录 + SchClassTeach teach = schClassTeachRepository.findBySchIdAndId(schId, id) + .orElseThrow(() -> new DException("任教记录不存在,ID=" + id)); + + // 2. 删除 + schClassTeachRepository.deleteById(id); + + // 3. 清除缓存 + cacheService.clearTeachCache(teach.getSchId(), teach.getClassId()); + + // 4. 构建日志描述 + String description = logService.delTeachLog(schId, teach); + LogContextHolder.setDescription(description); + } + + // ==================== 删除班级的所有任教 ==================== + + /** + * 删除指定班级的所有任教记录 + * + * @param user 当前操作用户 + * @param classId 班级ID + */ + public void delClassTeach(UserContext.UserInfo user, Integer classId) { + Integer schId = user.getSchId(); + + // 1. 参数校验 + if (schId == null) { + throw new IllegalArgumentException("学校ID不能为空"); + } + if (classId == null) { + throw new IllegalArgumentException("班级ID不能为空"); + } + + // 2. 获取待删除记录 + List teachList = cacheService.getSchClassTeachList(schId, null, classId); + + // 3. 如果有记录,执行删除和日志 + if (teachList != null && !teachList.isEmpty()) { + // 3.1 批量删除 + schClassTeachRepository.deleteAll(teachList); + + // 3.2 清除缓存 + cacheService.clearTeachCache(schId, classId); + + // 3.3 构建日志描述 + String description = logService.delClassTeachLog(schId, teachList); + LogContextHolder.setDescription(description); + } + // 如果没有记录,无需操作 + } + + // ==================== 批量删除 ==================== + + /** + * 批量删除学制/年级下的任教记录 + * + * @param user 当前操作用户 + * @param schsystemId 学制ID(必填) + * @param gradeId 年级ID(可选,不传则删除该学制下所有年级) + */ + public void delBatch(UserContext.UserInfo user, Integer schsystemId, Integer gradeId) { + Integer schId = user.getSchId(); + + // 1. 参数校验 + if (schsystemId == null) { + throw new IllegalArgumentException("学制ID不能为空"); + } + + // 2. 获取年级列表 + List gradeSelectList = baseSchsystemGradeService.getGradeSelect(schId, schsystemId, gradeId); + if (gradeSelectList.isEmpty()) { + throw new IllegalArgumentException("未找到相关学制年级"); + } + List gradeIds = gradeSelectList.stream() + .map(SelectIntVO::getId) + .collect(Collectors.toList()); + + // 3. 获取待删除记录 + List teachList = queryService.getSchGradeTeachList(schId, gradeIds); + + // 4. 如果有记录,执行删除 + if (teachList != null && !teachList.isEmpty()) { + // 4.1 批量删除 + schClassTeachRepository.deleteAll(teachList); + + // 4.2 收集受影响的班级ID + Set affectedClassIds = teachList.stream() + .map(SchClassTeach::getClassId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 4.3 清除缓存 + for (Integer cid : affectedClassIds) { + cacheService.clearTeachCache(schId, cid); + } + + // 4.4 构建日志描述 + String description = logService.delBatchLog(schId, teachList, schsystemId, gradeSelectList, affectedClassIds); + LogContextHolder.setDescription(description); + } + // 如果无记录,无需操作 + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachLogService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachLogService.java new file mode 100644 index 0000000..263a333 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachLogService.java @@ -0,0 +1,303 @@ +package com.bestsch.bschclassmanage.service.impl.teachs; + +import com.alibaba.fastjson.JSON; +import com.bestsch.bschclassmanage.entity.OperationLogRecord; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.entity.SchTeacher; +import com.bestsch.bschclassmanage.model.constant.LogModule; +import com.bestsch.bschclassmanage.model.vo.BaseSchClassVO; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; +import com.bestsch.bschclassmanage.service.IComSchTreeService; +import com.bestsch.bschclassmanage.service.ILogService; +import com.bestsch.bschclassmanage.service.ISchClassService; +import com.bestsch.bschclassmanage.service.ISchDicSubjectService; +import com.bestsch.bschclassmanage.service.ISchTeacherService; +import com.bestsch.bschclassmanage.utils.UserContext; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 任教日志服务(内部实现,无接口) + * 职责:同步构建日志描述 + 异步保存日志 + */ +@Slf4j +@Service +public class SchClassTeachLogService { + + @Autowired + private ILogService logService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private ISchDicSubjectService schDicSubjectService; + + @Autowired + private ISchTeacherService schTeacherService; + + private static final String MODULE_TEACH = LogModule.TEACH; + + // ==================== 同步构建日志描述 ==================== + + /** + * 构建保存任教记录的日志描述(供 saveTeach 调用) + */ + public String buildTeachLogDescription(Integer schId, SchClassTeach savedEntity, + boolean isNew, Integer oldTeaId) { + try { + // 1. 查询班级名称 + String className = "未知班级"; + if (savedEntity.getGradeId() != null && savedEntity.getClassId() != null) { + List classList = schClassService.searcBaseSchClass( + schId, null, savedEntity.getGradeId(), savedEntity.getClassId()); + Optional classOpt = classList.stream().findFirst(); + if (classOpt.isPresent()) { + BaseSchClassVO classVO = classOpt.get(); + className = classVO.getGradeName() + classVO.getName(); + } + } + + // 2. 查询学科名称 + String subjectName = "未知学科"; + if (savedEntity.getSubId() != null) { + Map subjectMap = schDicSubjectService.toIdAndNameMap(schId, null); + subjectName = subjectMap.getOrDefault(savedEntity.getSubId(), "未知学科"); + } + + // 3. 查询教师名称 + Map teacherMap = schTeacherService.toIdAndNameMap(schId); + String oldTeacherName = "无"; + if (!isNew && oldTeaId != null) { + oldTeacherName = teacherMap.getOrDefault(oldTeaId, "未知教师"); + } + String newTeacherName = "无"; + if (savedEntity.getTeaId() != null) { + newTeacherName = teacherMap.getOrDefault(savedEntity.getTeaId(), "未知教师"); + } + + // 4. 构建内容 + if (isNew) { + return String.format("添加任教记录[班级:%s, 学科:%s, 教师:%s]成功,详情%s", + className, subjectName, newTeacherName, JSON.toJSONString(savedEntity)); + } else { + return String.format("修改任教记录[班级:%s, 学科:%s, 教师:%s修改教师:%s] ,详情%s", + className, subjectName, oldTeacherName, newTeacherName, JSON.toJSONString(savedEntity)); + } + } catch (Exception e) { + log.error("保存任教操作日志失败:" + JSON.toJSONString(savedEntity), e); + return isNew ? "添加任教日志失败" : "修改任教日志失败"; + } + } + + /** + * 构建删除单条任教记录的日志描述(供 delTeachById 调用) + */ + public String delTeachLog(Integer schId, SchClassTeach deletedTeach) { + try { + // 1. 班级名称 + String className = "未知班级"; + if (deletedTeach.getGradeId() != null && deletedTeach.getClassId() != null) { + List classList = schClassService.searcBaseSchClass( + schId, null, deletedTeach.getGradeId(), deletedTeach.getClassId()); + Optional classOpt = classList.stream().findFirst(); + if (classOpt.isPresent()) { + BaseSchClassVO classVO = classOpt.get(); + className = classVO.getGradeName() + classVO.getName(); + } + } + + // 2. 学科名称 + String subjectName = "未知学科"; + if (deletedTeach.getSubId() != null) { + Map subjectMap = schDicSubjectService.toIdAndNameMap(schId, null); + subjectName = subjectMap.getOrDefault(deletedTeach.getSubId(), "未知学科"); + } + + // 3. 教师名称 + Map teacherMap = schTeacherService.toIdAndNameMap(schId); + String teacherName = "无"; + if (deletedTeach.getTeaId() != null) { + teacherName = teacherMap.getOrDefault(deletedTeach.getTeaId(), "未知教师"); + } + + return String.format("删除任教记录[班级:%s, 学科:%s, 教师:%s]成功,详情%s", + className, subjectName, teacherName, JSON.toJSONString(deletedTeach)); + } catch (Exception e) { + log.error("记录删除任教日志失败", e); + return "删除任教日志失败"; + } + } + + /** + * 构建删除整个班级任教记录的日志描述(供 delClassTeach 调用) + */ + public String delClassTeachLog(Integer schId, List teachList) { + try { + if (teachList == null || teachList.isEmpty()) { + return "无删除记录"; + } + + // 获取班级名称(取第一条记录获取年级和班级ID) + String className = "未知班级"; + SchClassTeach first = teachList.get(0); + if (first.getGradeId() != null && first.getClassId() != null) { + List classList = schClassService.searcBaseSchClass( + schId, null, first.getGradeId(), first.getClassId()); + Optional classOpt = classList.stream().findFirst(); + if (classOpt.isPresent()) { + BaseSchClassVO classVO = classOpt.get(); + className = classVO.getGradeName() + classVO.getName(); + } + } + + // 批量获取名称 Map + Map subjectMap = schDicSubjectService.toIdAndNameMap(schId, null); + Map teacherMap = schTeacherService.toIdAndNameMap(schId); + + // 构建每个任教的描述 + List details = teachList.stream() + .map(teach -> { + String subName = subjectMap.getOrDefault(teach.getSubId(), "未知学科"); + String teaName = teacherMap.getOrDefault(teach.getTeaId(), "无"); + return subName + ":" + teaName; + }) + .collect(Collectors.toList()); + + String detailStr = String.join("; ", details); + return String.format("删除班级[%s]的任教记录,共%d条,详情:[%s]", + className, teachList.size(), detailStr); + } catch (Exception e) { + log.error("删除班级任教日志失败", e); + return "删除班级任教日志失败"; + } + } + + /** + * 构建批量删除任教记录的日志描述(供 delBatch 调用) + */ + public String delBatchLog(Integer schId, List teachList, + Integer schsystemId, List gradeSelectList, + Set affectedClassIds) { + try { + // 学制名称(简化为ID) + String schsystemName = "学制" + schsystemId; + + // 年级名称 + String gradeNames = gradeSelectList.stream() + .map(SelectIntVO::getName) + .collect(Collectors.joining("、")); + + // 班级名称(截断) + List classNameList = new ArrayList<>(); + for (Integer classId : affectedClassIds) { + List classList = schClassService.searcBaseSchClass( + schId, null, null, classId); + if (!classList.isEmpty()) { + BaseSchClassVO vo = classList.get(0); + classNameList.add(vo.getGradeName() + vo.getName()); + } else { + classNameList.add("未知班级(ID:" + classId + ")"); + } + } + String classNames; + if (classNameList.size() <= 10) { + classNames = String.join("、", classNameList); + } else { + classNames = String.join("、", classNameList.subList(0, 10)) + + "等" + classNameList.size() + "个班级"; + } + + return String.format( + "批量删除学制[%s]年级[%s]下的任教记录,共涉及%d个班级,删除%d条任教记录。班级列表:[%s]", + schsystemName, gradeNames, affectedClassIds.size(), teachList.size(), classNames + ); + } catch (Exception e) { + log.error("批量删除任教日志失败", e); + return "批量删除任教日志失败"; + } + } + + // ==================== 异步日志 ==================== + + /** + * 导入日志(异步) + */ + @Async("logExecutor") + public void importLogs(UserContext.UserInfo user, + List addTeachList, + List delTeachList, + List schClassList, + List schSubList, + List schTeacherList) { + try { + LocalDateTime now = LocalDateTime.now(); + + // 构建快速查找 Map + Map classDisplayMap = schClassList.stream() + .collect(Collectors.toMap( + BaseSchClassVO::getClassId, + vo -> vo.getGradeName() + vo.getName(), + (a, b) -> a + )); + + Map subjectNameMap = schSubList.stream() + .collect(Collectors.toMap( + SelectStrVO::getId, + SelectStrVO::getName, + (a, b) -> a + )); + + Map teacherNameMap = schTeacherList.stream() + .collect(Collectors.toMap( + SchTeacher::getTeaId, + SchTeacher::getName, + (a, b) -> a + )); + + List logs = new ArrayList<>(); + + // 新增任教日志 + if (addTeachList != null && !addTeachList.isEmpty()) { + for (SchClassTeach teach : addTeachList) { + String className = classDisplayMap.get(teach.getClassId()); + String subName = subjectNameMap.get(teach.getSubId()); + String teaName = teacherNameMap.get(teach.getTeaId()); + String content = String.format("导入班级任教[班级:%s,学科:%s,教师:%s]成功,任教信息:%s", + className, subName, teaName, JSON.toJSONString(teach)); + OperationLogRecord log = logService.buildLogRecord(user, MODULE_TEACH, content, now); + logs.add(log); + } + log.debug("操作人:{},班级任教导入日志成功:{}", user.getUserName(), JSON.toJSONString(addTeachList)); + } + + // 删除任教日志 + if (delTeachList != null && !delTeachList.isEmpty()) { + for (SchClassTeach teach : delTeachList) { + String className = classDisplayMap.get(teach.getClassId()); + String subName = subjectNameMap.get(teach.getSubId()); + String teaName = teacherNameMap.get(teach.getTeaId()); + String content = String.format("导入时删除班级任教[班级:%s,学科:%s,教师:%s]成功,任教信息:%s", + className, subName, teaName, JSON.toJSONString(teach)); + OperationLogRecord log = logService.buildLogRecord(user, MODULE_TEACH, content, now); + logs.add(log); + } + log.debug("操作人:{},导入删除班级任教日志成功:{}", user.getUserName(), JSON.toJSONString(delTeachList)); + } + + if (!logs.isEmpty()) { + logService.saveAllLogAsync(logs); + } + + } catch (Exception e) { + log.error("操作人:{},班级导入日志记录失败:{}", user.getUserName(), e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachQueryService.java b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachQueryService.java new file mode 100644 index 0000000..2c5be72 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/service/impl/teachs/SchClassTeachQueryService.java @@ -0,0 +1,311 @@ +package com.bestsch.bschclassmanage.service.impl.teachs; + +import com.bestsch.bschclassmanage.Repository.SchClassTeachRepository; +import com.bestsch.bschclassmanage.entity.SchClass; +import com.bestsch.bschclassmanage.entity.SchClassTeach; +import com.bestsch.bschclassmanage.model.entityField.EntityFieldNames; +import com.bestsch.bschclassmanage.model.vo.*; +import com.bestsch.bschclassmanage.service.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; + +import javax.persistence.criteria.Predicate; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 任教查询服务(内部实现,无接口) + * 职责:所有任教记录的查询逻辑 + */ +@Slf4j +@Service +public class SchClassTeachQueryService { + + @Autowired + private SchClassTeachRepository schClassTeachRepository; + + @Autowired + private IBaseSchsystemGradeService baseSchsystemGradeService; + + @Autowired + private ISchDicSubjectService schDicSubjectService; + + @Autowired + private ISchTeacherService schTeacherService; + + @Autowired + private ISchClassService schClassService; + + @Autowired + private SchClassTeachCacheService cacheService; + + + // ==================== 基础查询 ==================== + + + /** + * 根据学校、年级列表查询任教记录 + * + * @param schId 学校ID(必填) + * @param gradeIds 年级ID列表(可选) + * @return 任教记录列表 + */ + public List getSchGradeTeachList(Integer schId, List gradeIds) { + Specification spec = (root, query, cb) -> { + List predicates = new ArrayList<>(); + predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId)); + + if (gradeIds != null && !gradeIds.isEmpty()) { + predicates.add(root.get(EntityFieldNames.gradeId).in(gradeIds)); + } + + return cb.and(predicates.toArray(new Predicate[0])); + }; + return schClassTeachRepository.findAll(spec); + } + + // ==================== 缓存版查询 ==================== + + /** + * 获取任教记录(带缓存) + * 如果指定了班级,直接查该班级;否则查全校/全年级并合并 + * + * @param schId 学校ID(必填) + * @param gradeId 年级ID(可选) + * @param classId 班级ID(可选) + * @return 任教记录列表 + */ + public List getSchClassTeachCacheList(Integer schId, Integer gradeId, Integer classId) { + // 情况1:指定了班级,直接获取单个班级的缓存 + if (classId != null && classId > 0) { + return cacheService.getClassTeachList(schId, classId); + } + + // 情况2:未指定班级,获取该校所有班级的任教记录(按需过滤年级) + List allClasses = schClassService.getSchClassCacheList(schId); + + if (gradeId != null && gradeId > 0) { + allClasses = allClasses.stream() + .filter(s -> s.getGradeId().equals(gradeId)) + .collect(Collectors.toList()); + } + + if (allClasses == null || allClasses.isEmpty()) { + return Collections.emptyList(); + } + + // 提取班级ID列表 + List classIds = allClasses.stream() + .map(SchClass::getClassId) + .collect(Collectors.toList()); + + // 批量获取缓存(一次 Redis mget + 一次 DB 批量查询) + Map> batchMap = cacheService.getClassTeachBatchMap(schId, classIds); + + // 合并结果 + List result = new ArrayList<>(); + for (List list : batchMap.values()) { + if (list != null && !list.isEmpty()) { + result.addAll(list); + } + } + return result; + } + + // ==================== 复杂查询:任教地图 ==================== + + /** + * 获取任教地图数据(班级 × 学科 → 教师映射) + * 用于前端展示班级-学科-教师的矩阵关系 + * + * @param schId 学校ID(必填) + * @param schsystemId 学制ID(可选,用于过滤年级) + * @param gradeId 年级ID(可选,不传则获取所有年级) + * @return 任教地图VO + */ + public SchTeachMapVO getSchTeachMapVO(Integer schId, Integer schsystemId, Integer gradeId) { + // 1. 获取年级数据 + Map gradeNameMap = baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, gradeId); + if (gradeNameMap == null || gradeNameMap.isEmpty()) { + return buildEmptyResult(); + } + + // 2. 获取学科数据 + Map subjectNameMap = schDicSubjectService.toIdAndNameMap(schId, schsystemId); + if (subjectNameMap == null || subjectNameMap.isEmpty()) { + return buildEmptyResult(); + } + + // 3. 获取教师数据(允许为空) + Map teacherNameMap = schTeacherService.toIdAndNameMap(schId); + if (teacherNameMap == null) { + teacherNameMap = Collections.emptyMap(); + } + + // 4. 构建学科VO列表 + List subjectVOList = subjectNameMap.entrySet().stream() + .map(entry -> new SelectStrVO(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); + + // 5. 获取班级列表 + List gradeIds = new ArrayList<>(gradeNameMap.keySet()); + List schClassList = schClassService.getSchClassCacheFilter(schId, gradeIds, null); + if (schClassList == null || schClassList.isEmpty()) { + return buildEmptyResult(); + } + + // 6. 构建班级VO列表 + List classVOList = schClassList.stream() + .map(clazz -> convertToGradeClassVO(clazz, gradeNameMap)) + .collect(Collectors.toList()); + + // 7. 获取任教记录并构建映射 + List teachList = getSchClassTeachCacheList(schId, null, null); + Map teachMap = teachList.stream() + .filter(t -> t.getClassId() != null && t.getSubId() != null) + .collect(Collectors.toMap( + t -> t.getClassId() + "_" + t.getSubId(), + t -> t, + (a, b) -> a // 若有重复,保留第一个 + )); + + // 8. 构建班级-学科-教师的矩阵数据 + List teachClassMapVOList = new ArrayList<>(classVOList.size()); + for (SelectGradeClassVO classVO : classVOList) { + SchTeachClassMapVO mapVO = new SchTeachClassMapVO(); + mapVO.setClassId(classVO.getClassId()); + mapVO.setGradeId(classVO.getGradeId()); + + List teachIdVOList = new ArrayList<>(subjectVOList.size()); + for (SelectStrVO subjectVO : subjectVOList) { + SchTeachMapIdVO idVO = new SchTeachMapIdVO(); + idVO.setSubId(subjectVO.getId()); + + String key = classVO.getClassId() + "_" + subjectVO.getId(); + SchClassTeach teach = teachMap.get(key); + if (teach != null) { + Integer teaId = teach.getTeaId(); + idVO.setId(teach.getId()); + idVO.setTeacherId(teaId); + idVO.setTeacherName(teacherNameMap.get(teaId)); + } + // 若没有任教记录,teacherId/Name 保持 null,前端自行处理 + + teachIdVOList.add(idVO); + } + mapVO.setTeachSubjectList(teachIdVOList); + teachClassMapVOList.add(mapVO); + } + + // 9. 封装返回结果 + SchTeachMapVO result = new SchTeachMapVO(); + result.setClassList(classVOList); + result.setSubjectList(subjectVOList); + result.setTeachList(teachClassMapVOList); + return result; + } + + + + public List getSchClassTeachMapVO(Integer schId, Integer gradeId, Integer classId) { + // 1. 参数校验 + if (schId == null || classId == null) { + return Collections.emptyList(); + } + Integer schsystemId = baseSchsystemGradeService.getSchGradeIdBySchsystemId(schId, gradeId); + + // 2. 获取学科数据 + Map subjectNameMap = schDicSubjectService.toIdAndNameMap(schId, schsystemId); + if (subjectNameMap == null || subjectNameMap.isEmpty()) { + return Collections.emptyList(); + } + + // 3. 获取教师数据(允许为空) + Map teacherNameMap = schTeacherService.toIdAndNameMap(schId); + if (teacherNameMap == null) { + teacherNameMap = Collections.emptyMap(); + } + + // 4. 构建学科 VO 列表(可直接使用,无需中间 SelectStrVO) + List result = new ArrayList<>(subjectNameMap.size()); + + // 5. 获取任教记录并构建映射(仅当前班级) + List teachList = getSchClassTeachCacheList(schId, gradeId, classId); + Map teachMap = teachList.stream() + .filter(t -> t.getClassId() != null && t.getSubId() != null) + .collect(Collectors.toMap( + t -> t.getClassId() + "_" + t.getSubId(), + t -> t, + (a, b) -> a // 保留第一个,若业务允许多教师可调整 + )); + + // 6. 遍历学科,组装 VO + for (Map.Entry entry : subjectNameMap.entrySet()) { + String subId = entry.getKey(); + String subName = entry.getValue(); + + SchTeachMapIdVO idVO = new SchTeachMapIdVO(); + idVO.setSubId(subId); + idVO.setSubName(subName); // 若需要学科名称,确保 VO 有该字段 + + String key = classId + "_" + subId; + SchClassTeach teach = teachMap.get(key); + if (teach != null) { + Integer teaId = teach.getTeaId(); + idVO.setId(teach.getId()); + idVO.setTeacherId(teaId); + idVO.setTeacherName(teaId != null ? teacherNameMap.get(teaId) : null); + } + // 若未找到任教记录,teacherId/Name 保持 null + + result.add(idVO); + } + + return result; + } + + + + + + // ==================== 私有辅助方法 ==================== + + /** + * 转换班级实体为 SelectGradeClassVO + * + * @param clazz 班级实体 + * @param gradeNameMap 年级ID -> 名称映射 + * @return SelectGradeClassVO + */ + private SelectGradeClassVO convertToGradeClassVO(SchClass clazz, Map gradeNameMap) { + SelectGradeClassVO vo = new SelectGradeClassVO(); + vo.setClassId(clazz.getClassId()); + vo.setGradeId(clazz.getGradeId()); + + // 获取年级名称,若不存在则设为"未知年级" + String gradeName = gradeNameMap.get(clazz.getGradeId()); + vo.setGradeName(gradeName != null ? gradeName : "未知年级"); + + // 显示名:别称(cname)优先,无别称则用正式名称(name) + String displayName = StringUtils.isNotBlank(clazz.getCname()) ? clazz.getCname() : clazz.getName(); + vo.setName(displayName); + + return vo; + } + + /** + * 构造空结果(避免上层处理 null) + * + * @return 空的 SchTeachMapVO + */ + private SchTeachMapVO buildEmptyResult() { + SchTeachMapVO empty = new SchTeachMapVO(); + empty.setClassList(Collections.emptyList()); + empty.setSubjectList(Collections.emptyList()); + empty.setTeachList(Collections.emptyList()); + return empty; + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/utils/CalendarUtils.java b/src/main/java/com/bestsch/bschclassmanage/utils/CalendarUtils.java similarity index 94% rename from src/main/java/com/bestsch/classicalchinese/utils/CalendarUtils.java rename to src/main/java/com/bestsch/bschclassmanage/utils/CalendarUtils.java index 9e5eef5..4fd289a 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/CalendarUtils.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/CalendarUtils.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import java.util.Calendar; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java b/src/main/java/com/bestsch/bschclassmanage/utils/ChinaDate.java similarity index 99% rename from src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java rename to src/main/java/com/bestsch/bschclassmanage/utils/ChinaDate.java index 05531ef..17c03b5 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/ChinaDate.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import java.text.ParseException; import java.text.SimpleDateFormat; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/ConstantUtil.java similarity index 88% rename from src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/ConstantUtil.java index 339bdc8..2337b28 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/ConstantUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; public class ConstantUtil { diff --git a/src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/DateRangeUtil.java similarity index 97% rename from src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/DateRangeUtil.java index b674d5a..7e0a312 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/DateRangeUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import org.apache.http.client.utils.DateUtils; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/DicUtil.java similarity index 99% rename from src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/DicUtil.java index 2765022..b186bc7 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/DicUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; /** diff --git a/src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/DownloadFileUtil.java similarity index 97% rename from src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/DownloadFileUtil.java index 2233129..1a22492 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/DownloadFileUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.InputStreamResource; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java b/src/main/java/com/bestsch/bschclassmanage/utils/EasyPoiUtils.java similarity index 96% rename from src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java rename to src/main/java/com/bestsch/bschclassmanage/utils/EasyPoiUtils.java index b4f56f0..1ae0dac 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/EasyPoiUtils.java @@ -1,6 +1,7 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.word.WordExportUtil; import org.apache.poi.ss.usermodel.Workbook; @@ -10,6 +11,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Field; import java.net.URLEncoder; import java.util.List; import java.util.Map; @@ -76,7 +78,5 @@ public final class EasyPoiUtils { e.printStackTrace(); } - } - } diff --git a/src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/EnumUtil.java similarity index 98% rename from src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/EnumUtil.java index bc21311..d6c466b 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/EnumUtil.java @@ -1,7 +1,6 @@ -package com.bestsch.classicalchinese.utils; - -import org.apache.commons.lang.StringUtils; +package com.bestsch.bschclassmanage.utils; +import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/HttpUtils.java b/src/main/java/com/bestsch/bschclassmanage/utils/HttpUtils.java similarity index 97% rename from src/main/java/com/bestsch/classicalchinese/utils/HttpUtils.java rename to src/main/java/com/bestsch/bschclassmanage/utils/HttpUtils.java index 412192d..f658109 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/HttpUtils.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/HttpUtils.java @@ -1,6 +1,6 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; -import com.bestsch.utils.DException; +import com.yunhai.platform.utils.exception.DException; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/JavaBeanUtil.java similarity index 98% rename from src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/JavaBeanUtil.java index cb52fe0..2dcafb9 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/JavaBeanUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/ListMapSortUtil.java similarity index 97% rename from src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/ListMapSortUtil.java index cd63a6a..280a73b 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/ListMapSortUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import java.util.List; diff --git a/src/main/java/com/bestsch/bschclassmanage/utils/LogContextHolder.java b/src/main/java/com/bestsch/bschclassmanage/utils/LogContextHolder.java new file mode 100644 index 0000000..6987908 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/utils/LogContextHolder.java @@ -0,0 +1,17 @@ +package com.bestsch.bschclassmanage.utils; + +public class LogContextHolder { + private static final ThreadLocal LOG_DESCRIPTION = new ThreadLocal<>(); + + public static void setDescription(String desc) { + LOG_DESCRIPTION.set(desc); + } + + public static String getDescription() { + return LOG_DESCRIPTION.get(); + } + + public static void clear() { + LOG_DESCRIPTION.remove(); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/ModelMapperUtil.java similarity index 74% rename from src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/ModelMapperUtil.java index ea03e8d..11e934c 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/ModelMapperUtil.java @@ -1,5 +1,7 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; +import com.bestsch.bschclassmanage.model.vo.SelectIntVO; +import com.bestsch.bschclassmanage.model.vo.SelectStrVO; import org.modelmapper.ModelMapper; import org.modelmapper.convention.MatchingStrategies; @@ -7,11 +9,11 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; /** * 对象映射转换工具类,转换逻辑属性名完全匹配进行转换 @@ -196,6 +198,58 @@ public final class ModelMapperUtil { } } + + /** + * 将实体列表转换为 Map<键, 名称>,自动过滤键为 null 的记录 + * @param list 实体列表 + * @param keyMapper 提取键的函数(可为 Integer / String / 其他) + * @param valueMapper 提取值的函数(返回 String) + * @param 实体类型 + * @param 键类型 + * @return Map + */ + public static Map toMap(List list, + Function keyMapper, + Function valueMapper) { + if (list == null || list.isEmpty()) { + return Collections.emptyMap(); + } + return list.stream() + .filter(item -> keyMapper.apply(item) != null) + .collect(Collectors.toMap(keyMapper, valueMapper, (a, b) -> a)); + } + + /** + * 将列表转换为 SelectIntVO 列表 + */ + public static List toSelectIntVOList( + List sourceList, + Function idMapper, + Function nameMapper) { + + if (sourceList == null || sourceList.isEmpty()) { + return Collections.emptyList(); + } + + return sourceList.stream() + .map(item -> new SelectIntVO(idMapper.apply(item), nameMapper.apply(item))) + .collect(Collectors.toList()); + } + + public static List toSelectStrVOList( + List sourceList, + Function idMapper, + Function nameMapper) { + + if (sourceList == null || sourceList.isEmpty()) { + return Collections.emptyList(); + } + + return sourceList.stream() + .map(item -> new SelectStrVO(idMapper.apply(item), nameMapper.apply(item))) + .collect(Collectors.toList()); + } + } diff --git a/src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/OkHttpUtil.java similarity index 99% rename from src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/OkHttpUtil.java index 74d9999..788f6ca 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/OkHttpUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import okhttp3.*; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/OrgJsonUtil.java similarity index 93% rename from src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/OrgJsonUtil.java index 829a67d..3040b11 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/OrgJsonUtil.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import org.json.JSONArray; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/OtherUtil.java similarity index 51% rename from src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/OtherUtil.java index d2a7abb..abd2e6d 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/OtherUtil.java @@ -1,16 +1,16 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; -import com.bestsch.classicalchinese.enums.AppType; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.entity.BaseEntity; -import com.bestsch.utils.DException; +import com.bestsch.bschclassmanage.entity.BaseEntity; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.yunhai.platform.utils.exception.DException; +import io.netty.util.internal.StringUtil; import org.commonmark.node.Node; import org.commonmark.parser.Parser; import org.commonmark.renderer.html.HtmlRenderer; @@ -19,18 +19,21 @@ import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; -import javax.websocket.DecodeException; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; - /* * 杂项公用方法集合 * */ public class OtherUtil { - + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + private OtherUtil() {} /** * @Description: 判断字符串能否序列化 * @Author: chenx @@ -60,17 +63,28 @@ public class OtherUtil { } } + /** - * @Description: 数组深拷贝 - * @Author: chenx - * @Date: 2023/4/20 + * JSON序列化方式实现集合跨类型拷贝 + * @param src 源集合 + * @param targetClazz 目标类 + * @return 新集合 */ - public final static List deepCopy(List src, Class clazz) { - String jsonStr=JSON.toJSONString(src); - if (!isJsonArray(jsonStr)) return src; - return JSONArray.parseArray(jsonStr,clazz); + public final static List deepCopy(List src, Class targetClazz) { + if (src == null) { + return new ArrayList<>(); + } + String jsonStr = JSON.toJSONString(src); + return JSONArray.parseArray(jsonStr, targetClazz); } + public final static T deepCopy(T source, Class clazz) { + try { + return objectMapper.readValue(objectMapper.writeValueAsString(source), clazz); + } catch (Exception e) { + throw new RuntimeException("深拷贝失败", e); + } + } /** @@ -128,19 +142,25 @@ public class OtherUtil { } } - public static void setBaseEntityValue(UserSysRole curRole, T entity, Integer id) - { - if(id==null||id==0) - entity.setCDate(new Date()); - else - entity.setId(id); + public static void setBaseEntityValue(UserContext.UserInfo user, T entity) { + if (user == null || entity == null) { + throw new IllegalArgumentException("参数不能为null"); + } + Date now = new Date(); + Integer userId = user.getUserId(); + entity.setUpdateDate(now); + entity.setUpdateUserId(userId); - entity.setSchId(curRole.getSchId()); - entity.setCUserId(curRole.getUserId()); + // 判断是否为新增:id为null或0视为新增 + Integer id = entity.getId(); + if (id == null || id == 0) { + entity.setCreateDate(now); + entity.setCreateUserId(userId); + entity.setSchId(user.getSchId()); + } } public static Map convertJsonToMap(String json) { - ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.readValue(json, Map.class); } catch (Exception e) { @@ -151,9 +171,7 @@ public class OtherUtil { } public static List> convertJsonToMapList(String json) { - ObjectMapper objectMapper = new ObjectMapper(); List> list=new ArrayList<>(); - try { list = objectMapper.readValue(json, new TypeReference>>() {}); } catch (Exception e) { @@ -164,15 +182,13 @@ public class OtherUtil { System.out.println("convertJsonToMapList json to MapList 失败!json="+json); e.printStackTrace(); } - return list; } public static List> jsonToMapTree(String json) { - ObjectMapper mapper = new ObjectMapper(); List> result = new ArrayList<>(); try { - JsonNode rootNode = mapper.readTree(json); + JsonNode rootNode = objectMapper.readTree(json); for (JsonNode node : rootNode) { result.add(jsonNodeToMap(node)); @@ -209,8 +225,7 @@ public class OtherUtil { } public static Target mapToClass(Map map, Class targetClass) { - ObjectMapper mapper = new ObjectMapper(); - return mapper.convertValue(map,targetClass); + return objectMapper.convertValue(map,targetClass); } public static List mapToList(List> sourceList, Class targetClass) { @@ -229,13 +244,86 @@ public class OtherUtil { } public static List mapList(List> sourceList, Class targetClass) { - ObjectMapper objectMapper = new ObjectMapper(); List sList=mapToList(sourceList,targetClass); return sList.stream() .map(student -> objectMapper.convertValue(student, new TypeReference() {})) .collect(Collectors.toList()); } + + /** + * 将 JSON 数组字符串解析为指定类型的 List + * @param json JSON 数组字符串(如 "[{...},{...}]") + * @param targetClass 目标元素类型(如 BaseTree.class) + * @param 目标类型 + * @return 解析后的 List,若失败或为空则返回 null + */ + public static List jsonParseList(String json, Class targetClass) { + if (json == null || json.trim().isEmpty()) { + return null; + } + try { + // 使用 TypeReference 保留泛型信息,避免类型擦除 + return objectMapper.readValue(json, new TypeReference>() {}); + } catch (Exception e) { + System.err.println("解析 JSON 数组失败,json 前缀: " + json); + e.printStackTrace(); + return null; + } + } + + /** + * 将 JSON 字符串解析为单个对象(非数组) + * @param json JSON 对象字符串 + * @param targetClass 目标类型 + * @param 目标类型 + * @return 解析后的对象,失败返回 null + */ + public static T jsonParseObject(String json, Class targetClass) { + if (json == null || json.trim().isEmpty()) { + return null; + } + try { + return objectMapper.readValue(json, targetClass); + } catch (Exception e) { + System.err.println("解析 JSON 数组失败,json 前缀: " + json); + e.printStackTrace(); + return null; + } + } + + + public static List jsonParseArrayTree(String json, Class elementClass) { + if (json == null || json.trim().isEmpty()) { + return null; + } + try { + // 使用 TypeFactory 动态构建 List 的 JavaType + JavaType listType = objectMapper.getTypeFactory() + .constructCollectionType(List.class, elementClass); + return objectMapper.readValue(json, listType); + } catch (Exception e) { + System.err.println("解析 JSON 数组失败: " + json); + e.printStackTrace(); + return null; + } + } + + + public static T jsonParseTree(String json, Class elementClass) { + if (json == null || json.trim().isEmpty()) { + return null; + } + try { + JavaType javaType = objectMapper.getTypeFactory().constructType(elementClass); + return objectMapper.readValue(json, javaType); + } catch (Exception e) { + System.err.println("解析 JSON 数组失败: " + json); + e.printStackTrace(); + return null; + } + } + public static HttpServletRequest getRequest() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); @@ -258,20 +346,70 @@ public class OtherUtil { throw new DException(headerName+" is null"); } - public static String getXdCode() { - String val=getHeader("xdCode"); - List ids=new ArrayList<>(Arrays.asList("2","3","4")); - if(ids.contains(val)) - return val; - else throw new DException(val+" Non compliant"); + public static Integer[] convertToArray(String idsStr) { + if (idsStr == null || idsStr.trim().isEmpty()) { + return new Integer[0]; + } + String[] parts = idsStr.split(","); + Integer[] result = new Integer[parts.length]; + for (int i = 0; i < parts.length; i++) { + result[i] = Integer.parseInt(parts[i].trim()); + } + return result; } - public static String getAppType() { - String val=getHeader("apptype"); - List> list= EnumUtil.toMapList(AppType.class); - List ids=list.stream().map(s->s.get("id").toString()).collect(Collectors.toList()); - if(ids.contains(val)) - return val; - else throw new DException(val+" Non compliant"); + /** + * 获取客户端真实 IP 地址(支持代理转发) + */ + public static String getClientIp() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + return "unknown"; + } + HttpServletRequest request = attributes.getRequest(); + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + // 多个代理的情况,取第一个 IP + if (ip != null && ip.contains(",")) { + ip = ip.split(",")[0].trim(); + } + return ip; + } + + public static String nullToStr(Object obj) { + return obj == null ? "null":(obj==""? "空字符串": obj.toString()); + } + + public static int extractClassNumber(String className) { + if (StringUtil.isNullOrEmpty(className)) return -1; + // 优先匹配 "数字+班" + Matcher matcher = Pattern.compile("(\\d+)\\s*班").matcher(className); + if (matcher.find()) { + return Integer.parseInt(matcher.group(1)); + } + // 若无“班”,尝试提取所有数字中的最后一个(且长度≤2,视为班级号) + Matcher fallback = Pattern.compile("\\d+").matcher(className); + int lastNum = -1; + while (fallback.find()) { + String numStr = fallback.group(); + if (numStr.length() <= 2) { // 只接受1~2位数字作为班级号 + lastNum = Integer.parseInt(numStr); + } + } + return lastNum; // 若没有符合的数字,返回 -1 } } diff --git a/src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/PageUtil.java similarity index 93% rename from src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/PageUtil.java index a2145dd..37d96df 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/PageUtil.java @@ -1,6 +1,6 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; -import com.bestsch.classicalchinese.model.PageInfo; +import com.bestsch.bschclassmanage.model.tool.PageInfo; import org.springframework.data.domain.Pageable; import java.util.ArrayList; diff --git a/src/main/java/com/bestsch/bschclassmanage/utils/RedisConstants.java b/src/main/java/com/bestsch/bschclassmanage/utils/RedisConstants.java new file mode 100644 index 0000000..13136be --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/utils/RedisConstants.java @@ -0,0 +1,84 @@ +package com.bestsch.bschclassmanage.utils; + +public class RedisConstants { + + public static final String CachePrefix = "bsch.classmanage"; + + //-----------------------------过期时间-------------------------- + + public static final long CACHE_EXPIRE_5M = 5 * 60 * 1000; + + public static final long CACHE_EXPIRE_10M = 10 * 60 * 1000; + + public static final long CACHE_EXPIRE_30M = 3 * CACHE_EXPIRE_10M; + + public static final long CACHE_EXPIRE_1H = 60 * 60 * 1000; + + public static final long CACHE_EXPIRE_1D= 24 * CACHE_EXPIRE_1H ; + + public static final long CACHE_EXPIRE_7D= 7 * CACHE_EXPIRE_1D ; + + public static final long CACHE_EXPIRE_30D=30 * CACHE_EXPIRE_1D; + + //-------------------------------系统--------------------------------------- + + //系统年级 + public static final String SYSTEM_GRAGE =CachePrefix+ ".system_grdae"; + + //系统年级 + public static final String SYSTEM_SUBJECT =CachePrefix+ ".system_subject"; + + //系统学制 + public static final String SYSTEM_SCHSYSTEM =CachePrefix+ ".system_schsystem"; + + //系统年级 + public static final String SYSTEM_YEARTERM =CachePrefix+ ".system_yearterm"; + + //执行进度Progress + public static final String EXTERNAL_PROGRESS = CachePrefix + "external_progress"; + + //执行任务数据缓存 + public static final String EXTERNAL_PLAN_DATA = CachePrefix + "external_plan_data"; + + + //---------------------------学校------------------------------------------------------- + + //学校树 + public static final String SCHOOL_TREE =CachePrefix+ ".sch_tree"; + + //学校列表 + public static final String SCHOOL_LIST =CachePrefix+ ".sch_list"; + + //学校年级 + public static final String SCHOOL_SUBJECT =CachePrefix+ ".sch_subject"; + + //学校院校 + public static final String SCHOOL_CAMPUS =CachePrefix+ ".sch_campus"; + + //学部 + public static final String SCHOOL_DICISION =CachePrefix+ ".sch_division"; + + //专业 + public static final String SCHOOL_MAJORS =CachePrefix+ ".sch_majors"; + + //课程 + public static final String SCHOOL_COURSE =CachePrefix+ ".sch_course"; + + //学校年级 + public static final String SCHOOL_GRAGE =CachePrefix+ ".sch_grdae"; + + //班级 + public static final String SCHOOL_CLASS =CachePrefix+ ".sch_class"; + + public static final String SCHOOL_TEACHER =CachePrefix+ ".sch_teacher"; + + public static final String SCHOOL_CLASS_TEACH =CachePrefix+ ".sch_class_teach"; + + + public static final String SCHOOL_CLASS_STUDENT=CachePrefix+ ".sch_class_student"; + + public static final String SCHOOL_CUSTOM_GROUP=CachePrefix+ ".sch_group_teacher"; + + + +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/RedisUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/RedisUtil.java similarity index 85% rename from src/main/java/com/bestsch/classicalchinese/utils/RedisUtil.java rename to src/main/java/com/bestsch/bschclassmanage/utils/RedisUtil.java index 7f3368b..59e8456 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/RedisUtil.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/RedisUtil.java @@ -1,14 +1,13 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; +import com.alibaba.fastjson.JSON; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; @@ -19,7 +18,6 @@ import java.util.concurrent.TimeUnit; @Component public final class RedisUtil { - @Autowired private RedisTemplate redisTemplate; @@ -122,18 +120,18 @@ public final class RedisUtil { // ============================String============================= - /** - * 普通缓存获取 - * - * @param key 键 - * @return 值 - */ - - public Object get(String key) { - - return key == null ? null : redisTemplate.opsForValue().get(key); - - } +// /** +// * 普通缓存获取 +// * +// * @param key 键 +// * @return 值 +// */ +// +// public Object get(String key) { +// +// return key == null ? null : redisTemplate.opsForValue().get(key); +// +// } /** @@ -865,4 +863,67 @@ public final class RedisUtil { } + /** + * 根据模式匹配获取所有 Key + * @param pattern 匹配模式,如 "school_class_teach_1_*" + * @return 匹配的 Key 集合 + */ + public Set keys(String pattern) { + try { + return redisTemplate.keys(pattern); + } catch (Exception e) { + return Collections.emptySet(); + } + } + + + + + public T get(String key, Class clazz) { + Object obj = redisTemplate.opsForValue().get(key); + if (obj == null) return null; + if (clazz.isInstance(obj)) { + return clazz.cast(obj); + } + // 如果类型不匹配,尝试用 FastJson 转换 + return JSON.parseObject(JSON.toJSONString(obj), clazz); + } + + /** + * 获取缓存并转换为目标 List 类型(专门解决 LinkedHashMap 问题) + */ + public List getList(String key, Class clazz) { + Object obj = redisTemplate.opsForValue().get(key); + if (obj instanceof List) { + return JSON.parseArray(JSON.toJSONString(obj), clazz); + } + return null; + } + + + /** + * 批量获取多个 Key 的 List 数据 + * @param keys 缓存 Key 列表 + * @param clazz 元素类型 + * @return Key -> List 映射 + */ + public Map> mgetList(List keys, Class clazz) { + if (keys == null || keys.isEmpty()) { + return Collections.emptyMap(); + } + try { + List results = redisTemplate.opsForValue().multiGet(keys); + Map> resultMap = new HashMap<>(); + for (int i = 0; i < keys.size(); i++) { + String key = keys.get(i); + Object value = results.get(i); + if (value != null) { + resultMap.put(key,JSON.parseArray(JSON.toJSONString(value), clazz)); + } + } + return resultMap; + } catch (Exception e) { + return Collections.emptyMap(); + } + } } diff --git a/src/main/java/com/bestsch/classicalchinese/utils/Signature.java b/src/main/java/com/bestsch/bschclassmanage/utils/Signature.java similarity index 96% rename from src/main/java/com/bestsch/classicalchinese/utils/Signature.java rename to src/main/java/com/bestsch/bschclassmanage/utils/Signature.java index c3a08fe..430e0ef 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/Signature.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/Signature.java @@ -1,7 +1,7 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; -import com.bestsch.utils.DException; -import org.apache.commons.lang.StringUtils; +import com.yunhai.platform.utils.exception.DException; +import org.apache.commons.lang3.StringUtils; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; diff --git a/src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java b/src/main/java/com/bestsch/bschclassmanage/utils/TimeUtils.java similarity index 54% rename from src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java rename to src/main/java/com/bestsch/bschclassmanage/utils/TimeUtils.java index 017de05..dc0445e 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/TimeUtils.java @@ -1,8 +1,5 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; -import com.bestsch.classicalchinese.enums.TimeTypeEnum; -import com.bestsch.classicalchinese.model.StartEndDate; -import org.apache.commons.lang.StringUtils; import java.text.SimpleDateFormat; import java.util.*; @@ -10,47 +7,6 @@ public class TimeUtils { private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - /** - * 根据俩日期,获取中间存在某周的周一、周日 - */ - public static List getMonAndSunWeek(Date startDate, Date endDate) { - List list = new ArrayList<>(); - Date tmp = startDate; - int ii = 0; - try { - while (tmp.before(endDate)) { - StartEndDate pram = new StartEndDate(); - - Calendar calendar = Calendar.getInstance(); - if (ii == 0) { - String dateStr = sdf.format(startDate); - Date date = sdf.parse(dateStr); - calendar.setTime(date); - - if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) - calendar.add(Calendar.DAY_OF_YEAR, -1); - } else { - calendar.setTime(tmp); - calendar.add(Calendar.DATE, 1); - } - int i = calendar.get(Calendar.DAY_OF_WEEK) - 1; - calendar.add(Calendar.DATE, -i + 1); - pram.setStartDate(calendar.getTime());//周一 - - calendar.add(Calendar.DATE, 6); - Date dd = calendar.getTime(); - pram.setEndDate(dd);//周日 - tmp = dd; - ii++; - list.add(pram); - } - } catch (Exception e) { - } - return list; - } - - - /** * 日期转星期 */ @@ -77,18 +33,7 @@ public class TimeUtils { - public static Map getTime(String timeIndex,String startDate,String endDate){ - Map selectTime = new HashMap<>(); - if (!StringUtils.isEmpty(timeIndex) && !timeIndex.equals("6")) { - selectTime = selectTime(Integer.parseInt(timeIndex)); - } else { - if (StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) { - selectTime.put("startTime", timstamp2DateTime(startDate)); - selectTime.put("endTime", timstamp2DateTime(endDate)); - } - } - return selectTime; - } + public static String timstamp2DateTime(String timestamp) { String[] split = timestamp.split("-"); @@ -99,50 +44,7 @@ public class TimeUtils { else return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Long.parseLong(timestamp)); } - public static Map selectTime(Integer index) { - try { - Map map = new HashMap<>(); - String startTime = ""; - String endTime = ""; - // indexStr 0代表什么,1代表什么... - int currentYear = CalendarUtils.getYear(); - int currentMonth = CalendarUtils.getMonth(); - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - String halfOfJan = ChinaDate.lunarToSolar(currentYear + "0115", false); - Date halfJan = sdf.parse(halfOfJan); - if (TimeTypeEnum.CURRENT_TERM.getId() == index) { - if (new Date().getTime() >= halfJan.getTime()) { - if (currentMonth < 9) { - startTime = halfOfJan + " 00:00:00"; - endTime = currentYear + "-08-31 23:59:59"; - } else { - startTime = currentYear + "-09-01 00:00:00"; - endTime = ChinaDate.lunarToSolar((currentYear + 1) + "0115", false) + " 23:59:59"; - } - } else { - startTime = (currentYear - 1) + "-09-01 00:00:00"; - endTime = halfOfJan + " 23:59:59"; - } - } else if (TimeTypeEnum.CURRENT_MONTH.getId() == index) { - startTime = getFirstDayOfCurrentMonth() + " 00:00:00"; - endTime = getLastDayOfCurrentMonth() + " 23:59:59"; - } else if (TimeTypeEnum.CURRENT_WEEK.getId() == index) { - startTime = getFirstOfWeek() + " 00:00:00"; - endTime = getLastOfWeek() + " 23:59:59"; - } else if (TimeTypeEnum.TODAY.getId() == index) { - startTime = sdf.format(new Date()) + " 00:00:00"; - endTime = sdf.format(new Date()) + " 23:59:59"; - } - - map.put("startTime", startTime); - map.put("endTime", endTime); - return map; - } catch (Exception e) { -// e.printStackTrace(); - } - return null; - } /** * 获取这个月的第一天 */ diff --git a/src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java b/src/main/java/com/bestsch/bschclassmanage/utils/UUIDUtils.java similarity index 87% rename from src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java rename to src/main/java/com/bestsch/bschclassmanage/utils/UUIDUtils.java index 3a8d1de..b325777 100644 --- a/src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java +++ b/src/main/java/com/bestsch/bschclassmanage/utils/UUIDUtils.java @@ -1,4 +1,4 @@ -package com.bestsch.classicalchinese.utils; +package com.bestsch.bschclassmanage.utils; import java.util.UUID; diff --git a/src/main/java/com/bestsch/bschclassmanage/utils/UserContext.java b/src/main/java/com/bestsch/bschclassmanage/utils/UserContext.java new file mode 100644 index 0000000..2041137 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/utils/UserContext.java @@ -0,0 +1,96 @@ +package com.bestsch.bschclassmanage.utils; + +import lombok.Value; + +public class UserContext { + private static final ThreadLocal USER_ID = new ThreadLocal<>(); + private static final ThreadLocal USER_NAME = new ThreadLocal<>(); + private static final ThreadLocal ROLE_ID = new ThreadLocal<>(); + private static final ThreadLocal SCH_ID = new ThreadLocal<>(); + private static final ThreadLocal IP = new ThreadLocal<>(); + + // 原有 setter/getter 示例(请确保都有) + public static void setUserId(Integer userId) { + USER_ID.set(userId); + } + public static Integer getUserId() { + return USER_ID.get(); + } + + public static void setUserName(String userName) { + USER_NAME.set(userName); + } + public static String getUserName() { + return USER_NAME.get(); + } + + public static void setRoleId(Integer roleId) { + ROLE_ID.set(roleId); + } + public static Integer getRoleId() { + return ROLE_ID.get(); + } + + public static void setSchId(Integer schId) { + SCH_ID.set(schId); + } + public static Integer getSchId() { + return SCH_ID.get(); + } + + // ⬇️ 新增 IP 的 setter/getter + public static void setIp(String ip) { + IP.set(ip); + } + public static String getIp() { + return IP.get(); + } + + @Value + public static class UserInfo { + Integer userId; + String userName; + Integer roleId; + Integer schId; + String ip; + } + + public static UserInfo getCurrentUserInfo() { + return new UserInfo( + USER_ID.get(), + USER_NAME.get(), + ROLE_ID.get(), + SCH_ID.get(), + IP.get() + ); + } + + public static void setUserInfo(UserInfo info) { + if (info == null) return; // 或抛异常 + USER_ID.set(info.getUserId()); + USER_NAME.set(info.getUserName()); + ROLE_ID.set(info.getRoleId()); + SCH_ID.set(info.getSchId()); + IP.set(info.getIp()); + } + + public static Runnable wrap(Runnable task) { + UserInfo info = getCurrentUserInfo(); + return () -> { + try { + setUserInfo(info); + task.run(); + } finally { + clear(); + } + }; + } + + public static void clear() { + USER_ID.remove(); + USER_NAME.remove(); + ROLE_ID.remove(); + SCH_ID.remove(); + IP.remove(); + } +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/utils/ValidateUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/ValidateUtil.java new file mode 100644 index 0000000..0d10ad9 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/utils/ValidateUtil.java @@ -0,0 +1,148 @@ +package com.bestsch.bschclassmanage.utils; + +import cn.hutool.core.util.StrUtil; + +import java.util.regex.Pattern; + +public class ValidateUtil { + // ==================== 身份证号验证 ==================== + // 格式正则(允许空串) + private static final String ID_CARD_REGEX = + "^$|^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$"; + private static final Pattern PATTERN = Pattern.compile(ID_CARD_REGEX); + + // 校验位权重因子(前17位) + private static final int[] WEIGHT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 校验码映射表 + private static final char[] VERIFY_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; + + /** + * 基础格式校验(允许空串) + * @param idCard 身份证号(可为 null) + * @return true 格式正确或空串;false 格式错误(包括 null) + */ + public static boolean isValidIdCard(String idCard) { + if (idCard == null) { + return false; + } + return PATTERN.matcher(idCard).matches(); + } + + /** + * 校验最后一位校验码是否正确(仅用于18位身份证) + * @param idCard 18位身份证号(必须符合基本格式,此方法不检查格式) + * @return true 校验位匹配;false 不匹配或输入无效 + */ + private static boolean verifyCheckDigit(String idCard) { + if (idCard == null || idCard.length() != 18) { + return false; + } + // 转为大写(兼容小写x) + idCard = idCard.toUpperCase(); + int sum = 0; + for (int i = 0; i < 17; i++) { + char c = idCard.charAt(i); + if (c < '0' || c > '9') { + return false; // 前17位必须全数字 + } + sum += (c - '0') * WEIGHT[i]; + } + char expected = VERIFY_CODE[sum % 11]; + return idCard.charAt(17) == expected; + } + + /** + * 全量校验:格式正确 + 校验位正确(空串仍视为合法) + * @param idCard 身份证号 + * @return true 完全合法(或空串);false 任何一项不合法(包括 null) + */ + public static boolean isValidIdCardStrict(String idCard) { + if (idCard == null) { + return false; + } + // 先用格式校验 + if (!isValidIdCard(idCard)) { + return false; + } + // 空串直接通过(业务允许不填) + if (idCard.isEmpty()) { + return true; + } + // 18位长度,校验校验位 + return verifyCheckDigit(idCard); + } + + /** + * 获取详细的错误信息(用于前端提示) + * @param idCard 身份证号 + * @return 若合法返回 null,否则返回具体错误原因 + */ + public static String getValidateMessage(String idCard) { + if (idCard == null) { + return "身份证号不能为null"; + } + if (!isValidIdCard(idCard)) { + return "身份证号码格式不正确(需为18位有效格式)"; + } + if (!idCard.isEmpty() && !verifyCheckDigit(idCard)) { + return "身份证号码校验位错误(最后一位不匹配)"; + } + return null; // 合法 + } + // ==================== 密码验证 ==================== + + /** + * 条件校验:若密码不为空,则必须符合强密码规则 + * @param password 待校验密码 + * @return true 表示允许(要么为空,要么符合规则);false 表示填写了但格式不对 + */ + public static boolean validatePasswordIfPresent(String password) { + // 1. 如果为空,直接放行(不校验) + if (StrUtil.isBlank(password)) { + return true; + } + // 2. 如果有值,则必须符合强密码规则 + return isValidStrongPassword(password); + } + + // 强密码正则(复用之前的) + private static boolean isValidStrongPassword(String password) { + String regex = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]).{8,}$"; + return Pattern.matches(regex, password); + } + + + // ==================== 手机号验证 ==================== + + // 手机号正则(允许空串;11位,1开头,第二位3-9,后跟9位数字) + private static final String MOBILE_REGEX = "^$|^1[3-9]\\d{9}$"; + private static final Pattern MOBILE_PATTERN = Pattern.compile(MOBILE_REGEX); + + /** + * 校验手机号格式(允许空串) + * @param mobile 手机号(可为 null) + * @return true 表示格式正确或为空串;false 表示格式错误(包括 null) + */ + public static boolean isValidMobile(String mobile) { + if (mobile == null) { + return false; + } + return MOBILE_PATTERN.matcher(mobile).matches(); + } + + /** + * 获取手机号的详细错误信息(用于前端提示) + * @param mobile 手机号 + * @return 若合法返回 null,否则返回具体错误原因 + */ + public static String getMobileValidateMessage(String mobile) { + if (mobile == null) { + return "手机号不能为null"; + } + if (!isValidMobile(mobile)) { + return "手机号格式不正确(需为11位有效号码,如 13800138000)"; + } + return null; // 合法 + } + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/bschclassmanage/utils/ValidationUtil.java b/src/main/java/com/bestsch/bschclassmanage/utils/ValidationUtil.java new file mode 100644 index 0000000..8142960 --- /dev/null +++ b/src/main/java/com/bestsch/bschclassmanage/utils/ValidationUtil.java @@ -0,0 +1,46 @@ +package com.bestsch.bschclassmanage.utils; + +import javax.validation.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class ValidationUtil { + private static final Validator validator; + + static { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + validator = factory.getValidator(); + } + + public static void validate(Object object) { + Set> violations = validator.validate(object); + if (!violations.isEmpty()) { + for (ConstraintViolation violation : violations) { + System.out.println(violation.getMessage()); // 输出错误信息 + } + throw new ConstraintViolationException(violations); // 可以根据需要抛出异常 + } + } + + /** + * 校验对象,返回所有错误信息(去重) + * @param object 待校验对象 + * @return 错误信息列表(若无错误,返回空列表) + */ + public static List validateMsgs(Object object) { + if (object == null) { + return new ArrayList<>(); // 或 throw new IllegalArgumentException("校验对象不能为空") + } + Set> violations = validator.validate(object); + if (violations.isEmpty()) { + return new ArrayList<>(); // 空列表 + } + // 提取错误信息并去重 + return violations.stream() + .map(ConstraintViolation::getMessage) + .distinct() + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java deleted file mode 100644 index 9c698ec..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.BschKnowledge; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Optional; - -/** - * @ Description : java类作用描述 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:21 - * @ Company : bestsch - */ -@Repository -public interface BschKnowledgeRepository extends JpaRepository { - - @Query("from BschKnowledge where id = :id") - BschKnowledge getById(int id); - - List getAllByParentIdOrderByOrderCodeAsc(int parentId); - - List getAllByPathLikeOrderByOrderCodeAsc(String path); - - /** - * 获取同层级 某个排序区间内的知识节点 - * @param parentId - * @param begin - * @param end - * @return - */ - @Query("from BschKnowledge k where k.parentId = :parentId and k.orderCode >= :begin and k.orderCode <= :end order by k.orderCode asc") - List getSection(Integer parentId, int begin, int end); - - @Query("from BschKnowledge where path like :pathKey order by orderCode asc") - List getChildByPath(String pathKey); - - @Query("from BschKnowledge k where k.parentId = :parentId order by k.orderCode asc") - List getSectionList(Integer parentId); - - List getAllByIdInOrderByLevelAsc(List ids); -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/BschLeadlearningRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/BschLeadlearningRepository.java deleted file mode 100644 index 8506a75..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/BschLeadlearningRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.BschLeadlearning; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface BschLeadlearningRepository extends JpaRepository, JpaSpecificationExecutor { - - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/BschQuestionRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/BschQuestionRepository.java deleted file mode 100644 index 58837f8..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/BschQuestionRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.BschQuestion; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface BschQuestionRepository extends JpaRepository, JpaSpecificationExecutor { - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/BschTextbookRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/BschTextbookRepository.java deleted file mode 100644 index 271d266..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/BschTextbookRepository.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.BschTextbook; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -/** - * @ Description : java类作用描述 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:22 - * @ Company : bestsch - */ -@Repository -public interface BschTextbookRepository extends JpaRepository { - /** - * 统计当前查询条件下总数据量 - * @param specification - * @return - */ - Long count(Specification specification); - - /** - * 条件查询,支持分页 - * @param specification - * @param pageable - * @return - */ - Page findAll(Specification specification, Pageable pageable); - - /** - * 条件查询,不支持分页 - * @param specification - * @return - */ - List findAll(Specification specification); - - BschTextbook getById(int id); - - BschTextbook getFirstByTreeId(int treeId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/BschVideoExplanationRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/BschVideoExplanationRepository.java deleted file mode 100644 index 858cd9f..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/BschVideoExplanationRepository.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.BschVideoExplanation; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; - -import javax.transaction.Transactional; - -public interface BschVideoExplanationRepository extends JpaRepository, JpaSpecificationExecutor { - -// @Query(value = "select * from bsch_video_explanation where textbook_id=:textbook_id and node_id=:nodeId ;", nativeQuery = true) -// List getAllBySchIdAndNodeId(Integer textbookId, Integer nodeId); - - @Query(value = "SELECT * from bsch_video_explanation where textbook_id=?1 and (node_id=?2 or path like CONCAT('%,',?2,',%')) ", - countQuery = "select count(id) from bsch_video_explanation where textbook_id=?1 and (node_id=?2 or path like CONCAT('%,',?2,',%')) ", nativeQuery = true) - Page findPageBySchIdAndNodeId(Integer textbookId, Integer nodeId, Pageable pageable); - - - @Query(value = "SELECT * from bsch_video_explanation where textbook_id=?1 and subject_id=?2 and if(?3 is null,1=1, node_id=?3 or path like CONCAT('%,',?3,',%')) and if(?4 is null,1=1,name like CONCAT('%',?4,'%')) ", - countQuery = "select count(id) from bsch_video_explanation where textbook_id=?1 and subject_id=?2 and if(?3 is null,1=1, node_id=?3 or path like CONCAT('%,',?3,',%')) and if(?4 is null,1=1,name like CONCAT('%',?4,'%')) ", nativeQuery = true) - Page findPageBySchIdAndSubjectIdAndNodeIdAndName(Integer textbookId, String subjectId, Integer nodeId, String keyword, Pageable pageable); - - - @Query(value = "select id from bsch_video_explanation where id=?1 and create_user=?2 ;", nativeQuery = true) - Integer getIdByIdAndUserId(Integer id, Integer userId); - - @Query(value = "select * from bsch_video_explanation where id=?1 ;", nativeQuery = true) - BschVideoExplanation getAllById(Integer id); - - @Transactional - @Modifying - @Query(nativeQuery = true, value = "delete from bsch_video_explanation where id=?1 ") - void deleteAllById(Integer id); - - - @Transactional - @Modifying - @Query(nativeQuery = true, value = "update bsch_video_explanation set clicks=clicks+1 where id=?1 ") - void updateClickById(Integer id); -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/FeedBackRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/FeedBackRepository.java deleted file mode 100644 index a927678..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/FeedBackRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.FeedBack; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; - - -@Repository -public interface FeedBackRepository extends JpaRepository, JpaSpecificationExecutor { - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/OcrDataCacheRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/OcrDataCacheRepository.java deleted file mode 100644 index abd3ad6..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/OcrDataCacheRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.enums.OcrDataCache; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.Query; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -@Repository -public interface OcrDataCacheRepository extends JpaRepository, JpaSpecificationExecutor { - - @Query(value = "SELECT data FROM ocr_data_cache WHERE img_url = ?1", nativeQuery = true) - Optional findDataByImgUrl(String imgUrl); -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/PunitCommunicationRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/PunitCommunicationRepository.java deleted file mode 100644 index 7ee9fbc..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/PunitCommunicationRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.PunitCommunication; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface PunitCommunicationRepository extends JpaRepository, JpaSpecificationExecutor { - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/PunitLeadlearningRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/PunitLeadlearningRepository.java deleted file mode 100644 index 3e2eaa6..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/PunitLeadlearningRepository.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.PunitLeadlearning; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.Query; - -import java.util.List; -import java.util.Map; - -public interface PunitLeadlearningRepository extends JpaRepository, JpaSpecificationExecutor { - - @Query(value = "select * from (SELECT *," + - "(select count(id) from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.stu_id=?3) as stucount," + - "(select count(id) from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.stu_id=?3 and status=1) as duicount," + - "(select count(id) from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.stu_id=?3 and status=2) as cuocount," + - "(select count(id) from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.stu_id=?3 and status not in(1,2)) as elecount," + - "(select count(id) from punit_question b where a.sch_id=b.sch_id and b.node_id=a.node_id) as qcount," + - "IFNULL((select is_review from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.stu_id=?3 LIMIT 1),0) is_review from punit_leadlearning a where sch_id=?1 and if(?2 is null,1=1,node_id=?2 or path like CONCAT('%,',?2,',%')) )c where is_review in (?4)", - countQuery = "select count(id) from (" + - " SELECT *,IFNULL((select is_review from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.stu_id=?3 LIMIT 1),0) is_review from punit_leadlearning a where sch_id=?1 and if(?2 is null,1=1,node_id=?2 or path like CONCAT('%,',?2,',%')) ) c where is_review in (?4)", nativeQuery = true) - Page> findPageBySchId(Integer schId, Integer nodeId, Integer stuId, List is_review, Pageable pageable); - - - - - @Query(value = "select * from (SELECT *," + - "(select count(DISTINCT stu_id) from punit_stu_answer b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.class_id=?3) as stucount," + - "(select count(id) from punit_communication b where a.sch_id=b.sch_id and b.node_id=a.node_id and b.c_id=0) as askcount," + - "(select count(id) from punit_question b where a.sch_id=b.sch_id and b.node_id=a.node_id) as qcount " + - " from punit_leadlearning a where sch_id=?1 and if(?4 is null,1=1,node_id=?2 or path like CONCAT('%,',?2,',%')) ) c " , - countQuery = "select count(id) from (" + - " SELECT * from punit_leadlearning a where sch_id=?1 and if(?2 is null,1=1,node_id=?2 or path like CONCAT('%,',?2,',%') ) )c where ?3=?3", nativeQuery = true) - Page> findTeaPageBySchId(Integer schId, Integer nodeId, Integer classId, Pageable pageable); - - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/PunitQuestionRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/PunitQuestionRepository.java deleted file mode 100644 index a522f3a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/PunitQuestionRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.PunitQuestion; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.Query; - -import java.util.List; -import java.util.Map; - -public interface PunitQuestionRepository extends JpaRepository, JpaSpecificationExecutor { - - - @Query(value = "select node_id,Count(id) qcount from punit_question where sch_id=?1 group by node_id",nativeQuery = true) - List findByNodeQcount(Integer schId); - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/PunitStuAnswerRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/PunitStuAnswerRepository.java deleted file mode 100644 index d3476c3..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/PunitStuAnswerRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.PunitStuAnswer; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.Query; - -import java.util.List; -import java.util.Map; - -public interface PunitStuAnswerRepository extends JpaRepository, JpaSpecificationExecutor { - - @Query(value = "select node_id,Count(id) qcount from punit_question where sch_id=?1 and grade_id=?2 and subject_id=?3 group by node_id",nativeQuery = true) - List findByNodeQcount(Integer schId, Integer gradeId, String subjectId); - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/PunitZiYuanTreeTeaRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/PunitZiYuanTreeTeaRepository.java deleted file mode 100644 index 267d3ba..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/PunitZiYuanTreeTeaRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.PunitZiYuanTreeTea; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface PunitZiYuanTreeTeaRepository extends JpaRepository, JpaSpecificationExecutor { - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/UploadFileRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/UploadFileRepository.java deleted file mode 100644 index d456f62..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/UploadFileRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.UploadFile; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; - -@Repository -public interface UploadFileRepository extends JpaRepository, JpaSpecificationExecutor { - -} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/VideoExplanationRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/VideoExplanationRepository.java deleted file mode 100644 index b3ab537..0000000 --- a/src/main/java/com/bestsch/classicalchinese/Repository/VideoExplanationRepository.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.bestsch.classicalchinese.Repository; - -import com.bestsch.classicalchinese.entity.VideoExplanation; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; - -import javax.transaction.Transactional; -import java.util.List; - -public interface VideoExplanationRepository extends JpaRepository, JpaSpecificationExecutor { - - @Query(value = "select * from video_explanation where sch_id=:schId and node_id=:nodeId ;", nativeQuery = true) - List getAllBySchIdAndNodeId(Integer schId, Integer nodeId); - - - @Query(value = "SELECT * from video_explanation where sch_id=?1 and (node_id=?2 or path like CONCAT('%,',?2,',%')) ", - countQuery = "select count(id) from video_explanation where sch_id=?1 and (node_id=?2 or path like CONCAT('%,',?2,',%')) ", nativeQuery = true) - Page findPageBySchIdAndNodeId(Integer schId, Integer nodeId, Pageable pageable); - - - - @Query(value = "SELECT * from video_explanation where sch_id=?1 and subject_id=?2 and if(?3 is null,1=1, node_id=?3 or path like CONCAT('%,',?3,',%')) and if(?4 is null,1=1,name like CONCAT('%',?4,'%')) ", - countQuery = "select count(id) from video_explanation where sch_id=?1 and subject_id=?2 and if(?3 is null,1=1, node_id=?3 or path like CONCAT('%,',?3,',%')) and if(?4 is null,1=1,name like CONCAT('%',?4,'%')) ", nativeQuery = true) - Page findPageBySchIdAndSubjectIdAndNodeIdAndName(Integer schId, String subjectId, Integer nodeId, String keyword, Pageable pageable); - - - @Query(value = "select id from video_explanation where id=?1 and create_user=?2 ;", nativeQuery = true) - Integer getIdByIdAndUserId(Integer id, Integer userId); - - @Query(value = "select * from video_explanation where id=?1 ;", nativeQuery = true) - VideoExplanation getAllById(Integer id); - - @Transactional - @Modifying - @Query(nativeQuery = true, value = "delete from video_explanation where id=?1 ") - void deleteAllById(Integer id); - - - @Transactional - @Modifying - @Query(nativeQuery = true, value = "update video_explanation set clicks=clicks+1 where id=?1 ") - void updateClickById(Integer id); -} diff --git a/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrComponent.java b/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrComponent.java deleted file mode 100644 index 2f2098d..0000000 --- a/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrComponent.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.bestsch.classicalchinese.baidu; - -import com.bestsch.classicalchinese.enums.OcrDataCache; -import com.bestsch.classicalchinese.service.IOcrDataCacheService; -import com.bestsch.classicalchinese.utils.FileUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import com.baidu.aip.ocr.AipOcr; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Optional; - -/** - * @author CHY - * @date 2024/5/31 16:51 - */ -@Component -@Slf4j -public class AipOcrComponent { - - @Autowired - private AipOcr aipOcr; - @Autowired - private IOcrDataCacheService iOcrDataCacheService; - - /** - * 手写文字识别 - */ - private String handwriting(byte[] image) { - JSONObject handwriting = aipOcr.handwriting(image, new HashMap<>()); - List list = new ArrayList<>(); - try { - JSONArray wordsResult = handwriting.getJSONArray("words_result"); - for (int i = 0; i < wordsResult.length(); i++) { - String words = wordsResult.getJSONObject(i).getString("words"); - list.add(words); - } - } catch (JSONException e) { - log.error("手写文字识别handwriting方法报错:", e); - } - - if (!list.isEmpty()) { - String data = String.join("", list); - log.info("手写识别结果:{}", data); - return data; - } - return ""; - } - - /** - * 手写文字识别url - */ - public String handwriting(String imageUrl) { - // 先从db中拿 - Optional optional = iOcrDataCacheService.findDataByImgUrl(imageUrl); - if (optional.isPresent()) { - return optional.get(); - } - - byte[] imageBytes = FileUtil.getBytes(imageUrl); - - String data = imageBytes.length == 0 ? "" : handwriting(imageBytes); - // 存db - if (StringUtils.isNotBlank(data)) { - OcrDataCache ocrDataCache = new OcrDataCache(null, imageUrl, data); - iOcrDataCacheService.save(ocrDataCache); - } - return data; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrConfig.java b/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrConfig.java deleted file mode 100644 index cebd0b0..0000000 --- a/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.bestsch.classicalchinese.baidu; - -import com.baidu.aip.ocr.AipOcr; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author CHY - * @date 2024/5/31 16:51 - */ -@Configuration -public class AipOcrConfig { - - @Autowired - private BaiDuConfigProperties baiDuConfigProperties; - - @Bean - public AipOcr createClient() { - // 初始化一个AipOcr - AipOcr client = new AipOcr(baiDuConfigProperties.getAppId(), baiDuConfigProperties.getAppKey(), baiDuConfigProperties.getAppSecret()); - // 可选:设置网络连接参数 - client.setConnectionTimeoutInMillis(2000); - client.setSocketTimeoutInMillis(60000); - return client; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/baidu/BaiDuConfigProperties.java b/src/main/java/com/bestsch/classicalchinese/baidu/BaiDuConfigProperties.java deleted file mode 100644 index 83f73e4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/baidu/BaiDuConfigProperties.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.bestsch.classicalchinese.baidu; - -import lombok.Data; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -/** - * @author CHY - * @date 2023/10/12 17:28 - */ -@Component -@Data -public class BaiDuConfigProperties { - - @Value("${baidu.api.app_id}") - private String appId; - - @Value("${baidu.api.app_secret}") - private String appSecret; - - @Value("${baidu.api.app_key}") - private String appKey; -} diff --git a/src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java b/src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java deleted file mode 100644 index cd50cba..0000000 --- a/src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.bestsch.classicalchinese.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -/** - * 解决跨域 - */ -@Configuration -public class DWebMvcConfig implements WebMvcConfigurer { - - @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowedOrigins("*") - .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") - .allowedHeaders("*") - .maxAge(3600).allowCredentials(true); - } -} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/controller/BaseController.java b/src/main/java/com/bestsch/classicalchinese/controller/BaseController.java deleted file mode 100644 index e579575..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/BaseController.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.bestsch.classicalchinese.controller; - - -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.classicalchinese.model.Page; -import com.bestsch.classicalchinese.service.IBschTextbookService; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; - - -@Slf4j -public class BaseController { - - protected Page getPageVO(String page, String pageCount) { - Page pageVO = new Page(); - if (StringUtils.isNumeric(pageCount)) { - int num = Integer.valueOf(pageCount); - /*if (num>50) { - pageVO.setPageSize(50); - }*/ - pageVO.setPageSize(Double.valueOf(pageCount).intValue()); - } - if (StringUtils.isNumeric(page)) { - pageVO.setCurrent(page); - } - return pageVO; - } - - - public static Integer getIntByString(String str){ - Integer id = null; - if (str != null && StringUtils.isNotBlank(str) && !str.equals("null")) - id = Integer.valueOf(str); - return id; - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/Handler/ValidationExceptionHandler.java b/src/main/java/com/bestsch/classicalchinese/controller/Handler/ValidationExceptionHandler.java deleted file mode 100644 index 1b17bd8..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/Handler/ValidationExceptionHandler.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.bestsch.classicalchinese.controller.Handler; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.FieldError; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import java.util.HashMap; -import java.util.Map; - -@RestControllerAdvice -public class ValidationExceptionHandler { - - @ExceptionHandler(MethodArgumentNotValidException.class) - public ResponseEntity> handleValidationExceptions(MethodArgumentNotValidException ex) { - Map errors = new HashMap<>(); - ex.getBindingResult().getAllErrors().forEach(error -> { - String fieldName = ((FieldError) error).getField(); - String errorMessage = error.getDefaultMessage(); - errors.put(fieldName, errorMessage); - }); - return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/BschSettingsController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/BschSettingsController.java deleted file mode 100644 index 4daddfe..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/BschSettingsController.java +++ /dev/null @@ -1,374 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import cn.afterturn.easypoi.excel.ExcelExportUtil; -import cn.afterturn.easypoi.excel.ExcelImportUtil; -import cn.afterturn.easypoi.excel.entity.ExportParams; -import cn.afterturn.easypoi.excel.entity.ImportParams; -import com.alibaba.fastjson.JSON; -import com.bestsch.classicalchinese.service.IBschKnowledgeService; -import com.bestsch.classicalchinese.service.IBschTextbookService; -import com.bestsch.classicalchinese.service.com.ZiyuankuService; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.controller.BaseController; -import com.bestsch.classicalchinese.entity.*; -import com.bestsch.classicalchinese.model.ExcelBschLeadlearning; -import com.bestsch.classicalchinese.model.Page; -import com.bestsch.classicalchinese.model.SystemGrade; -import com.bestsch.classicalchinese.model.vo.BschFormQuestionVo; -import com.bestsch.classicalchinese.service.impl.*; -import com.bestsch.classicalchinese.utils.EasyPoiUtils; -import com.bestsch.classicalchinese.utils.ModelMapperUtil; -import com.bestsch.classicalchinese.utils.ValidationUtil; -import com.bestsch.utils.DException; -import com.bestsch.utils.ErrorCode; -import org.apache.commons.collections.ListUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.poi.ss.usermodel.Workbook; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.constraints.NotBlank; -import java.util.*; -import java.util.stream.Collectors; - - -@RestController -@RequestMapping(Config.API_PATH+"/bschset/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class BschSettingsController extends BaseController { - - @Autowired - private BschLeadlearningService bschLeadlearningService; - - @Autowired - private BschExplanationService bschExplanationService; - - @Autowired - private BschQuestionService bschQuestionService; - - @Autowired - private IBschKnowledgeService bschKnowledgeService; - - @Autowired - private IBschTextbookService bschTextbookService; - /************************************************* 知识树节点相关接口 ************************************************/ - - @RequestMapping("addKnowledge") - public BschKnowledge addKnowledge(Integer parentId, String name){ - if(StringUtils.isBlank(name) - || parentId == null){ - throw new DException(ErrorCode.WRONG_REQUEST_PARAMS); - } - return bschKnowledgeService.addKnowledge(parentId,name); - } - - @PostMapping("delKnowledge") - public void delKnowledge(Integer id){ - if(id == null){ - throw new DException(ErrorCode.WRONG_REQUEST_PARAMS); - } - bschKnowledgeService.delKnowledge(id); - } - - @PostMapping("setKnowledge") - public BschKnowledge setKnowledge(Integer id, String name){ - if(id == null){ - throw new DException(ErrorCode.WRONG_REQUEST_PARAMS); - } - BschKnowledge knowledge = new BschKnowledge(); - knowledge.setName(name); - return bschKnowledgeService.setKnowledge(id,knowledge); - } - - @PostMapping("setKnowledgeOrder") - public void setKnowledgeOrder(Integer id, Integer replaceId){ - if(id == null - || replaceId == null){ - throw new DException(ErrorCode.WRONG_REQUEST_PARAMS); - } - bschKnowledgeService.setOrder(id,replaceId); - } - - /** 功能描述: 获取指定教材知识树结构 - * @param - * @return: - * @Author: cls - * @Date: 2021/3/17 17:04 - */ - @GetMapping("getKnowledgeTree") - public Map getKnowledgeTree(HttpServletRequest reques){ - Integer textbookId=this.getTextbookId(reques); - Map result = new HashMap<>(); - result.put("tree",bschKnowledgeService.getTreeOfSystemForApi(textbookId)); - //getTreeOfSystemForApi(textbookId) - return result; - } - - @GetMapping("getTextbookId") - public Integer getTextbookId(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getId(); - else - throw new DException(""); - } - - @GetMapping("getTextbookName") - public String getTextbookName(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getName(); - else - return ""; - } - -// /** 功能描述: 设置知识树的维护人员 -// * @param knowledgeId 知识节点id -// * @param users 维护人信息集合 [{id:xxx,name:"xxx"}] 以替换的形式更新 -// * @return: -// * @Author: cls -// * @Date: 2021/3/22 15:58 -// */ -// @PostMapping("knowledge/maintainer/set") -// public List setKnowledgeMaintainer(Integer knowledgeId, Integer schoolSid, String users){ -// if(knowledgeId == null || schoolSid == null){ -// throw new DException(ErrorCode.WRONG_REQUEST_PARAMS); -// } -// return bschKnowledgeService.set(knowledgeId,schoolSid,users); -// } - - /*************************************************/ - -// @GetMapping("getAllGrade") -// public List> getAllGrade() { -// List> list = new ArrayList<>(); -// for (SystemGrade grade : SystemGrade.values()) { -// Map map = new HashMap<>(); -// map.put("id",grade.getGradeId()); -// map.put("name",grade.getGradeName()); -// list.add(map); -// } -// return list; -// } - -// @GetMapping("getKnowledgeTree") -// public Object getKnowledgeTree(BoaUser authUserWithDept,@RequestParam(required = true) Integer textbookId){ -// List textbookIds=new ArrayList<>(Arrays.asList(textbookId)); -// return ziyuankuService.getKnowledgeTree_cache(textbookIds); -// } - - @GetMapping("getSubdirectoryList") - public Object getSubdirectoryList(HttpServletRequest reques,BoaUser authUserWithDept){ - int textbookId=getTextbookId(reques); - return bschKnowledgeService.getSubdirectoryList(textbookId); - } - - @GetMapping("getEndNodeList") - public Object getEndNodeList(HttpServletRequest reques){ - int textbookId=getTextbookId(reques); - return bschKnowledgeService.getEndNodeList(textbookId); - } - - - @GetMapping("getLeadlearning") - public Optional getLeadlearning(HttpServletRequest reques,BoaUser authUserWithDept, @RequestParam(required = true) Integer nodeId - ) { - int textbookId=getTextbookId(reques); - return bschLeadlearningService.findOne(textbookId,nodeId); - } - - @PostMapping("saveLeadlearning") - public void saveLeadlearning(HttpServletRequest reques,BoaUser authUserWithDept, - @RequestParam(required = true) Integer nodeId, - @RequestParam(required = true) String content, - @RequestParam(required = true) String path - ) { - int textbookId=getTextbookId(reques); - if(authUserWithDept.getType()!=1) throw new DException("无权限!"); - BschLeadlearning model=new BschLeadlearning(); - Optional modelOpt = bschLeadlearningService.findOne(textbookId,nodeId); - model.setId(modelOpt.map(BschLeadlearning::getId).orElse(0)); - model.setTextbookId(textbookId); - model.setContent(content); - model.setNodeId(nodeId); - model.setPath(path); - model.setCDate(new Date()); - model.setCUserId(authUserWithDept.getId()); - bschLeadlearningService.save(model); - } - - -// @GetMapping("DownBschLeadlearningTemp") -// public void DownBschLeadlearningTemp(HttpServletResponse response, -// @RequestParam(value = "textbookId", required = false) Integer textbookId) { -// List list= bschLeadlearningService.getExcelBschLeadlearning(textbookId); -// String fileName="导入模板"; -// String titleName ="内容导入" ; -// ExportParams exportParams = new ExportParams(titleName, ""); -// Workbook workbook2 = ExcelExportUtil.exportExcel(exportParams, ExcelBschLeadlearning.class, list); -// EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook2); -// } - - -// @PostMapping("ImportBschLeadlearningTemp") -// public void ImportPunitTeaTemp(UserSysRole curRole, -// @RequestPart("file") MultipartFile file, -// @RequestParam(value = "textbookId", required = false) Integer textbookId -// ) throws Exception -// { -// List errorMsgArr=new ArrayList<>(); -// List baseList=new ArrayList(); -// ImportParams params = new ImportParams(); -// params.setTitleRows(1); -// params.setHeadRows(1); -// -// try { -// List treenodelist= bschZiYuanTreeService.getTreeNodeList(textbookId); -// -// List list = ExcelImportUtil.importExcel(file.getInputStream(), ExcelBschLeadlearning.class, params); -// int rows=0; -// Date date=new Date(); -// for (ExcelBschLeadlearning item:list) { -// -// rows+=1; -// if(item.getCname()==null){ -// errorMsgArr.add("第"+(rows+2)+"行,章节不能为空!"); -// continue; -// } -// Optional treenodeFirst=treenodelist.stream().filter(s->s.get("cname").toString().equals(item.getCname())).findFirst(); -// -// if(!treenodeFirst.isPresent()) -// { -// errorMsgArr.add("第"+(rows+2)+"行,“"+item.getCname()+"”章节不存在!"); -// continue; -// } -// -// Integer nodeId=Integer.parseInt(treenodeFirst.get().get("id").toString()); -// String path=treenodeFirst.get().get("path").toString(); -// { -// BschLeadlearning model = new BschLeadlearning(); -// model.setCDate(date); -// model.setCUserId(curRole.getUserId()); -// model.setPath(path); -// model.setNodeId(nodeId); -// model.setContent(item.getBschLeadlearning()); -// model.setTextbookId(textbookId); -// baseList.add(model); -// } -// } -// if(errorMsgArr.size()>0) throw new DException(String.join("
",errorMsgArr)); -// -// bschLeadlearningService.saveAll(baseList); -// } catch (Exception e) { -// System.out.println(e); -// throw new Exception("导入失败,请联系管理员!
错误详情:
" + e.getMessage().toString()); -// } -// } - - - @GetMapping("getExplanationList") - public Object getExplanationList(BoaUser authUserWithDept, - @RequestParam(required = true) Integer textbookId, - @RequestParam(required = true) Integer nodeId,@RequestParam(defaultValue = "1") Integer page, - @RequestParam(defaultValue = "10") Integer count - - ) { - Page pageVO = getPageVO(page.toString(), count.toString()); - Sort sort = Sort.by(Sort.Order.desc("create_time")); - Pageable pageable = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(),sort); - return bschExplanationService.getExplanationList(textbookId,authUserWithDept.getId(),nodeId,pageable); - } - - - @PostMapping("saveExplanation") - public void saveExplanation(BoaUser authUserWithDept, - @RequestBody List list - ) { - if (authUserWithDept.getType() !=1 ) - throw new NullPointerException("您没有该权限!"); - bschExplanationService.saveExplanation(authUserWithDept.getId(),list); - } - - - @PostMapping("saveExplanation1") - public void saveExplanation1(BoaUser authUserWithDept, @RequestBody Map map) { - bschExplanationService.saveExplanation1(authUserWithDept.getId(), map); - } - - - - @GetMapping("findNodeQuestion") - public List findNodeQuestion(HttpServletRequest reques, - @RequestParam(value = "nodeId", required = true) Integer nodeId) - { - int textbookId=getTextbookId(reques); - return bschQuestionService.findGradeMapAll(nodeId,textbookId); - } - - @PostMapping("saveNodeQuestion") - public void findNodeQuestion(BoaUser authUserWithDept,@RequestBody @NotBlank String jsonData) - { - Date date=new Date(); - BschFormQuestionVo form = JSON.parseObject(jsonData, BschFormQuestionVo.class); - List questions=form.getQuestionList(); - long questionCount=questions.stream().map(BschQuestion::getName).distinct().count(); - if(questionCount!=questions.stream().count()) throw new DException("题目存在重复!"); - - for (BschQuestion qtem:questions) { - ValidationUtil.validate(qtem); - if(qtem.getId()==null) qtem.setId(0); - qtem.setNodeId(qtem.getNodeId()); - qtem.setTextbookId(qtem.getTextbookId()); - } - - List questionList=bschQuestionService.findNoteAll(form.getNodeId(),form.getTextbookId()); - List dbquestionIds=questionList.stream().filter(s->s.getId() != null &&s.getId()>0).map(BschQuestion::getId).collect(Collectors.toList()); - List jsonQuestionIds=questions.stream().filter(s->s.getId() != null &&s.getId()>0).map(BschQuestion::getId).collect(Collectors.toList()); - - for (BschQuestion qtem:questions) { - Optional bschQuestionOpt=questionList.stream().filter(s->s.getId().equals(qtem.getId())).findFirst(); - BschQuestion eniity=new BschQuestion(); - //数据库赋值(用户,时间,学校) - if(bschQuestionOpt.isPresent()) eniity=bschQuestionOpt.get(); - - eniity= ModelMapperUtil.map(qtem,BschQuestion.class);//编辑或添加赋值 - eniity.setCUserId(authUserWithDept.getId()); - eniity.setCDate(date); - bschQuestionService.save(eniity); - } - List delquestionIds= ListUtils.subtract(dbquestionIds,jsonQuestionIds); - if(delquestionIds.stream().count()>0) - { - List delQuestionList=questionList.stream().filter(s->delquestionIds.contains(s.getId())).collect(Collectors.toList()); - bschQuestionService.deleteAll(delQuestionList); - } - } - - - - - - - - - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/CommonController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/CommonController.java deleted file mode 100644 index 164dd3c..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/CommonController.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.service.ICommonService; -import com.bestsch.classicalchinese.service.com.*; -import com.bestsch.utils.DException; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.bind.annotation.*; - -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping(Config.API_PATH+"/com/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class CommonController { - - @Value("${FILE_PATH}") - private String FILE_PATH; - - @Autowired - private ICommonService commonService; - - @Autowired - private UserGradeClassSubService userGradeClassSubService; - - /** - * 获取学科年级学期 - * 教师端,不用传gradeId - */ -// @GetMapping("getSubjectGradeTerm") -// public Object getSubjectGradeTerm(UserSysRole curRole,@RequestParam(required = false) Integer gradeId){ -// return commonService.getSubjectGradeTerm(curRole.getSchId(),curRole.getRoleId(),curRole.getUserId(),gradeId); -// } -// -// @GetMapping("getTeaSubGradeTrem") -// public Object getTeaSubGradeTrem(UserSysRole curRole){ -// return commonService.getTeaSubGradeTrem(curRole.getRoleId(),curRole.getSchId(),curRole.getUserId()); -// } - - /** - * 知识树节点 - */ -// @GetMapping("getChapterWrongQuestNumTree") -// public Object getChapterWrongQuestNumTree(UserSysRole curRole, -// String subjectId, Integer gradeId, Integer year, Integer term, -// @RequestParam(required = false) String checkedIds) { -// if (StringUtils.isEmpty(subjectId) || gradeId == null) -// throw new DException("年级或学科不能为空!"); -// -// return commonService.getChapterWrongQuestNumTree(curRole.getSchId(), subjectId, gradeId, year, term, checkedIds); -// } - -// @GetMapping("getChapterWrongQuestNumTree") -// public Object getChapterWrongQuestNumTree(UserSysRole curRole, -// String subjectId, -// @RequestParam(required = false) String checkedIds) { -// if (StringUtils.isEmpty(subjectId)) -// throw new DException("学科不能为空!"); -// -// return commonService.getChapterWrongQuestNumTree(curRole.getSchId(), curRole.getUserId(), subjectId,checkedIds); -// } - - - /** - * 知识树节点--年级学期(墨水瓶) - */ -// @GetMapping("getGradeTerm") -// public Object getGradeTerm(UserSysRole curRole,Integer gradeId){ -// return commonService.getGradeTerm(curRole.getSchId(),curRole.getUserId(),gradeId); -// } - - /** - * 获取年级班级 - */ - @GetMapping("getGradeClass") - public List getGradeClass(UserSysRole curRole){ - return commonService.getGradeClass(curRole.getSchId(),curRole.getRoleId(),curRole.getUserId()); - } - - /** - * 获取班级学生 - */ - @GetMapping("getClassStuList") - public List getClassStuList(UserSysRole curRole,Integer classId){ - return commonService.getClassStuList(curRole.getSchId(),classId); - } - - - @GetMapping("getSchTeaTree") - public Object getSchTeaTree(UserSysRole curRole){ - return commonService.getSchTeaTree(curRole.getSchId()); - } - - - @GetMapping("geTeaGradeSubClass") - public Object geTeaGradeSubClass(UserSysRole curRole) - { - return userGradeClassSubService.GetList(curRole.getRoleId(),curRole.getUserId(),curRole.getSchId()); - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/ExplanationController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/ExplanationController.java deleted file mode 100644 index 4ff36d1..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/ExplanationController.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.classicalchinese.service.impl.BschTextbookService; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.service.IExplanationService; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.controller.BaseController; -import com.bestsch.classicalchinese.entity.VideoExplanation; -import com.bestsch.classicalchinese.model.Page; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -@RestController -@RequestMapping(Config.API_PATH+"explanation/") -@CrossOrigin(origins = {"*"}, allowCredentials = "true") -public class ExplanationController extends BaseController { - @Autowired - private IExplanationService explanationService; - - @Autowired - private BschTextbookService bschTextbookService; - - @GetMapping("getTextbookId") - public Integer getTextbookId(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getId(); - else - return null; - } - - /** - * 讲解--列表 - */ - @GetMapping("getExplanationList") - public Object getExplanationList(UserSysRole curRole,Integer nodeId, - @RequestParam(defaultValue = "1") Integer page, - @RequestParam(defaultValue = "10") Integer count){ - if (curRole.getRoleId() !=1 && curRole.getRoleId()!=2 && curRole.getRoleId() !=7) - throw new NullPointerException("您没有该权限!"); - - Page pageVO = getPageVO(page.toString(), count.toString()); - Sort sort = Sort.by(Sort.Order.desc("create_time")); - Pageable pageable = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(),sort); - - return explanationService.getExplanationList(curRole.getSchId(),curRole.getUserId(),nodeId,pageable); - } - - /** - * 讲解--添加 - */ - @PostMapping("saveExplanation") - public void saveExplanation(HttpServletRequest reques,UserSysRole curRole, @RequestBody List list) { - if (curRole.getRoleId() !=1 && curRole.getRoleId()!=2 && curRole.getRoleId() !=7) - throw new NullPointerException("您没有该权限!"); - - Integer textbookId=getTextbookId(reques); - for (VideoExplanation vmodel:list) - { - vmodel.setTextbookId(textbookId); - } - explanationService.saveExplanation(curRole.getSchId(), curRole.getUserId(), list); - } - - @PostMapping("saveExplanation1") - public void saveExplanation1(UserSysRole curRole, @RequestBody Map map) { - explanationService.saveExplanation1(curRole.getSchId(), curRole.getUserId(), map); - } - - - - /** - * 讲解--删除 - */ - @PostMapping("deleteExplanation") - public void deleteExplanation(UserSysRole curRole,Integer id){ - if (curRole.getRoleId() !=1 && curRole.getRoleId()!=2 && curRole.getRoleId() !=7) - throw new NullPointerException("您没有该权限!"); - - if(curRole.getRoleId()==7||curRole.getRoleId()==2) - explanationService.deleteExplanation(id); - else - explanationService.deleteExplanation(curRole.getUserId(),id); - } - - - - - /** - * 从资源库选择--知识树 - */ - @GetMapping("getZYKSubjectTree") - public Object getZYKSubjectTree(UserSysRole curRole, - @RequestParam(required = false) Integer nodeId){ - - return explanationService.getZYKSubjectTree(curRole.getSchId(),curRole.getUserId(),nodeId); - } - - /** - * 从资源库选择--视频列表 - */ - @GetMapping("getZYKVideoList") - public Object getZYKVideoList(UserSysRole curRole,Integer nodeId, - @RequestParam(defaultValue = "1") Integer page, - @RequestParam(defaultValue = "10") Integer count){ - return explanationService.getZYKVideoList(curRole.getSchId(),curRole.getUserId(),curRole.getRoleId(),nodeId,page,count); - } - - @GetMapping("pdfPreview") - public Object pdfPreview(UserSysRole curRole,Integer id){ - return explanationService.pdfPreview(curRole.getSchId(),id); - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java deleted file mode 100644 index 504d50e..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java +++ /dev/null @@ -1,288 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import com.bestsch.classicalchinese.model.YearSemester; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.controller.BaseController; -import com.bestsch.classicalchinese.entity.*; -import com.bestsch.classicalchinese.model.Grade; -import com.bestsch.classicalchinese.model.vo.PunitFormVo; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.impl.*; -import com.bestsch.classicalchinese.utils.ModelMapperUtil; -import com.bestsch.classicalchinese.utils.OtherUtil; -import com.bestsch.classicalchinese.utils.ValidationUtil; -import com.bestsch.utils.DException; -import org.apache.commons.collections.ListUtils; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import com.alibaba.fastjson.JSON; - -import javax.servlet.http.HttpServletRequest; -import javax.validation.constraints.NotBlank; -import java.util.*; -import java.util.stream.Collectors; - - -@RestController -@RequestMapping(Config.API_PATH+"/punitnode/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class PunitNodeController extends BaseController { - @Autowired - private PunitLeadlearningService punitLeadlearningService; - - @Autowired - private PunitQuestionService punitQuestionService; - - @Autowired - private ClassService classService; - - @Autowired - private PunitCommunicationService punitCommunicationService; - - @Autowired - public BschLeadlearningService bschLeadlearningService; - - @Autowired - private BschBaseOpenApi bschBaseOpenApi; - - @Autowired - private BschTextbookService bschTextbookService; - - @GetMapping("getTextbookId") - public Integer getTextbookId(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getId(); - else - throw new DException(""); - } - - @GetMapping("getPunitForm") - public Map getPunitForm(HttpServletRequest reques,UserSysRole curRole,@RequestParam(value = "nodeId", required = true) Integer nodeId - ) { - Integer textBookId= getTextbookId(reques); - Optional modelOpt = punitLeadlearningService.findOne(textBookId,nodeId, curRole.getSchId()); - String content = modelOpt.map(PunitLeadlearning::getContent).orElse(""); - Integer id=modelOpt.map(PunitLeadlearning::getId).orElse(0); - if(StringUtils.isEmpty(content)) - { - Optional bschLeadlearningOpt= bschLeadlearningService.findOne(textBookId,nodeId); - content= bschLeadlearningOpt.map(BschLeadlearning::getContent).orElse(""); - } - - Map map=new HashMap(); - { - map.put("id", id); - map.put("nodeId", nodeId); - map.put("content",content); - map.put("type",1); - map.put("questionList",punitQuestionService.findMapAll(nodeId,curRole.getSchId())); - } - //map.put("subjectName",getSubjectName(curRole.getSchId(),subjectId)); - //map.put("gradeName",getNameBySystemGrade(curRole.getSchId(),gradeId)); - return map; - } - - - @PostMapping("savePunitForm") - public void savePunitForm(HttpServletRequest reques,UserSysRole curRole, @RequestBody @NotBlank String jsonData) { - PunitFormVo punit = JSON.parseObject(jsonData, PunitFormVo.class); - Integer textbookId=getTextbookId(reques); - List questions=punit.getQuestionList(); - long questionCount=questions.stream().map(PunitQuestion::getName).distinct().count(); - if(questionCount!=questions.stream().count()) throw new DException("题目存在重复!"); - - //Integer textBookId= punitZiYuanTreeService.findTextBookId(punit.getYear(),punit.getTerm(),punit.getGradeId(),punit.getSubjectId(),curRole.getSchId()); - //添加修改删除 - for (PunitQuestion qtem:questions) { - ValidationUtil.validate(qtem); - if(qtem.getId()==null) qtem.setId(0); - qtem.setNodeId(punit.getNodeId()); - qtem.setTextbookId(textbookId); - } - Optional modelOpt = punitLeadlearningService.findOne(punit.getId(), curRole.getSchId()); - int id = modelOpt.map(PunitLeadlearning::getId).orElse(0); - PunitLeadlearning model=ModelMapperUtil.map(punit,PunitLeadlearning.class); - OtherUtil.setBaseEntityValue(curRole, model, id); - model.setTextbookId(textbookId); - punitLeadlearningService.save(model); - - - List questionList=punitQuestionService.findSchAll(punit.getNodeId(),curRole.getSchId()); - List dbquestionIds=questionList.stream().filter(s->s.getId() != null &&s.getId()>0).map(PunitQuestion::getId).collect(Collectors.toList()); - List jsonQuestionIds=questions.stream().filter(s->s.getId() != null &&s.getId()>0).map(PunitQuestion::getId).collect(Collectors.toList()); - - for (PunitQuestion qtem:questions) { - Optional punitQuestionOpt=questionList.stream().filter(s->s.getId().equals(qtem.getId())).findFirst(); - PunitQuestion eniity=new PunitQuestion(); - //数据库赋值(用户,时间,学校) - if(punitQuestionOpt.isPresent()) eniity=punitQuestionOpt.get(); - eniity.setTextbookId(textbookId); - eniity= ModelMapperUtil.map(qtem,PunitQuestion.class);//编辑或添加赋值 - OtherUtil.setBaseEntityValue(curRole, eniity, eniity.getId());////编辑或添加赋值(用户,时间,学校) - punitQuestionService.save(eniity); - } - List delquestionIds= ListUtils.subtract(dbquestionIds,jsonQuestionIds); - if(delquestionIds.stream().count()>0) - { - List delQuestionList=questionList.stream().filter(s->delquestionIds.contains(s.getId())).collect(Collectors.toList()); - punitQuestionService.deleteAll(delQuestionList); - } - } - -// private String getSubjectName(Integer schId,String subjectId){ -// List list = (List)classService.getSchoolSubject(schId); -// String subjectName = list.stream().filter(x -> Objects.equals(x.get("subId").toString(), subjectId)).map(x -> x.get("name").toString()).findFirst().orElse(null); -// return subjectName; -// } - - - @PostMapping("saveLeadlearning") - public void saveLeadlearning(HttpServletRequest reques,UserSysRole curRole, - @RequestBody @NotBlank String jsonData) { - PunitFormVo punit = JSON.parseObject(jsonData, PunitFormVo.class); - Integer textBookId= getTextbookId(reques); - Optional modelOpt = punitLeadlearningService.findOne(punit.getId(),curRole.getSchId()); - Integer id = modelOpt.map(PunitLeadlearning::getId).orElse(0); - PunitLeadlearning model=ModelMapperUtil.map(punit,PunitLeadlearning.class); - model.setTextbookId(textBookId); - OtherUtil.setBaseEntityValue(curRole, model, id); - punitLeadlearningService.save(model); - } - - - @PostMapping("saveQuestions") - public void saveQuestions(HttpServletRequest reques,UserSysRole curRole, @RequestBody @NotBlank String jsonData) { - PunitFormVo punit = JSON.parseObject(jsonData, PunitFormVo.class); - List questions=punit.getQuestionList(); - long questionCount=questions.stream().map(PunitQuestion::getName).distinct().count(); - if(questionCount!=questions.stream().count()) throw new DException("题目存在重复!"); - - Integer textbookId=getTextbookId(reques); - //添加修改删除 - for (PunitQuestion qtem:questions) { - ValidationUtil.validate(qtem); - if(qtem.getId()==null) qtem.setId(0); - qtem.setNodeId(punit.getNodeId()); - qtem.setTextbookId(textbookId); - } - - List questionList=punitQuestionService.findSchAll(punit.getNodeId(),curRole.getSchId()); - List dbquestionIds=questionList.stream().filter(s->s.getId() != null &&s.getId()>0).map(PunitQuestion::getId).collect(Collectors.toList()); - List jsonQuestionIds=questions.stream().filter(s->s.getId() != null &&s.getId()>0).map(PunitQuestion::getId).collect(Collectors.toList()); - - for (PunitQuestion qtem:questions) { - Optional punitQuestionOpt=questionList.stream().filter(s->s.getId().equals(qtem.getId())).findFirst(); - PunitQuestion eniity=new PunitQuestion(); - //数据库赋值(用户,时间,学校) - if(punitQuestionOpt.isPresent()) eniity=punitQuestionOpt.get(); - eniity.setTextbookId(textbookId); - eniity= ModelMapperUtil.map(qtem,PunitQuestion.class);//编辑或添加赋值 - OtherUtil.setBaseEntityValue(curRole, eniity, eniity.getId());////编辑或添加赋值(用户,时间,学校) - punitQuestionService.save(eniity); - } - List delquestionIds= ListUtils.subtract(dbquestionIds,jsonQuestionIds); - if(delquestionIds.stream().count()>0) - { - List delQuestionList=questionList.stream().filter(s->delquestionIds.contains(s.getId())).collect(Collectors.toList()); - punitQuestionService.deleteAll(delQuestionList); - } - - - } - - - @GetMapping("getCommunicationClassStu") - public List getClassStuList(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = false) Integer classId){ - return punitCommunicationService.getCommunicationClassStu(curRole.getSchId(),classId,nodeId); - } - - - @GetMapping("getCommunicationList") - public Object getCommunicationList(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "stuId", required = false) Integer stuId) - { - if(curRole.getRoleId()==3)stuId=curRole.getUserId(); - - return punitCommunicationService.getCommunicationList(nodeId,stuId,curRole.getSchId()); - } - - - @PostMapping("saveCommunication") - public void saveCommunication(HttpServletRequest reques,BoaUser authUser, UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = true) Integer classId, - @RequestParam(value = "id", required = true) Integer id, - @RequestParam(value = "cId", required = true) Integer cId, - @RequestParam(value = "content", required = true) String content - ) - { - - if(StringUtils.isEmpty(content)) throw new DException("内容为空!"); - if(content.length()>500) throw new DException("字符串超出限定长度(500)!"); - if (!Objects.equals(authUser.getId(),curRole.getUserId())) { - authUser = bschBaseOpenApi.getUserInfo(curRole.getUserId()); - } - - if(id>0) - { - Optional punitCommunicationOptional= punitCommunicationService.findOne(id,curRole.getUserId(),curRole.getSchId()); - if(!punitCommunicationOptional.isPresent()) throw new DException("无权限!"); - } - Integer textBookId=getTextbookId(reques); - YearSemester years= classService.getCurYearSemesterDate(); - PunitCommunication pction=new PunitCommunication(); - pction.setId(id); - pction.setYear(years.getYear()); - pction.setTerm(years.getSemester()); - pction.setCId(cId); - pction.setTextbookId(textBookId); - pction.setNodeId(nodeId); - pction.setClassId(classId); - pction.setContent(content); - pction.setCUserId(curRole.getUserId()); - pction.setUserName(authUser.getName()); - pction.setUserPhoto(authUser.getProfilePicture()); - pction.setSchId(curRole.getSchId()); - pction.setRole(curRole.getRoleId()==3?3:1); - pction.setCDate(new java.util.Date()); - punitCommunicationService.save(pction); - } - - @PostMapping("delCommunication") - public void saveCommunication(BoaUser authUser, UserSysRole curRole,Integer id) - { - Optional punitCommunicationOptional= punitCommunicationService.findOne(id,curRole.getUserId(),curRole.getSchId()); - if(!punitCommunicationOptional.isPresent()) throw new DException("无权限!"); - punitCommunicationService.delete(punitCommunicationOptional.get()); - } - -// @GetMapping("getPunitList") -// private List getPunitList(UserSysRole curRole) { -// List nodeList = bschKnowledgeService.getEndNodeList(textbookId); -// return punitLeadlearningService.getPunitList(curRole.getRoleId(), curRole.getUserId(),year,term,curRole.getSchId()); -// } - - - private String getNameBySystemGrade(Integer schId,Integer systemGrade){ - List list = classService.getGradeListBySchoolId(schId); - String name = list.stream().filter(x -> Objects.equals(x.getGradeId(), systemGrade)).map(x -> x.getName()).findFirst().orElse(null); - return name; - } - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/PunitSettingsController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/PunitSettingsController.java deleted file mode 100644 index b95f8e3..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/PunitSettingsController.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import cn.afterturn.easypoi.excel.ExcelExportUtil; -import cn.afterturn.easypoi.excel.ExcelImportUtil; -import cn.afterturn.easypoi.excel.entity.ExportParams; -import cn.afterturn.easypoi.excel.entity.ImportParams; -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.classicalchinese.service.IBschTextbookService; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.controller.BaseController; -import com.bestsch.classicalchinese.entity.PunitZiYuanTreeTea; -import com.bestsch.classicalchinese.model.ExcelPunitTreeTea; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.impl.*; -import com.bestsch.classicalchinese.utils.*; -import com.bestsch.utils.DException; -import org.apache.commons.lang.StringUtils; -import org.apache.poi.ss.usermodel.Workbook; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.*; -import java.util.stream.Collectors; - - -@RestController -@RequestMapping(Config.API_PATH+"/settings/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class PunitSettingsController extends BaseController { - - @Autowired - private PunitLeadlearningService punitLeadlearningService; - - @Autowired - private ClassService classService; - - @Autowired - private BschKnowledgeService bschKnowledgeService; - - @Autowired - private PunitZiYuanTreeTeaService punitZiYuanTreeTeaService; - - @Autowired - private IBschTextbookService bschTextbookService; - - - @GetMapping("getTextbookId") - public Integer getTextbookId(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getId(); - else - return null; - } - -// -// @GetMapping("getTreeNodeList") -// private List getTreeNodeList(UserSysRole curRole, -// @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subjectId", required = true) String subjectId -// ) { -// return punitZiYuanTreeService.findTeaTreeNodeAll(year,term,gradeId,subjectId,curRole.getSchId()); -// } -// -// -// @PostMapping("saveTreeNodeId") -// private void saveTreeNodeId(UserSysRole curRole, @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subId", required = true) String subId, -// @RequestParam(value = "nodeIds", required = true) String nodeIds -// ) -// { -// -// List nodeIdInt=new ArrayList<>(); -// if(!StringUtils.isEmpty(nodeIds)){ -// nodeIdInt=Arrays.stream(nodeIds.split(",")) -// .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); -// } -// punitZiYuanTreeService.savePunitZiYuanNodeId(curRole.getUserId(),year,term,gradeId,subId,curRole.getSchId(),nodeIdInt); -// -// } - - - @PostMapping("saveTreeNodeTea") - private void saveTreeNodeTea(UserSysRole curRole, @RequestParam(value = "year", required = true) Integer year, - @RequestParam(value = "term", required = true) Integer term, - @RequestParam(value = "gradeId", required = true) Integer gradeId, - @RequestParam(value = "subId", required = true) String subId, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "teaIds", required = true) String teaIds - ) - { - List teaIdsInt=new ArrayList<>(); - if(!StringUtils.isEmpty(teaIds)){ - teaIdsInt=Arrays.stream(teaIds.split(",")) - .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); - } - punitZiYuanTreeTeaService.saveTreeNodeTea(curRole.getUserId(),year,term,gradeId,subId,nodeId,teaIdsInt,curRole.getSchId()); - } - - - //导出研学基地模板 -// @GetMapping("DownPunitTeaTemp") -// public void DownPunitTeaTemp(HttpServletResponse response, BoaUser authUser, -// @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subjectId", required = true) String subjectId, -// @RequestParam(value = "schId", required = true) Integer schId) { -// List list= punitLeadlearningService.getExcelPunitTreeTea(authUser.getId(),year,term,gradeId,subjectId,schId); -// String fileName="预习教师导入模板"; -// String titleName ="预习教师导入"; -// ExportParams exportParams = new ExportParams(titleName, ""); -// Workbook workbook2 = ExcelExportUtil.exportExcel(exportParams, ExcelPunitTreeTea.class, list); -// EasyPoiUtils.downLoadExcel(fileName + ".xls", response, workbook2); -// } - - -// @PostMapping("ImportPunitTeaTemp") -// public void ImportPunitTeaTemp(UserSysRole curRole, -// @RequestPart("file") MultipartFile file, -// @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subjectId", required = true) String subjectId -// ) throws Exception -// { -// List errorMsgArr=new ArrayList<>(); -// List baseList=new ArrayList(); -// ImportParams params = new ImportParams(); -// params.setTitleRows(1); -// params.setHeadRows(1); -// try { -// List treenodelist= punitLeadlearningService.getPunitAllList(year,term,gradeId,subjectId,curRole.getSchId()); -// -// List tealist=classService.getSchteaList(curRole.getSchId()); -// -// List list = ExcelImportUtil.importExcel(file.getInputStream(), ExcelPunitTreeTea.class, params); -// int rows=0; -// Date date=new Date(); -// for (ExcelPunitTreeTea item:list) { -// -// rows+=1; -// if(item.getCname()==null){ -// errorMsgArr.add("第"+(rows+2)+"行,章节不能为空!"); -// continue; -// } -// Optional treenodeFirst=treenodelist.stream().filter(s->s.get("cname").toString().equals(item.getCname())).findFirst(); -// -// if(!treenodeFirst.isPresent()) -// { -// errorMsgArr.add("第"+(rows+2)+"行,“"+item.getCname()+"”章节不存在!"); -// continue; -// } -// -// if(item.getTeaNames()==null){ -// continue; -// } -// -// List cNames=Arrays.asList(item.getTeaNames().split(",")); -// -// List notExistsTeaNames=new ArrayList<>(); -// List teaIds=new ArrayList<>(); -// for (String name:cNames) -// { -// Optional teaOptional=tealist.stream().filter(s->s.get("TeaName").toString().equals(name)).findFirst(); -// if(!teaOptional.isPresent()) -// { -// notExistsTeaNames.add(name); -// }else { -// teaIds.add(Integer.parseInt(teaOptional.get().get("UserTeaSerID").toString())); -// } -// } -// if(notExistsTeaNames.stream().count()>0) -// { -// errorMsgArr.add("第"+(rows+2)+"行,教师“"+String.join(",",notExistsTeaNames)+"”不存在!"); -// continue; -// } -// Integer nodeId=Integer.parseInt(treenodeFirst.get().get("id").toString()); -// for (Integer teaId:teaIds) -// { -// PunitZiYuanTreeTea model = new PunitZiYuanTreeTea(); -// model.setCDate(date); -// model.setCUserId(curRole.getUserId()); -// model.setTeaId(teaId); -// model.setNodeId(nodeId); -// model.setSchId(curRole.getSchId()); -// baseList.add(model); -// } -// } -// if(errorMsgArr.size()>0) throw new DException(String.join("
",errorMsgArr)); -// -// punitZiYuanTreeTeaService.saveAll(baseList); -// } catch (Exception e) { -// System.out.println(e); -// throw new Exception("导入失败,请联系管理员!
错误详情:
" + e.getMessage().toString()); -// } -// } - -// @GetMapping("getGradeSubTextBookInfo") -// public List getGradeSubTextBookInfo(UserSysRole curRole, -// @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subjectId", required = true) String subjectId -// ) -// { -// List listMap=new ArrayList<>(); -// -// List nodelist= punitZiYuanTreeService.findGradeSubAll(year,term,gradeId,subjectId,curRole.getSchId()); -// -// for (PunitZiYuanTree node:nodelist) { -// Map map=new HashMap(); -// map.put("textbookld",node.getTextbookId()); -// map.put("textbookName",ziyuankuService.getTextbookInfo(node.getTextbookId())); -// listMap.add(map); -// } -// return listMap; -// } - -// @GetMapping("getTextBookInfo") -// public List getTextBookInfo(UserSysRole curRole, -// @RequestParam(value = "textbooklds", required = true) String textbooklds -// ) -// { -// List tlds= Arrays.stream(textbooklds.split(",")).map(s->Integer.parseInt(s)).collect(Collectors.toList()); -// -// List listMap=new ArrayList<>(); -// for (Integer tid:tlds) { -// listMap.add(ziyuankuService.getTextbookInfo(tid)); -// } -// return listMap; -// } - - -// @GetMapping("getGradeSubTextBookId") -// public List getGradeSubTextBookId(UserSysRole curRole, -// @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subId", required = true) String subId -// ) -// { -// return punitZiYuanTreeService.findTextBookIds(year,term,gradeId,subId,curRole.getSchId()); -// } - -// @PostMapping("setGradeSubTextBookId") -// public void setGradeSubTextBookId(UserSysRole curRole, -// @RequestParam(value = "year", required = true) Integer year, -// @RequestParam(value = "term", required = true) Integer term, -// @RequestParam(value = "gradeId", required = true) Integer gradeId, -// @RequestParam(value = "subId", required = true) String subId, -// @RequestParam(value = "textbookIds", required = true) String textbookIds -// ) -// { -// List tIds= Arrays.stream(textbookIds.split(",")).map(s->Integer.parseInt(s)).collect(Collectors.toList()); -// punitZiYuanTreeService.setGradeSubTextBookId(year,term,gradeId,subId,tIds,curRole.getUserId(),curRole.getSchId()); -// } - - @GetMapping("initialization") - public void initialization(){ - - - - - } - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/RelayController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/RelayController.java deleted file mode 100644 index 410d513..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/RelayController.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import com.alibaba.fastjson.JSONObject; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.utils.DException; -import com.bestsch.utils.DHttp; -import com.bestsch.utils.JsonResp; -import com.google.common.base.Joiner; -import com.google.common.collect.Maps; -import org.apache.commons.lang.StringUtils; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import java.io.*; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -/** - * @program: QualityEvaluate - * @description: 转发第三发接口请求 - * @author: chenx - * @create: 2023-08-30 14:43 - **/ -@RestController -@RequestMapping(Config.API_PATH+"/relay/") -public class RelayController { - - //, Map paramsMap - @GetMapping(value = "doGet", produces = "application/json") - public Object doGet(BoaUser authUserWithDept, UserSysRole curRole, @RequestHeader("RelayUrl") String apiUrl, - @RequestParam HashMap map ) { -// System.out.println("curRole============"+ JSON.toJSONString(curRole)); - apiUrl += apiUrlInit(apiUrl); - apiUrl += "&" + asUrlParams(map); - apiUrl +="&"+ asRoleParams(curRole); - -// System.out.println("apiUrl============"+apiUrl); - String resultStr = DHttp.get(apiUrl, getRoleMap(curRole)); - return formatRespStr(resultStr); - } - - @PostMapping(value = "doPost", produces = "application/json") - public Object doPost(BoaUser authUserWithDept, UserSysRole curRole, - @RequestHeader("RelayUrl") String apiUrl, - @RequestBody HashMap map ) { - apiUrl += apiUrlInit(apiUrl); - apiUrl += "&" + asRoleParams(curRole); - String jsonString = JSONObject.toJSONString(map); -// String resultStr= DHttp.post(apiUrl,jsonString.getBytes(),getRoleMap(currentRole)); - Map header = getRoleMap(curRole); - header.put("Content-Type", "application/json"); - String resultStr = DHttp.post(apiUrl, jsonString.getBytes(), header); - return formatRespStr(resultStr); - } - - @PostMapping(value = "doPost2", produces = "application/json") - public Object doPost2(BoaUser authUserWithDept,UserSysRole curRole, - @RequestHeader("RelayUrl") String apiUrl, - @RequestParam HashMap map ) { - String postData = asRoleParams(curRole); - apiUrl += apiUrlInit(apiUrl); - apiUrl += "&"+asUrlParams(map); - String resultStr = DHttp.post(apiUrl, postData.getBytes(), getRoleMap(curRole)); - return formatRespStr(resultStr); - } - - @PostMapping(value = "doUpload", produces = "application/json") - public Object doUpload(UserSysRole curRole, - @RequestHeader("RelayUrl") String apiUrl, - @RequestParam HashMap map, - @RequestPart("file") MultipartFile file)throws Exception { - apiUrl += apiUrlInit(apiUrl); - apiUrl +="&"+ asRoleParams(curRole); - - Map header = getRoleMap(curRole); - Map fileMap = new HashMap<>(); - fileMap.put("file", multipartFile2File(file)); - String resultStr = DHttp.formUpload(apiUrl, map, fileMap, header); - if(StringUtils.isEmpty(resultStr))return Optional.empty(); - else return formatRespStr(resultStr); - } - - - - private Map getRoleMap(UserSysRole curRole){ - Map header=new HashMap<>(); - header.put("schId",String.valueOf(curRole.getSchId())); - header.put("userId",String.valueOf(curRole.getUserId())); - header.put("roleId",String.valueOf(curRole.getRoleId())); - header.put("currentRole", JSONObject.toJSONString(curRole)); -// System.out.println("header============"+ JSONObject.toJSONString(header)); - return header; - } - - private String setRoleParams(String apiUrl,UserSysRole curRole){ -// if(apiUrl==null)apiUrl="1=1"; -// else if(apiUrl.indexOf("?")==-1) apiUrl+="?1=1"; - apiUrl+="schId=" + curRole.getSchId(); - apiUrl+="&userId="+ curRole.getUserId(); - apiUrl+="&roleId="+ curRole.getRoleId(); - return apiUrl; - } - private String asRoleParams(UserSysRole curRole) { - String paramsStr=""; - paramsStr+="schId=" + curRole.getSchId(); - paramsStr+="&userId="+ curRole.getUserId(); - paramsStr+="&roleId="+ curRole.getRoleId(); - return paramsStr; - } - - - private static File multipartFile2File(MultipartFile multipartFile) throws IOException { - InputStream inputStream = multipartFile.getInputStream(); - String fileName=multipartFile.getOriginalFilename(),extension= "tmp"; - int lastIndex = fileName.lastIndexOf("."); - if (lastIndex != -1 && lastIndex < fileName.length() - 1) { - extension = fileName.substring(lastIndex + 1); - } - File file = File.createTempFile(multipartFile.getOriginalFilename(),"."+ extension); - FileOutputStream outputStream = new FileOutputStream(file); - byte[] buffer = new byte[1024]; - int bytesRead = 0; - while ((bytesRead = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - outputStream.close(); - file.deleteOnExit(); - return file; - } - - private Object formatRespStr(String resultStr){ - JSONObject json = JSONObject.parseObject(resultStr); - if(json.containsKey("State") && json.getBoolean("State")== false){ - if(json.get("Message")!=null)throw new DException(json.getString("Message")); - else throw new DException(JSONObject.toJSON(json.get("Data")).toString()); - } - JsonResp resp= JSONObject.parseObject(resultStr, JsonResp.class); - if(resp.getCode()==0){ - if( resp.getData()!=null) return resp.getData(); - else return Optional.empty(); - } - else{ - if(resp.getMsg()!=null) throw new DException(resp.getMsg()); - else throw new DException(JSONObject.toJSONString(resp.getData())); - } - } - - public String asUrlParams( Map source){ - Map tmp = Maps.newHashMap(); - // java8 语法 - source.forEach((k, v) -> { - if (k != null){ - try { - tmp.put(k, URLEncoder.encode(v, "utf-8")); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - }); - return Joiner.on("&").useForNull("").withKeyValueSeparator("=").join(tmp); - } - - private String apiUrlInit(String apiUrl) { - return apiUrl.indexOf("?") == -1 ? "?1=1" : ""; - } - - private static String hexToString(String hex) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < hex.length(); i += 2) { - String hexSubstring = hex.substring(i, i + 2); - int decimalValue = Integer.parseInt(hexSubstring, 16); - sb.append((char) decimalValue); - } - return sb.toString(); - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/StatisticsController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/StatisticsController.java deleted file mode 100644 index b225dbd..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/api/StatisticsController.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.bestsch.classicalchinese.controller.api; - -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.service.impl.PunitStuAnswerService; -import com.bestsch.classicalchinese.service.impl.StatisticsService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; -import org.springframework.web.bind.annotation.*; - -import java.util.*; - -@RestController -@RequestMapping(Config.API_PATH+"/statistics/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class StatisticsController { - - @Autowired - private StatisticsService statisticsService; - - @Autowired - private PunitStuAnswerService punitStuAnswerService; - - //1 根据章节 班级 统计 完成度 学生名单 year term nodeId classId - @GetMapping("getClassWcqk") - public Map getClassWcqk(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = true) Integer classId - ) { - return statisticsService.getClassWcqk(curRole.getSchId(),nodeId,classId); - } - - @GetMapping("getStuPunitList") - public Map getStuPunitList(UserSysRole curRole, - @RequestParam(value = "stuId", required = true) Integer stuId, - Pageable pageable - ) { - List status= Arrays.asList(0,1); - return statisticsService.getStuPunitList(curRole.getSchId(),stuId,status,pageable); - } - - @GetMapping("getStuSeeQuestion") - public Map getStuSeeQuestion(UserSysRole curRole,Integer nodeId) - { - return punitStuAnswerService.getStuSeeQuestion(nodeId,curRole.getUserId(),curRole.getSchId()); - } - - @GetMapping("findStuAnswerRecordAll") - public List findStuAnswerRecordAll(UserSysRole curRole,Integer stuId,Integer nodeId) - { - return punitStuAnswerService.findStuAnswerRecordAll(nodeId,stuId,curRole.getSchId()); - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java deleted file mode 100644 index bb3280f..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java +++ /dev/null @@ -1,328 +0,0 @@ -package com.bestsch.classicalchinese.controller.mobiapi; - - -import com.alibaba.fastjson.JSON; -import com.bestsch.classicalchinese.entity.BschKnowledge; -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.entity.FeedBack; -import com.bestsch.classicalchinese.entity.PunitCommunication; -import com.bestsch.classicalchinese.enums.GradeEnum; -import com.bestsch.classicalchinese.enums.SchoolSection; -import com.bestsch.classicalchinese.enums.Subject; -import com.bestsch.classicalchinese.model.ClassInfo; -import com.bestsch.classicalchinese.model.YearSemester; -import com.bestsch.classicalchinese.model.vo.SubmitStuQuestionVo; -import com.bestsch.classicalchinese.service.ICommonService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.impl.*; -import com.bestsch.utils.BschUtils; -import com.bestsch.utils.DException; -import com.bestsch.utils.ErrorCode; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.sql.Date; -import java.util.*; -import java.util.stream.Collectors; - -@RestController -@RequestMapping(Config.MOBILEAPI_PATH+"com/") -@CrossOrigin(origins = {"*"}, allowCredentials = "true") -public class MobiCommonController { - @Autowired - private ICommonService commonService; - - @Autowired - private ClassService classService; - - @Autowired - private BschBaseOpenApi bschBaseOpenApi; - - @Autowired - private PunitStuAnswerService punitStuAnswerService; - - @Autowired - private ExplanationService explanationService; - - @Autowired - private FeedBackService feedBackService; - - @Autowired - private PunitCommunicationService punitCommunicationService; - - @Autowired - private BschTextbookService bschTextbookService; - - - @Autowired - private BschKnowledgeService bschKnowledgeService; - - @GetMapping("getTextbookId") - public Integer getTextbookId(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getId(); - else - throw new DException(""); - } - -// /** -// * 知识树节点--年级学期 -// */ -// @GetMapping("getGradeTerm") -// public Object getGradeTerm(UserSysRole curRole,Integer gradeId){ -// return commonService.getGradeTerm(curRole.getSchId(),curRole.getUserId(),gradeId); -// } - -// /** -// * 知识树节点 -// */ -// @GetMapping("getChapterWrongQuestNumTree") -// public Object getChapterWrongQuestNumTree(UserSysRole curRole, -// String subjectId, Integer gradeId, Integer year, Integer term, -// @RequestParam(required = false) String checkedIds) { -// if (StringUtils.isEmpty(subjectId) || gradeId == null) -// throw new DException(String.valueOf(ErrorCode.WRONG_REQUEST_PARAMS)); -// return commonService.getChapterWrongQuestNumTree(curRole.getSchId(), year, term, checkedIds); -// } - -// @GetMapping("getChapterWrongQuestNumTree") -// public Object getChapterWrongQuestNumTree(UserSysRole curRole, -// String subjectId, -// @RequestParam(required = false) String checkedIds) { -// if (StringUtils.isEmpty(subjectId)) -// throw new DException(String.valueOf(ErrorCode.WRONG_REQUEST_PARAMS)); -// -// return commonService.getChapterWrongQuestNumTree(curRole.getSchId(), curRole.getUserId(), subjectId, checkedIds); -// } - - /** - * 获取学生的班级、年级、学段信息 - */ - @GetMapping("getStuInfo") - public Object getStuInfo(BoaUser authUser, UserSysRole curRole) { - if (curRole.getRoleId() != 3) { - throw new DException("只支持学生用户"); - } - if (!Objects.equals(authUser.getId(),curRole.getUserId())) { - authUser = bschBaseOpenApi.getUserInfo(curRole.getUserId()); - } - ClassInfo classInfo = classService.getClassInfo(authUser.getGroupId()); - if (classInfo == null) { - throw new DException("未获取到班级信息"); - } - Optional sectionIdOptional = GradeEnum.getSectionIdBySystemGrade(classInfo.getGradeId()); - com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(classInfo)); - jsonObject.put("sectionId", sectionIdOptional.orElse(null)); - jsonObject.put("stuId", authUser.getId()); - jsonObject.put("stuName", authUser.getName()); - jsonObject.put("classId", classInfo.getClassId()); - jsonObject.put("gradeId", classInfo.getGradeId()); - jsonObject.put("year",classService.getCurYearSemesterDate().getYear()); - jsonObject.put("term",classService.getCurYearSemesterDate().getSemester()); - return jsonObject; - } - - - - //获取学生的科目 - @GetMapping("GetStuSubject") - public List getStuSubject(UserSysRole curRole) - { - - Set schoolSectionSet = classService.getSchoolSection(curRole.getSchId()); - - if (BschUtils.isEmpty(schoolSectionSet)) return new ArrayList<>(); - - List dtoList = new ArrayList<>(); - - for (SchoolSection.Dto dto: SchoolSection.dtoList()) - { - if (!schoolSectionSet.contains(dto.getId())) continue; - - dtoList.addAll(dto.getSubjects()); - } - - return dtoList.stream().distinct().collect(Collectors.toList()); - } - - @GetMapping("getKnowledgeTree") - public Map getKnowledgeTree(HttpServletRequest reques){ - Integer textbookId=this.getTextbookId(reques); - Map result = new HashMap<>(); - result.put("tree",bschKnowledgeService.getTreeOfSystemForApi(textbookId)); - //getTreeOfSystemForApi(textbookId) - return result; - } - - @GetMapping("getSubdirectoryList") - public Object getSubdirectoryList(HttpServletRequest reques,BoaUser authUserWithDept){ - int textbookId=getTextbookId(reques); - return bschKnowledgeService.getSubdirectoryList(textbookId); - } - -// @GetMapping("getPunitList") -// public Object getPunitList(UserSysRole curRole, String subjectId, Integer gradeId, Integer nodeId,String statusStr, Pageable pageable) -// { -// if(StringUtils.isEmpty(statusStr)) throw new DException("status is null"); -// List status= Arrays.stream(statusStr.split(",")) -// .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); -// return punitStuAnswerService.getPageBySchId(curRole.getSchId(),gradeId,subjectId,nodeId,curRole.getUserId(),status,pageable); -// } - - -// @GetMapping("getPunitList") -// public Object getPunitList(UserSysRole curRole, String subjectId, Integer gradeId, Integer nodeId,String statusStr, Pageable pageable) -// { -// if(StringUtils.isEmpty(statusStr)) throw new DException("status is null"); -// List status= Arrays.stream(statusStr.split(",")) -// .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); -// return punitStuAnswerService.getPageBySchId(curRole.getSchId(),gradeId,subjectId,nodeId,curRole.getUserId(),status,pageable); -// } - - @GetMapping("getStuPunitList") - public Object getStuPunitList(HttpServletRequest reques,UserSysRole curRole, Integer nodeId, String statusStr,String name,Date startDate, Pageable pageable) - { - if(StringUtils.isEmpty(statusStr)) throw new DException("status is null"); - List status= Arrays.stream(statusStr.split(",")) - .mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()); - - int textbookId=getTextbookId(reques); - return punitStuAnswerService.getStuPageByList(textbookId,curRole.getSchId(),nodeId,curRole.getUserId(),startDate,status,pageable); - } - - - @GetMapping("getPunitNodeInfo") - public Object getPunitNodeInfo(HttpServletRequest reques,UserSysRole curRole,Integer nodeId) - { - int textbookId=getTextbookId(reques); - return punitStuAnswerService.getPunitNodeInfo(textbookId,curRole.getSchId(),curRole.getUserId(),nodeId); - } - - @GetMapping("getExplanationList") - public Object getExplanationList(UserSysRole curRole,Integer nodeId,Pageable pageable){ - Sort sort = Sort.by(Sort.Order.desc("create_time")); - pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(),sort); - return explanationService.getExplanationList(curRole.getSchId(),curRole.getUserId(),nodeId,pageable); - } - -// @GetMapping("getQuestionList") -// public Object getQuestionList(UserSysRole curRole,Integer nodeId,Pageable pageable){ -// Sort sort = Sort.by(Sort.Order.desc("create_time")); -// pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(),sort); -// return punitStuAnswerService.getQuestionList(curRole.getSchId(),curRole.getUserId(),nodeId,pageable); -// } - - @GetMapping("getStuSeeQuestion") - public Map getStuSeeQuestion(UserSysRole curRole,Integer nodeId) - { - return punitStuAnswerService.getStuSeeQuestion(nodeId,curRole.getUserId(),curRole.getSchId()); - } - - @GetMapping("findStuAnswerRecordAll") - public List findStuAnswerRecordAll(UserSysRole curRole,Integer nodeId) - { - return punitStuAnswerService.findStuAnswerRecordAll(nodeId,curRole.getUserId(),curRole.getSchId()); - } - - @PostMapping("saveStuAnswerRecord") - public void saveStuAnswerRecord(HttpServletRequest reques,BoaUser authUser,UserSysRole curRole,SubmitStuQuestionVo model) - { - int textbookId=getTextbookId(reques); - if (curRole.getRoleId() != 3) { - throw new DException("只支持学生用户"); - } - if (!Objects.equals(authUser.getId(),curRole.getUserId())) { - authUser = bschBaseOpenApi.getUserInfo(curRole.getUserId()); - } - ClassInfo classInfo = classService.getClassInfo(authUser.getGroupId()); - if (classInfo == null) { - throw new DException("未获取到班级信息"); - } - model.setTextbookId(textbookId); - YearSemester curYear = classService.getCurYearSemesterDate(); - punitStuAnswerService.saveStuAnswerRecord(model,authUser.getId(),authUser.getName(),authUser.getGroupId(),curYear.getYear(),curYear.getSemester(),curRole.getSchId()); - } - - @PostMapping("correctStuAnswer") - public void correctStuAnswer(BoaUser authUser,UserSysRole curRole,Integer nodeId) - { - punitStuAnswerService.correctStuAnswer(authUser.getId(),curRole.getSchId(),nodeId); - } - - - - @GetMapping("getCommunicationList") - public Object getCommunicationList(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = true) Integer classId) - { - return punitCommunicationService.getClassCommunicationList(nodeId,classId,curRole.getSchId()); - } - - @PostMapping("saveCommunication") - public void saveCommunication(HttpServletRequest reques,BoaUser authUser, UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = true) Integer classId, - @RequestParam(value = "id", required = true) Integer id, - @RequestParam(value = "cId", required = true) Integer cId, - @RequestParam(value = "content", required = true) String content - ) - { - if(StringUtils.isEmpty(content)) throw new DException("内容为空!"); - if(content.length()>500) throw new DException("字符串超出限定长度(500)!"); - if (!Objects.equals(authUser.getId(),curRole.getUserId())) { - authUser = bschBaseOpenApi.getUserInfo(curRole.getUserId()); - } - - if(id>0) - { - Optional punitCommunicationOptional= punitCommunicationService.findOne(id,curRole.getUserId(),curRole.getSchId()); - if(!punitCommunicationOptional.isPresent()) throw new DException("无权限!"); - } - YearSemester years= classService.getCurYearSemesterDate(); - int textbookId=getTextbookId(reques); - - PunitCommunication pction=new PunitCommunication(); - pction.setId(id); - pction.setYear(years.getYear()); - pction.setTerm(years.getSemester()); - pction.setCId(cId); - pction.setTextbookId(textbookId); - pction.setNodeId(nodeId); - pction.setClassId(classId); - pction.setContent(content); - pction.setCUserId(curRole.getUserId()); - pction.setUserName(authUser.getName()); - pction.setUserPhoto(authUser.getProfilePicture()); - pction.setSchId(curRole.getSchId()); - pction.setRole(curRole.getRoleId()==3?3:1); - pction.setCDate(new java.util.Date()); - punitCommunicationService.save(pction); - } - - /** - * 学生创建问题反馈 - */ - @PostMapping("addFeedBack") - public void addFeedBack(@RequestBody @Validated FeedBack feedBack, BoaUser authUser, @ModelAttribute UserSysRole curRole) { - int userId = curRole.getUserId(); - feedBack.setUserId(userId); - feedBackService.addFeedBack(feedBack); - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiFileController.java b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiFileController.java deleted file mode 100644 index f848149..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiFileController.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.bestsch.classicalchinese.controller.mobiapi; - -import com.alibaba.fastjson.JSONArray; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.config.FileConfig; -import com.bestsch.classicalchinese.entity.UploadFile; -import com.bestsch.classicalchinese.enums.FileType; -import com.bestsch.classicalchinese.model.FileMessage; -import com.bestsch.classicalchinese.service.IExplanationService; -import com.bestsch.classicalchinese.service.com.UploadFileService; -import com.bestsch.classicalchinese.utils.FileUtil; -import com.bestsch.classicalchinese.utils.VideoTransCodeUtil; -import com.bestsch.utils.BschUtils; -import com.bestsch.utils.DException; -import com.bestsch.utils.ErrorCode; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.*; - -//文件管理 -@RestController -@RequestMapping(Config.MOBILEAPI_PATH+"file/") -@CrossOrigin(origins = {"*"}, allowCredentials = "true") -@Slf4j -public class MobiFileController -{ - @Autowired - private IExplanationService explanationService; - - @Autowired - private UploadFileService uploadFileService; - - @Autowired - private FileConfig fileConfig; - - @PostMapping(value = "uploadFile") - public Object save(@RequestParam(value = "file", required = false) MultipartFile[] files) - { - String pathName = "optionFile/"; - - List uploadFiles = uploadFile(files, pathName); - if (BschUtils.isEmpty(uploadFiles)) return new ArrayList<>(); - - List res = uploadFileService.save(uploadFiles); - getWebFileName(res, pathName); - return res; - } - - //base64数据图片上传 - @PostMapping(value = "uploadFileByBase64") - public Object save(String base64, @PathVariable String platform) - { - JSONArray jsonArray = JSONArray.parseArray(base64); - - List fileList = new ArrayList<>(); - for (int i = 0; i < jsonArray.size(); i++) - { - String base64Str = jsonArray.getString(i); - - int inx = base64Str.indexOf(","); - base64Str = base64Str.substring(inx + 1); - - byte[] bytes = Base64.getDecoder().decode(base64Str); - - UploadFile uploadFile = new UploadFile(); - //todo 这里要用字符串头里的信息来确定文件类型 - uploadFile.setRealName(".jpg"); - uploadFile.setBytes(bytes); - - fileList.add(uploadFile); - } - - if (BschUtils.isEmpty(fileList)) return new ArrayList<>(); - - String pathName = "optionFile/"; - saveUploadFile(fileList, pathName); - - for (UploadFile uploadFile: fileList) - uploadFile.setFileUrl(fileConfig.getWebPath() + pathName + uploadFile.getRealName()); - - return fileList; - } - - - - @PostMapping("deleteById") - public void findById(@RequestParam("id") String id) - { - if (StringUtils.isEmpty(id) || !StringUtils.isNumeric(id)) - throw new DException(String.valueOf(ErrorCode.WRONG_REQUEST_PARAMS)); - - uploadFileService.delete(Integer.parseInt(id)); - } - - /** - * 上传文件 - */ - @PostMapping("uploadFile1") - public Map uploadFile1(MultipartFile file) throws IOException { - if (file == null || file.isEmpty()) { - throw new DException("上传文件不能为空"); - } - - String originalFilename = file.getOriginalFilename(); - String fileType = originalFilename.substring(originalFilename.lastIndexOf(".")); - String fileName = UUID.randomUUID().toString() + fileType; - String filePath = fileConfig.getPath() + fileName; - String webPath = fileConfig.getWebPath() + fileName; - - Files.copy(file.getInputStream(), Paths.get(filePath), StandardCopyOption.REPLACE_EXISTING); - - Map map = new HashMap<>(); - map.put("fileName", fileName); - map.put("webPath", webPath); - return map; - } - - @GetMapping("mkdir") - public void mkdir(String dirName) { - String filePath = fileConfig.getPath() + dirName; - File file = new File(filePath); - file.mkdirs(); - } - - public List getWebFileName(List uploadFiles, String path) { - if (uploadFiles!=null) { - for (UploadFile file : uploadFiles) { - String videoPicture = file.getVideoPicture(); - String fileUrl = file.getFileUrl(); - if (StringUtils.isNotEmpty(videoPicture)) - file.setVideoPicture(fileConfig.getWebPath() + path + videoPicture); - if (StringUtils.isNotEmpty(fileUrl)) file.setFileUrl(fileConfig.getWebPath() + path + fileUrl); - } - - } - return uploadFiles; - } - - //按数据列表存储 - protected void saveUploadFile(List files, String pathName) - { - if (BschUtils.isEmpty(files)) return; - - String path = fileConfig.getPath() + pathName; - - for (UploadFile uploadFile: files) - { - String ext = "." + FileUtil.getExtensionName(uploadFile.getRealName()); - String name = FileUtil.randName(path, ext); - String filePath = path + name; - - FileUtil.save( new ByteArrayInputStream(uploadFile.getBytes()), filePath); - - uploadFile.setRealName(name); - } - } - - protected List uploadFile(MultipartFile[] files, String pathName) - { - List uploadFiles = new ArrayList<>(); - try - { - if (files != null && files.length > 0) - { - synchronized (this) - { - for (MultipartFile file : files) - { - if (!file.isEmpty()) - { - String realName = file.getOriginalFilename(); - Integer fileTypeId = FileUtil.getFileType(file); - String path = fileConfig.getPath() + pathName; - UploadFile uploadFile = new UploadFile(); - String fileName = ""; - String fileSize = ""; - if (fileTypeId.equals(FileType.VIDEO_TYPE.getId()) || fileTypeId.equals(FileType.AUDIO_TYPE.getId())) - { - FileMessage message = null; - try - { - message = VideoTransCodeUtil.VideoTransCode(path, file); - } - catch (Exception e) - { - log.error(e.getMessage()); - } - fileName = message.getFileName(); - fileSize = message.getSize(); - uploadFile.setVideoPicture(message.getPictureName()); - uploadFile.setVideoTime(message.getVideoSize()); - } - else - { - fileName = FileUtil.uploadImg(file, path); - fileSize = FileUtil.getSize((int) file.getSize()); - } - uploadFile.setFileUrl(fileName); - uploadFile.setRealName(realName); - uploadFile.setFileType(fileTypeId); - uploadFile.setFileSize(fileSize); - uploadFiles.add(uploadFile); - } - } - } - } - } - catch (Exception e) - { - log.error(e.getMessage()); - } - return uploadFiles; - } - - @GetMapping("pdfPreview") - public Object pdfPreview(UserSysRole curRole, Integer id){ - return explanationService.pdfPreview(curRole.getSchId(),id); - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiTeaAreaController.java b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiTeaAreaController.java deleted file mode 100644 index b20c516..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiTeaAreaController.java +++ /dev/null @@ -1,250 +0,0 @@ -package com.bestsch.classicalchinese.controller.mobiapi; - - -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.classicalchinese.model.YearSemester; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.openapi.UserSysRole; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.entity.PunitCommunication; -import com.bestsch.classicalchinese.service.ICommonService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.impl.*; -import com.bestsch.utils.DException; -import com.bestsch.utils.ErrorCode; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.web.bind.annotation.*; - -import javax.servlet.http.HttpServletRequest; -import java.util.*; - -@RestController -@RequestMapping(Config.MOBILEAPI_PATH+"tea/") -@CrossOrigin(origins = {"*"}, allowCredentials = "true") -public class MobiTeaAreaController { - @Autowired - private ICommonService commonService; - - @Autowired - private ClassService classService; - - @Autowired - private BschBaseOpenApi bschBaseOpenApi; - - @Autowired - private PunitStuAnswerService punitStuAnswerService; - - @Autowired - private ExplanationService explanationService; - - @Autowired - private FeedBackService feedBackService; - - @Autowired - private PunitCommunicationService punitCommunicationService; - - @Autowired - private PunitLeadlearningService punitLeadlearningService; - - - @Autowired - private StatisticsService statisticsService; - - @Autowired - private BschTextbookService bschTextbookService; - - @Autowired - private BschKnowledgeService bschKnowledgeService; - - @GetMapping("getTextbookId") - public Integer getTextbookId(HttpServletRequest reques){ - - String apptype= reques.getHeader("apptype"); - String xdCode= reques.getHeader("xdCode"); - - Optional textbookOptional= bschTextbookService.getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdCode)).findFirst(); - if(textbookOptional.isPresent()) - return textbookOptional.get().getId(); - else - throw new DException(""); - } - - @GetMapping("getKnowledgeTree") - public Map getKnowledgeTree(HttpServletRequest reques){ - Integer textbookId=this.getTextbookId(reques); - Map result = new HashMap<>(); - result.put("tree",bschKnowledgeService.getTreeOfSystemForApi(textbookId)); - //getTreeOfSystemForApi(textbookId) - return result; - } - - @GetMapping("getSubdirectoryList") - public Object getSubdirectoryList(HttpServletRequest reques,BoaUser authUserWithDept){ - int textbookId=getTextbookId(reques); - return bschKnowledgeService.getSubdirectoryList(textbookId); - } - /** - * 知识树节点--年级学期 - */ -// @GetMapping("getGradeTerm") -// public Object getGradeTerm(UserSysRole curRole,Integer gradeId){ -// return commonService.getGradeTerm(curRole.getSchId(),curRole.getUserId(),gradeId); -// } -// -// /** -// * 知识树节点 -// */ -// @GetMapping("getChapterWrongQuestNumTree") -// public Object getChapterWrongQuestNumTree(UserSysRole curRole, -// String subjectId, Integer gradeId, Integer year, Integer term, -// @RequestParam(required = false) String checkedIds) { -// if (StringUtils.isEmpty(subjectId) || gradeId == null) -// throw new DException(String.valueOf(ErrorCode.WRONG_REQUEST_PARAMS)); -// -// return commonService.getChapterWrongQuestNumTree(curRole.getSchId(), year, term, checkedIds); -// } - - @GetMapping("GetTeaSubject") - public Object GetTeaSubject(UserSysRole curRole) - { - if (curRole.getRoleId() == 3) { - throw new DException("只支持教师用户"); - } - return classService.getTeaSubject(curRole.getSchId(),curRole.getRoleId(),curRole.getUserId()); - } - - @GetMapping("GetTeaGrade") - public Object GetTeaGrade(UserSysRole curRole,String subjectId) - { - if (curRole.getRoleId() == 3) { - throw new DException("只支持教师用户"); - } - return classService.getTeaGrade(curRole.getSchId(),curRole.getRoleId(),curRole.getUserId(),subjectId); - } - - - @GetMapping("GetTeaClasses") - public Object getTeaClassesWithStu(UserSysRole curRole, BoaUser authUserWithDept) - { - if (curRole.getRoleId() == 3) { - throw new DException("只支持教师用户"); - } - Integer schId = curRole.getSchId(); - List> teaClasses = classService.getTeaClasses(curRole.getRoleId(), curRole.getUserId(), schId); - return teaClasses; - } - - - - @GetMapping("getTeaPunitList") - public Object getTeaPunitList(HttpServletRequest reques,UserSysRole curRole,Integer classId, Integer nodeId, Pageable pageable) - { - Integer textbookId=this.getTextbookId(reques); - return punitLeadlearningService.getTeaPunitList(textbookId,curRole.getRoleId(), curRole.getUserId(),nodeId,classId,curRole.getSchId(),pageable); - } - - - - @GetMapping("getPunitNodeInfo") - public Object getPunitNodeInfo(HttpServletRequest reques,UserSysRole curRole,Integer nodeId) - { - int textbookId=getTextbookId(reques); - return punitStuAnswerService.getPunitNodeInfo(textbookId,curRole.getSchId(),curRole.getUserId(),nodeId); - } - - - @GetMapping("getExplanationList") - public Object getExplanationList(UserSysRole curRole,Integer nodeId,Pageable pageable){ - Sort sort = Sort.by(Sort.Order.desc("create_time")); - pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(),sort); - return explanationService.getExplanationList(curRole.getSchId(),curRole.getUserId(),nodeId,pageable); - } - - - @PostMapping("saveCommunication") - public void saveCommunication(HttpServletRequest reques,BoaUser authUser, UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "gradeId", required = true) Integer gradeId, - @RequestParam(value = "classId", required = true) Integer classId, - @RequestParam(value = "subjectId", required = true) String subjectId, - @RequestParam(value = "id", required = true) Integer id, - @RequestParam(value = "cId", required = true) Integer cId, - @RequestParam(value = "content", required = true) String content - ) - { - - if(StringUtils.isEmpty(content)) throw new DException("内容为空!"); - if(content.length()>500) throw new DException("字符串超出限定长度(500)!"); - if (!Objects.equals(authUser.getId(),curRole.getUserId())) { - authUser = bschBaseOpenApi.getUserInfo(curRole.getUserId()); - } - - if(id>0) - { - Optional punitCommunicationOptional= punitCommunicationService.findOne(id,curRole.getUserId(),curRole.getSchId()); - if(!punitCommunicationOptional.isPresent()) throw new DException("无权限!"); - } - - YearSemester yreas= classService.getCurYearSemesterDate(); - int textbookId=getTextbookId(reques); - PunitCommunication pction=new PunitCommunication(); - pction.setId(id); - pction.setYear(yreas.getYear()); - pction.setTerm(yreas.getSemester()); - pction.setCId(cId); - pction.setTextbookId(textbookId); - pction.setNodeId(nodeId); - pction.setClassId(classId); - pction.setContent(content); - pction.setCUserId(curRole.getUserId()); - pction.setUserName(authUser.getName()); - pction.setUserPhoto(authUser.getProfilePicture()); - pction.setSchId(curRole.getSchId()); - pction.setRole(curRole.getRoleId()==3?3:1); - pction.setCDate(new java.util.Date()); - punitCommunicationService.save(pction); - } - - @GetMapping("getCommunicationList") - public Object getCommunicationList(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = true) Integer classId) - { - return punitCommunicationService.getClassCommunicationList(nodeId,classId,curRole.getSchId()); - } - - @GetMapping("getCommunicationClassStu") - public List getClassStuList(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "gradeId", required = true) Integer gradeId, - @RequestParam(value = "subjectId", required = true) String subjectId, - @RequestParam(value = "classId", required = true) Integer classId){ - return punitCommunicationService.getCommunicationClassStu(curRole.getSchId(),classId,nodeId); - } - - @GetMapping("getStuCommunicationList") - public Object getStuCommunicationList(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "stuId", required = true) Integer stuId) - { - return punitCommunicationService.getCommunicationList(nodeId,stuId,curRole.getSchId()); - } - - - - - @GetMapping("getClassWcqk") - public Map getClassWcqk(UserSysRole curRole, - @RequestParam(value = "nodeId", required = true) Integer nodeId, - @RequestParam(value = "classId", required = true) Integer classId - ) { - return statisticsService.getClassWcqk(curRole.getSchId(),nodeId,classId); - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/oapi/HyAIController.java b/src/main/java/com/bestsch/classicalchinese/controller/oapi/HyAIController.java deleted file mode 100644 index 5c1cede..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/oapi/HyAIController.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.bestsch.classicalchinese.controller.oapi; - -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.model.AiAsk; -import com.bestsch.classicalchinese.service.com.HyAIService; -import com.bestsch.classicalchinese.utils.OtherUtil; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping(Config.OAPI+"/hyai/") -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class HyAIController { - - @Autowired - private HyAIService hyaiService; - - @PostMapping("askQuestion") - public Map askQuestion(@Valid @RequestBody AiAsk aiAsk) { - if (StringUtils.isEmpty(aiAsk.getPrompt())) throw new NullPointerException("请输入你的问题"); - long startTime = System.currentTimeMillis(); - Map map = new HashMap(); - String json = hyaiService.send(aiAsk); - map.put("body", OtherUtil.convertJsonToMapList(json)); - long endTime = System.currentTimeMillis(); - map.put("time", (endTime - startTime) / 1000 + "s"); - return map; - } - - - - @PostMapping("askQuestions") - public Map askQuestions(@Valid @RequestBody AiAsk aiAsk) { - //aiAsk.setModel("deepseek-r1:14b"); - //qwen2.5:latest - if (StringUtils.isEmpty(aiAsk.getPrompt())) throw new NullPointerException("请输入你的问题"); - long startTime = System.currentTimeMillis(); - Map map = new HashMap(); - String json = hyaiService.send(aiAsk); - List> list = OtherUtil.convertJsonToMapList(json); - map.put("body", hyaiService.getQuestionList(list)); - long endTime = System.currentTimeMillis(); - map.put("time", (endTime - startTime) / 1000 + "s"); - return map; - } - - - - @PostMapping("askLeadlearning") - public Map askLeadlearning(@Valid @RequestBody AiAsk aiAsk) { - if (StringUtils.isEmpty(aiAsk.getPrompt())) throw new NullPointerException("请输入你的问题"); - long startTime = System.currentTimeMillis(); - Map map = new HashMap(); - map.put("body", hyaiService.send(aiAsk)); - long endTime = System.currentTimeMillis(); - map.put("time", (endTime - startTime) / 1000 + "s"); - return map; - } - - @PostMapping("askCommunication") - public Map askCommunication(@Valid @RequestBody AiAsk aiAsk) { - if (StringUtils.isEmpty(aiAsk.getPrompt())) throw new NullPointerException("请输入你的问题"); - long startTime = System.currentTimeMillis(); - Map map = new HashMap(); - map.put("body", hyaiService.send(aiAsk)); - long endTime = System.currentTimeMillis(); - map.put("time", (endTime - startTime) / 1000 + "s"); - return map; - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/oapi/OapiController.java b/src/main/java/com/bestsch/classicalchinese/controller/oapi/OapiController.java deleted file mode 100644 index 08ee984..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/oapi/OapiController.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.bestsch.classicalchinese.controller.oapi; - -import com.alibaba.fastjson.JSON; -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.entity.PunitLeadlearning; -import com.bestsch.classicalchinese.entity.PunitQuestion; -import com.bestsch.classicalchinese.entity.PunitStuAnswer; -import com.bestsch.classicalchinese.entity.VideoExplanation; -import com.bestsch.classicalchinese.model.YearSemester; -import com.bestsch.classicalchinese.model.vo.PunitFormVo; -import com.bestsch.classicalchinese.service.IExplanationService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.impl.PunitLeadlearningService; -import com.bestsch.classicalchinese.service.impl.PunitQuestionService; -import com.bestsch.classicalchinese.service.impl.PunitStuAnswerService; -import com.bestsch.classicalchinese.utils.ModelMapperUtil; -import com.bestsch.classicalchinese.utils.ValidationUtil; -import org.apache.commons.collections.ListUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import javax.validation.constraints.NotBlank; -import java.util.*; -import java.util.stream.Collectors; - -@RestController -@RequestMapping(Config.OAPI) -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class OapiController { - - @Autowired - private PunitLeadlearningService punitLeadlearningService; - - @Autowired - private IExplanationService explanationService; - - @Autowired - private PunitQuestionService punitQuestionService; - - @Autowired - private PunitStuAnswerService punitStuAnswerService; - - @Autowired - private ClassService classService; - - @Autowired - private BschBaseOpenApi bschBaseOpenApi; - - @PostMapping("batchPunitLeadlearning") - public void batchPunitLeadlearning(@RequestParam(value = "schId", required = true) Integer schId, - @RequestBody @NotBlank String jsonData) { - - List punitList = JSON.parseArray(jsonData, PunitFormVo.class); - - List punitLSchList = punitLeadlearningService.findSchAll(schId); - List questionSchList= punitQuestionService.findSchAll(schId); - - Date date=new Date(); - List saveLeadlearningEntitys=new ArrayList<>(); - List saveQuestionEntitys=new ArrayList<>(); - List delQuestionAllList=new ArrayList<>(); - for (PunitFormVo punit:punitList) - { - Optional punitOpt=punitLSchList.stream().filter(s->s.getNodeId().equals(punit.getNodeId())).findFirst(); - - ValidationUtil.validate(punit); - - PunitLeadlearning model=ModelMapperUtil.map(punit,PunitLeadlearning.class); - if(punitOpt.isPresent()) model.setId(punitOpt.get().getId()); - model.setCDate(date); - model.setSchId(schId); - model.setCUserId(10000); - saveLeadlearningEntitys.add(model); - - List questions=punit.getQuestionList(); - if(questions!=null){ - //添加修改删除 - for (PunitQuestion qtem:questions) { - ValidationUtil.validate(qtem); - if(qtem.getId()==null) qtem.setId(0); - qtem.setNodeId(punit.getNodeId()); - } - //当前节点的题目 - List questionList=questionSchList.stream().filter(s->s.getNodeId().equals(punit.getNodeId())).collect(Collectors.toList()); - - List dbquestionIds=questionList.stream().filter(s->s.getId() != null &&s.getId()>0).map(PunitQuestion::getId).collect(Collectors.toList()); - List jsonQuestionIds=questions.stream().filter(s->s.getId() != null &&s.getId()>0).map(PunitQuestion::getId).collect(Collectors.toList()); - - for (PunitQuestion qtem:questions) { - Optional punitQuestionOpt=questionList.stream().filter(s->s.getId().equals(qtem.getId())).findFirst(); - PunitQuestion eniity=new PunitQuestion(); - //数据库赋值(用户,时间,学校) - if(punitQuestionOpt.isPresent()) eniity=punitQuestionOpt.get(); - - eniity= ModelMapperUtil.map(qtem,PunitQuestion.class);//编辑或添加赋值 - eniity.setCDate(date); - eniity.setSchId(schId); - eniity.setCUserId(10000); - saveQuestionEntitys.add(eniity); - } - List delquestionIds= ListUtils.subtract(dbquestionIds,jsonQuestionIds); - if(delquestionIds.stream().count()>0) - { - List delQuestionList=questionList.stream().filter(s->delquestionIds.contains(s.getId())).collect(Collectors.toList()); - delQuestionAllList.addAll(delQuestionList); - } - } - } - - if(saveLeadlearningEntitys.stream().count()>0) - punitLeadlearningService.saveAll(saveLeadlearningEntitys); - if(delQuestionAllList.stream().count()>0) - punitQuestionService.deleteAll(delQuestionAllList); - if(saveQuestionEntitys.stream().count()>0) - punitQuestionService.saveAll(saveQuestionEntitys); - } - - - - @PostMapping("batchPunitFiles") - public void batchPunitFiles(@RequestParam(value = "schId", required = true) Integer schId, - @RequestBody @NotBlank String jsonData) - { - List list=JSON.parseArray(jsonData, VideoExplanation.class); - explanationService.saveExplanation(schId,10000, list); - } - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/oapi/UploadFileController.java b/src/main/java/com/bestsch/classicalchinese/controller/oapi/UploadFileController.java deleted file mode 100644 index 3d49904..0000000 --- a/src/main/java/com/bestsch/classicalchinese/controller/oapi/UploadFileController.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.bestsch.classicalchinese.controller.oapi; - - -import com.bestsch.classicalchinese.config.Config; -import com.bestsch.classicalchinese.service.com.UploadFileService; -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 org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping(Config.OAPI) -@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") -public class UploadFileController { - - @Autowired - private UploadFileService uploadFileService; - - @PostMapping("addFile") - public List addFile(MultipartFile[] file, HttpServletRequest request) { - return uploadFileService.addFile(file, request); - } - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/BaseEntity.java b/src/main/java/com/bestsch/classicalchinese/entity/BaseEntity.java deleted file mode 100644 index 8fee058..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/BaseEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.Data; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.util.Date; - - -@Data -@MappedSuperclass -public abstract class BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = Update.class) - private Integer id; - - @Column(name = "sch_id") - private Integer schId; - - @Column(name = "c_date") - private Date cDate; - - @Column(name = "c_user_id") - private Integer cUserId; - - public @interface Update {} -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/BschKnowledge.java b/src/main/java/com/bestsch/classicalchinese/entity/BschKnowledge.java deleted file mode 100644 index 8663023..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/BschKnowledge.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.Data; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.util.Date; -import java.util.List; - - -@Data -@Entity -@Table(name = "bsch_knowledge") -public class BschKnowledge { - - /** - * id - */ - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = BaseEntity.Update.class) - private Integer id; - - /** - * 节点名称 - */ - @Column(name = "name", nullable = false) - private String name; - - /** - * 父节点 - */ - @Column(name = "parent_id", nullable = false) - private Integer parentId = 0; - - /** - * 顶层节点为空,由父节点path+父id+逗号组成 - */ - @Column(name = "path") - private String path = ""; - - /** - * 层级 从1开始 - */ - @Column(name = "level", nullable = false) - private Integer level = 1; - - /** - * 排序码 - */ - @Column(name = "order_code") - private Integer orderCode = 0; - - - @Transient - private List child; -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/BschLeadlearning.java b/src/main/java/com/bestsch/classicalchinese/entity/BschLeadlearning.java deleted file mode 100644 index 3e0cb46..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/BschLeadlearning.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.util.Date; - - -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "bsch_leadlearning") - -public class BschLeadlearning { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = BaseEntity.Update.class) - private Integer id; - - @Column(name = "c_date") - private Date cDate; - - @Column(name = "c_user_id") - private Integer cUserId; - - @Column(name = "textbook_id") - private Integer textbookId; - - @Column(name = "node_id") - private Integer nodeId; - - @Column(name = "content",length = 8000) - private String content; - - @Column(name = "path") - private String path; - - public @interface Update { - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/BschQuestion.java b/src/main/java/com/bestsch/classicalchinese/entity/BschQuestion.java deleted file mode 100644 index 8a03b9b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/BschQuestion.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.util.Date; - -/** - * @program: UserProfile - * @description: 系统应用 - * @author: chenx - * @create: 2024-05-27 15:23 - **/ - -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "bsch_question") - -public class BschQuestion { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = Update.class) - private Integer id; - - @Column(name = "textbook_id") - private Integer textbookId; - - @Column(name = "node_id") - private Integer nodeId; - - //0AI 1我的 2校本 3题库 - @Column(name = "bank_type") - private Integer bankType; - - @Column(name = "question_type_id") - private Integer questionTypeId; - - /** - * 困难程度 - */ - @Column(name = "difficult_level_id", columnDefinition = "tinyint default 4 comment '难度'") - private Integer difficultLevelId; - - @Column(name = "name", columnDefinition = "text comment '' ") - private String name; - - /** - * 选项 - */ - @Size(max = 2000, message = "题目选项长度超出限制(2000字符)!") - @Column(name = "config", columnDefinition = "text comment '' ") - private String config; - - @Size(max = 4000, message = "题目选答案长度超出限制(4000字符)!") - @Column(name = "answer",length = 4000) - private String answer; - - @Size(max = 6000, message = "题目解析长度超出限制(6000字符)!") - @Column(name = "solve",length = 6000) - private String solve; - - @Size(max = 200) - @Column(name = "solve_question_files",columnDefinition = "text comment '' ") - private String solveQuestionFiles; - - @Column(name = "score") - private Double score; - - @Column(name = "p_id") - private Integer pId;//综合题需要 - - private Integer sort=999; - - @Column(name = "c_date") - private Date cDate; - - @Column(name = "c_user_id") - private Integer cUserId; - - - public @interface Update { - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/BschTextbook.java b/src/main/java/com/bestsch/classicalchinese/entity/BschTextbook.java deleted file mode 100644 index 94f5bc0..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/BschTextbook.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import javax.persistence.*; -import java.io.Serializable; -import java.util.Date; - -import static javax.persistence.GenerationType.IDENTITY; - -/** - * @ Description : java类作用描述 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:13 - * @ Company : bestsch - */ -@Data -@Entity -@NoArgsConstructor -@AllArgsConstructor -@Table(name = "bsch_textbook") -@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) -public class BschTextbook implements Serializable { - - /** - * id - */ - @Id - @GeneratedValue(strategy = IDENTITY) - @Column(name = "id", unique = true, nullable = false) - private Integer id; - - /** - * name - */ - @Column(name = "name") - private String name; - - /** - * apptype - */ - @Column(name = "apptype") - private Integer apptype; - - /** - * grade - */ - @Column(name = "sch_paragraph") - private Integer SchParagraph; - - /** - * 学科名称 - */ - @Column(name = "subject_name") - private String subjectName; - - /** - * out_time - */ - @Column(name = "out_time") - private String outTime; - - /** - * tree_id - */ - @Column(name = "tree_id") - private Integer treeId; - - /** - * 学期 0上学期 1下学期 - */ - @Column(name = "semester") - private Integer semester; - - /** - * 封面图 - */ - //@Column(name = "cover_image") - //private String coverImage; - -// @Column(name = "c_date") -// private Date cDate; -// -// @Column(name = "c_user_id") -// private Integer cUserId; -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/BschVideoExplanation.java b/src/main/java/com/bestsch/classicalchinese/entity/BschVideoExplanation.java deleted file mode 100644 index e6bfc44..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/BschVideoExplanation.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import java.util.Date; - -import static javax.persistence.GenerationType.IDENTITY; - -/** - * 视频讲解 - */ -@Data -@Entity -@NoArgsConstructor -@AllArgsConstructor -@Table(name = "bsch_video_explanation") -public class BschVideoExplanation { - @Id - @GeneratedValue(strategy = IDENTITY) - @Column(name = "id", unique = true, nullable = false) - private Integer id; - - @Column(name = "textbook_id") - private Integer textbookId; - - - @Column(name = "node_id", nullable = false) - private Integer nodeId; - - @Column(name = "path") - private String path; - - /** - * 资源名称 - */ - @Column(name = "name", nullable = false) - private String name; - - /** - * 资源大小,单位byte - */ - @Column(name = "size", nullable = false) - private String size = "0"; - - /** - * 时长,单位毫秒。对视频/音频资源有效 - */ - @Column(name = "duration") - private Long duration; - - /** - * 资源后缀名 - */ - @Column(name = "suffix_name", nullable = false) - private String suffixName; - - /** - * 文件路径 - */ - @Column(name = "file_url", nullable = false) - private String fileUrl; - - /** - * 类型 - * 1:本地上传;2:从资源库选择; - */ - @Column(name = "type", nullable = false) - private Integer type; - - /** - * 是否同步到资源 - * 0:否;1:是; - */ - @Column(name = "is_sync_resource", nullable = false) - private Integer isSyncResource = 0; - - /** - * 创建人 - */ - @Column(name = "create_user", nullable = false) - private Integer createUser; - - /** - * 创建时间 - */ - @Column(name = "create_time", nullable = false) - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") - private Date createTime; - - public @interface Update {} -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/FeedBack.java b/src/main/java/com/bestsch/classicalchinese/entity/FeedBack.java deleted file mode 100644 index f686592..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/FeedBack.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -/** - * @author CHY - * @date 2022/9/2 10:03 - * @description 考生反馈 - */ -@Data -@Entity -@Table(name = "feed_back") -public class FeedBack { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; - - @Column(name = "textbook_id") - private Integer textbookId; - - /** - * 测验id - */ - @NotNull - @Column(name = "node_id") - private Integer nodeId; - - /** - * 创建时间 - */ - @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") - @Column(name = "create_date_time") - private LocalDateTime createDateTime; - - /** - * 返回内容 - */ - @NotBlank - @Length(max = 500) - @Column(name = "content", length = 500) - private String content; - - /** - * 学生作业 - */ - @Column(name = "stu_punit_id") - private Integer stuPunitId; - - /** - * 反馈的题目 - */ - @Column(name = "question_id") - private Integer questionId; - - @Transient - private Integer userId; -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/PunitCommunication.java b/src/main/java/com/bestsch/classicalchinese/entity/PunitCommunication.java deleted file mode 100644 index 35d2638..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/PunitCommunication.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.persistence.*; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - -/** - * @author CHY - * @date 2022/9/2 10:03 - * @description 考生反馈 - */ -@Data -@Entity -@Table(name = "punit_communication") -public class PunitCommunication extends BaseEntity { - - @Column(name = "year") - private Integer year; - - @Column(name = "term") - private Integer term; - /** - * 交流id - */ - @Column(name = "c_id") - private Integer cId; - - @NotBlank - @Length(max = 50) - @Column(name = "user_name", length = 50) - private String userName; - - @NotBlank - @Length(max = 200) - @Column(name = "user_photo", length = 200) - private String userPhoto; - - @Column(name = "textbook_id") - private Integer textbookId; - - /** - * 测验id - */ - @NotNull - @Column(name = "node_id") - private Integer nodeId; - - @NotNull - @Column(name = "class_id") - private Integer classId; - /** - * 内容 - */ - @NotBlank - @Length(max = 500) - @Column(name = "content", length = 500) - private String content; - - private Integer role; -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/PunitLeadlearning.java b/src/main/java/com/bestsch/classicalchinese/entity/PunitLeadlearning.java deleted file mode 100644 index 471e57b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/PunitLeadlearning.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - - -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "punit_leadlearning") - -public class PunitLeadlearning extends BaseEntity { - - @Column(name = "textbook_id") - private Integer textbookId; - - @Column(name = "node_id") - private Integer nodeId; - - @Column(name = "name",length = 200) - private String name; - - //PunitHistoryLeadlearning历史导学content内容8000 - @Column(name = "content",length = 8000) - private String content; - - @Column(name = "path") - private String path; - - /** - * 显示答案解析 - * 0:不显示;1:显示; - */ - @Column(name = "is_show_answer", nullable = false) - private Integer isShowAnswer=0; - - - public @interface Update { - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/PunitQuestion.java b/src/main/java/com/bestsch/classicalchinese/entity/PunitQuestion.java deleted file mode 100644 index c2e7db4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/PunitQuestion.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.util.Date; - -/** - * @program: UserProfile - * @description: 系统应用 - * @author: chenx - * @create: 2024-05-27 15:23 - **/ - -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "punit_question") - -public class PunitQuestion extends Question { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = Update.class) - private Integer id; - - @Column(name = "c_date") - private Date cDate; - - @Column(name = "c_user_id") - private Integer cUserId; - - public @interface Update { - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/PunitStuAnswer.java b/src/main/java/com/bestsch/classicalchinese/entity/PunitStuAnswer.java deleted file mode 100644 index 42852c6..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/PunitStuAnswer.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.util.Date; - -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "punit_stu_answer") - -public class PunitStuAnswer { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = Update.class) - private Integer id; - - //根据学年学期查询预习单(备份版本号) - private Integer year; - - private Integer term; - - @Column(name = "textbook_id") - private Integer textbookId; - - @Column(name = "node_id") - private Integer nodeId; - - @Column(name = "question_id") - private Integer questionId; - - @Size(max=6000,message = "答案内容超出限制(6000字符)!") - @Column(name = "stu_analysis",length = 6000) - private String stuAnalysis; - - @Column(name = "stu_id") - private Integer stuId; - - @Column(name = "stu_name",length = 50) - private String stuName; - - @Column(name = "stu_grade_id") - private Integer stuGradeId; - - @Column(name = "class_id") - private Integer classId; - - @Column(name = "gclass_name",length = 50) - private String gClassName; - - @Column(name = "score") - private Double score; - - @Column(name = "status") - private Integer status;////题目正确 1正确 2错误 3半对 - - @Column(name = "tk_status", columnDefinition = "text comment '' ") - private String tkStatus;//填空题每个填空的答案是否正确 - - @Column(name = "is_review", length = 8, columnDefinition = "tinyint default 0 comment ' 0-未批 1-已批 2-订正'") - private Integer isReview;//题目是否批阅 ' 0-未批 1-已批 2-订正' - - @Column(name = "c_date") - private Date cDate; - - @Column(name = "sch_id") - private Integer schId; - - public @interface Update { - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/PunitZiYuanTreeTea.java b/src/main/java/com/bestsch/classicalchinese/entity/PunitZiYuanTreeTea.java deleted file mode 100644 index 35e6c30..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/PunitZiYuanTreeTea.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - - -@Data -@Entity -@Table(name = "punit_ziyuantreetea") -public class PunitZiYuanTreeTea extends BaseEntity { - - @Column(name = "textbook_id") - private Integer textbookId; - - @NotNull - @Column(name = "node_id") - private Integer nodeId; - - @Column(name = "tea_id") - private Integer teaId; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/Question.java b/src/main/java/com/bestsch/classicalchinese/entity/Question.java deleted file mode 100644 index e91313d..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/Question.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; -import javax.validation.constraints.Size; - -@AllArgsConstructor -@NoArgsConstructor -@Data -@MappedSuperclass -public abstract class Question extends BaseEntity { - - @Column(name = "textbook_id") - private Integer textbookId; - - @Column(name = "node_id") - private Integer nodeId; - - //0AI 1我的 2校本 3题库 - @Column(name = "bank_type") - private Integer bankType; - - @Column(name = "question_type_id") - private Integer questionTypeId; - - /** - * 困难程度 - */ - @Column(name = "difficult_level_id", columnDefinition = "tinyint default 4 comment '难度'") - private Integer difficultLevelId; - - @Column(name = "name", columnDefinition = "text comment '' ") - private String name; - - /** - * 选项 - */ - @Size(max = 2000, message = "题目选项长度超出限制(2000字符)!") - @Column(name = "config", columnDefinition = "text comment '' ") - private String config; - - @Size(max = 4000, message = "题目选答案长度超出限制(4000字符)!") - @Column(name = "answer",length = 4000) - private String answer; - - @Size(max = 6000, message = "题目解析长度超出限制(6000字符)!") - @Column(name = "solve",length = 6000) - private String solve; - - @Size(max = 200) - @Column(name = "solve_question_files",columnDefinition = "text comment '' ") - private String solveQuestionFiles; - - - @Column(name = "score") - private Double score; - - @Column(name = "p_id") - private Integer pId;//综合题需要 - - private Integer sort=999; - -} - - diff --git a/src/main/java/com/bestsch/classicalchinese/entity/UploadFile.java b/src/main/java/com/bestsch/classicalchinese/entity/UploadFile.java deleted file mode 100644 index 0d77c2b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/UploadFile.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.bestsch.classicalchinese.entity; - - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; - -/** - *文件 - */ -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "upload_file") -public class UploadFile { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @NotNull(groups = UploadFile.Update.class) - private Integer id; - -// @Column(name="fileName") -// private String fileName; - -// @Column(name = "file_type_id",columnDefinition = "tinyint default 1 comment ' 1-图片 2-视频 3-音频'") -// private Integer fileTypeId; - - - @Column(name = "real_name") - private String realName;//文件真实名 - - @Column(name = "file_url") - private String fileUrl; - - @Column(name = "file_size") - private String fileSize; - - @Column(name = "file_type") - private Integer fileType; - - // 视屏中中间截图,包含时间戳后缀 - @Column(name = "video_Picture") - private String videoPicture; - - //视频时长 - @Column(name = "video_time") - private Long videoTime; - - @Column(name="screen_file_name") - private String screenFileName;//视频截图文件 - - - @Column(name="imgWidth") - private Integer imgWidth; - - @Column(name="imgHeight") - private Integer imgHeight; - - @Transient - private byte[] bytes; - - - public UploadFile(Integer id, String fileUrl, Integer fileType) { - this.id = id; - this.fileUrl = fileUrl; - this.fileType=fileType; - } - - public @interface Update{}; -} diff --git a/src/main/java/com/bestsch/classicalchinese/entity/VideoExplanation.java b/src/main/java/com/bestsch/classicalchinese/entity/VideoExplanation.java deleted file mode 100644 index d332c5b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/entity/VideoExplanation.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.bestsch.classicalchinese.entity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import java.util.Date; - -import static javax.persistence.GenerationType.IDENTITY; - -/** - * 视频讲解 - */ -@Data -@Entity -@NoArgsConstructor -@AllArgsConstructor -@Table(name = "video_explanation") -public class VideoExplanation { - @Id - @GeneratedValue(strategy = IDENTITY) - @Column(name = "id", unique = true, nullable = false) - private Integer id; - - /** - * 所属学校id - */ - @Column(name = "sch_id", nullable = false) - private Integer schId; - - - @Column(name = "textbook_id") - private Integer textbookId; - /** - * 节点id - */ - @Column(name = "node_id", nullable = false) - private Integer nodeId; - - @Column(name = "path") - private String path; - - /** - * 资源名称 - */ - @Column(name = "name", nullable = false) - private String name; - - /** - * 资源大小,单位byte - */ - @Column(name = "size", nullable = false) - private String size = "0"; - - /** - * 时长,单位毫秒。对视频/音频资源有效 - */ - @Column(name = "duration") - private Long duration; - - /** - * 资源后缀名 - */ - @Column(name = "suffix_name", nullable = false) - private String suffixName; - - - /** - * 文件路径 - */ - @Column(name = "file_url", nullable = false) - private String fileUrl; - - /** - * 类型 - * 1:本地上传;2:从资源库选择; - */ - @Column(name = "type", nullable = false) - private Integer type; - - /** - * 是否同步到资源 - * 0:否;1:是; - */ - @Column(name = "is_sync_resource", nullable = false) - private Integer isSyncResource = 0; - - /** - * 被点击次数 - */ - @Column(name = "clicks", nullable = false) - private Integer clicks = 0; - - /** - * 下载次数 - */ - @Column(name = "down_num", nullable = false) - private Integer downNum = 0; - - /** - * 创建人 - */ - @Column(name = "create_user", nullable = false) - private Integer createUser; - - /** - * 创建时间 - */ - @Column(name = "create_time", nullable = false) - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") - private Date createTime; -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/AnswerStatus.java b/src/main/java/com/bestsch/classicalchinese/enums/AnswerStatus.java deleted file mode 100644 index ce5b3b3..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/AnswerStatus.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -public enum AnswerStatus { - //1-正确 2-错误 0-默认 3-半对 - // I(1,"错误"); - - O(0,"默认"), - I(1,"正确"), - II(2,"错误"), - III(3,"半对"); - - - private int id; - private String name; - - AnswerStatus(int id, String name) { - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/AppType.java b/src/main/java/com/bestsch/classicalchinese/enums/AppType.java deleted file mode 100644 index cd013d0..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/AppType.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -public enum AppType { - - O(1001,"古诗文"), - I(1002,"文言文"), - II(1003,"记叙文"), - III(1004,"散文"); - - private int id; - private String name; - - AppType(int id, String name) { - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/GradeEnum.java b/src/main/java/com/bestsch/classicalchinese/enums/GradeEnum.java deleted file mode 100644 index c704861..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/GradeEnum.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.bestsch.classicalchinese.enums; - - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Optional; - - -public enum GradeEnum { - /* GRADE100("幼托",100), - GRADE101("幼小",101), - GRADE102("幼中",102), - GRADE103("幼大",103),*/ - GRADE1("一年级上", 1, 1, SchoolSection.XX.getId()), - GRADE2("一年级下", 1, 2, SchoolSection.XX.getId()), - GRADE3("二年级上", 2, 1, SchoolSection.XX.getId()), - GRADE4("二年级下", 2, 2, SchoolSection.XX.getId()), - GRADE5("三年级上", 3, 1, SchoolSection.XX.getId()), - GRADE6("三年级下", 3, 2, SchoolSection.XX.getId()), - GRADE7("四年级上", 4, 1, SchoolSection.XX.getId()), - GRADE8("四年级下", 4, 2, SchoolSection.XX.getId()), - GRADE9("五年级上", 5, 1, SchoolSection.XX.getId()), - GRADE10("五年级下", 5, 2, SchoolSection.XX.getId()), - GRADE11("六年级上", 6, 1, SchoolSection.XX.getId()), - GRADE12("六年级下", 6, 2, SchoolSection.XX.getId()), - GRADE13("七年级上", 7, 1, SchoolSection.CZ.getId()), - GRADE14("七年级下", 7, 2, SchoolSection.CZ.getId()), - GRADE15("八年级上", 8, 1, SchoolSection.CZ.getId()), - GRADE16("八年级下", 8, 2, SchoolSection.CZ.getId()), - GRADE17("九年级上", 9, 1, SchoolSection.CZ.getId()), - GRADE18("九年级下", 9, 2, SchoolSection.CZ.getId()), - GRADE19("高一年级上", 10, 1, SchoolSection.GZ.getId()), - GRADE20("高一年级下", 10, 2, SchoolSection.GZ.getId()), - GRADE21("高二年级上", 11, 1, SchoolSection.GZ.getId()), - GRADE22("高二年级下", 11, 2, SchoolSection.GZ.getId()), - GRADE23("高三年级上", 12, 1, SchoolSection.GZ.getId()), - GRADE24("高三年级下", 12, 2, SchoolSection.GZ.getId()), - ; - - private String name; - private Integer system_garde; - private Integer term; - private Integer sectionId; - - GradeEnum(String name, Integer system_garde, Integer term, Integer sectionId) { - this.name = name; - this.system_garde = system_garde; - this.term = term; - this.sectionId = sectionId; - } - - private static List list; - - public static List list() { - if (list != null) - return list; - - list = new ArrayList<>(); - - EnumSet statusSet = EnumSet.allOf(GradeEnum.class); - for (GradeEnum status : statusSet) - list.add(status); - - return list; - } - - public static String getName(Integer id) { - - if (list == null) { - list = list(); - } - for (GradeEnum status : list) { - if (status.getSystem_garde().equals(id)) - return status.getName(); - } - return ""; - } - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getSystem_garde() { - return system_garde; - } - - public Integer getTerm() { - return term; - } - - public void setTerm(Integer term) { - this.term = term; - } - - public Integer getSectionId() { - return sectionId; - } - - public void setSectionId(Integer sectionId) { - this.sectionId = sectionId; - } - - public void setSystem_garde(Integer system_garde) { - this.system_garde = system_garde; - } - - /** - * 根据systemGrade获取学段 - */ - public static Optional getSectionIdBySystemGrade(Integer systemGrade) { - for (GradeEnum gradeEnum : GradeEnum.values()) { - if (gradeEnum.getSystem_garde().equals(systemGrade)) { - return Optional.of(gradeEnum.getSectionId()); - } - } - return Optional.empty(); - } - -} - - diff --git a/src/main/java/com/bestsch/classicalchinese/enums/OcrDataCache.java b/src/main/java/com/bestsch/classicalchinese/enums/OcrDataCache.java deleted file mode 100644 index ed7bc6d..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/OcrDataCache.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -/** - * 调用OCR接口,识别到的数据,缓存在这 - * 在现有逻辑下,会对同一个url的图片多次调用ocr接口,因此将这个url图片识别到的数据存储起来 - */ -@AllArgsConstructor -@NoArgsConstructor -@Data -@Entity -@Table(name = "ocr_data_cache", uniqueConstraints = { - @UniqueConstraint(name = "unique_img_url", columnNames = {"img_url"}) -}) -public class OcrDataCache { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; - - @Column(name = "img_url") - private String imgUrl; - - private String data; -} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/enums/QuestionDifficultyEnum.java b/src/main/java/com/bestsch/classicalchinese/enums/QuestionDifficultyEnum.java deleted file mode 100644 index a9964c8..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/QuestionDifficultyEnum.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -@AllArgsConstructor -public enum QuestionDifficultyEnum -{ - //容易 - Easily (1,"容易"), - //中等 - Medium (2,"中等"), - //困难 - Difficulty (3,"困难"), - //随机 - Random (4,"随机"); - - private Integer key; - private String value; -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java b/src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java deleted file mode 100644 index d686f63..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -//oneSelect单选题,manySelect多选题,judge判断题,answer解答题,fillBlanks填空题 - -@Getter -@NoArgsConstructor -@AllArgsConstructor -public enum QuestionTypeEnum -{ - oneSelect (1,"单选题"), - manySelect (2,"多选题"), - judge (3,"判断题"), - answer (4,"解答题"), - fillBlanks (5,"填空题"); - - private Integer key; - private String value; -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/ReviewStatus.java b/src/main/java/com/bestsch/classicalchinese/enums/ReviewStatus.java deleted file mode 100644 index deae235..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/ReviewStatus.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -public enum ReviewStatus { - - UNREVIEW(0,"未批"), - REVIEW(1,"已批"), - DINGZHENG(2,"订正"); - - - private int id; - private String name; - - ReviewStatus(int id, String name) { - this.id = id; - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection.java b/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection.java deleted file mode 100644 index 8202816..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.Data; - -import java.util.*; -import java.util.stream.Collectors; - -//学段,要跟班级管理一致 -public enum SchoolSection -{ - XX(2, "小学", "XX", Arrays.asList(Subject.YW, Subject.SX, Subject.YY, Subject.PD, Subject.KX)), -/* CZ(3, "初中", "CZ", - Arrays.asList(Subject.YW, Subject.SX, Subject.YY, Subject.WL, Subject.HX, Subject.SW, Subject.LS, Subject.DL, Subject.KX, Subject.XX, Subject.PD)),*/ - CZ(3, "初中", "CZ", - Arrays.asList(Subject.YW, Subject.SX, Subject.YY)), - GZ(4, "高中", "GZ", - Arrays.asList(Subject.YW, Subject.SX, Subject.YY, Subject.WL, Subject.HX, Subject.SW, Subject.ZZ, Subject.LS, Subject.DL, Subject.XX)); - - private int id; - private String name; - private String code; - - private List subjects = new ArrayList<>(); - - SchoolSection(int id, String name, String code, List subjects) - { - this.id = id; - this.name = name; - this.code = code; - this.subjects.addAll(subjects); - } - - public int getId() - { - return id; - } - - public String getName() - { - return name; - } - - public String getCode() - { - return code; - } - - public static SchoolSection getById(int id) - { - return map.get(id); - } - - private static List list; - private static Map map; - public static List list() - { - if (list != null) return list; - EnumSet statusSet = EnumSet.allOf(SchoolSection.class); - list = new ArrayList<>(statusSet); - map = list.stream().collect(Collectors.toMap(SchoolSection::getId, SchoolSection -> SchoolSection)); - return list; - } - - static - { - list(); - } - - @Data - public static class Dto - { - private int id; - private String name; - private String code; - private List subjects = new ArrayList<>(); - } - - public Dto toDto() - { - Dto dto = new Dto(); - dto.setId(id); - dto.setName(name); - dto.setCode(code); - - for (Subject subject: subjects) - dto.getSubjects().add(subject.toDto()); - - return dto; - } - - private static List dtoList; - public static List dtoList() - { - if (dtoList != null) return dtoList; - List dtoList = new ArrayList<>(); - - for (SchoolSection section: list()) - dtoList.add(section.toDto()); - - return dtoList; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection_.java b/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection_.java deleted file mode 100644 index 4d8ab2a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection_.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.Data; - -import java.util.*; -import java.util.stream.Collectors; - -//学段,要跟班级管理一致 -public enum SchoolSection_ -{ - XX(2, "小学", "XX", Arrays.asList(Subject.YW, Subject.SX, Subject.YY, Subject.PD, Subject.KX)), - CZ(3, "初中", "CZ", - Arrays.asList(Subject.YW, Subject.SX, Subject.YY, Subject.WL, Subject.HX, Subject.SW, Subject.LS, Subject.DL, Subject.KX, Subject.XX, Subject.PD, Subject.LJ)), - GZ(4, "高中", "GZ", - Arrays.asList(Subject.YW, Subject.SX, Subject.YY, Subject.WL, Subject.HX, Subject.SW, Subject.ZZ, Subject.LS, Subject.DL, Subject.XX)); - - private int id; - private String name; - private String code; - - private List subjects = new ArrayList<>(); - - SchoolSection_(int id, String name, String code, List subjects) - { - this.id = id; - this.name = name; - this.code = code; - this.subjects.addAll(subjects); - } - - public int getId() - { - return id; - } - - public String getName() - { - return name; - } - - public String getCode() - { - return code; - } - - public static SchoolSection_ getById(int id) - { - return map.get(id); - } - - private static List list; - private static Map map; - public static List list() - { - if (list != null) return list; - EnumSet statusSet = EnumSet.allOf(SchoolSection_.class); - list = new ArrayList<>(statusSet); - map = list.stream().collect(Collectors.toMap(SchoolSection_::getId, SchoolSection -> SchoolSection)); - return list; - } - - static - { - list(); - } - - @Data - public static class Dto - { - private int id; - private String name; - private String code; - private List subjects = new ArrayList<>(); - } - - public Dto toDto() - { - Dto dto = new Dto(); - dto.setId(id); - dto.setName(name); - dto.setCode(code); - - for (Subject subject: subjects) - dto.getSubjects().add(subject.toDto()); - - return dto; - } - - private static List dtoList; - public static List dtoList() - { - if (dtoList != null) return dtoList; - List dtoList = new ArrayList<>(); - - for (SchoolSection_ section: list()) - dtoList.add(section.toDto()); - - return dtoList; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/SourceEnum.java b/src/main/java/com/bestsch/classicalchinese/enums/SourceEnum.java deleted file mode 100644 index 707311d..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/SourceEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.Arrays; -import java.util.Optional; - -/** - * @Description 教材来源 - * @Author cls - * @Date 2021/3/17 14:59 - * @Version V1.0 - **/ -@AllArgsConstructor -@NoArgsConstructor -@Getter -public enum SourceEnum { - - UNKNOWN("UNKNOWN","未知"), - SYSTEM("SYSTEM","系统级"),SCHOOL("SCHOOL","校级") - ; - - private String enKey; - private String cnKey; - - public static SourceEnum getByEnKey(String enKey) { - String enKey0 = enKey.toUpperCase(); - SourceEnum[] enums = SourceEnum.values(); - Optional opt = Arrays.stream(enums).filter(item -> item.getEnKey().equals(enKey0.toUpperCase())).findAny(); - if(opt.isPresent()){ - return opt.get(); - } - return UNKNOWN; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/Subject.java b/src/main/java/com/bestsch/classicalchinese/enums/Subject.java deleted file mode 100644 index 4a25586..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/Subject.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public enum Subject -{ - YW(40,"语文","SUB01"), - SX(41,"数学","SUB02"), - YY(42,"英语","SUB03"), - WL(74,"物理","SUB04"), - HX(75,"化学","SUB05"), - SW(76,"生物","SUB06"), - XX(111,"信息","SUB7"), - PD(112,"道法","SUB8"), - TY(113,"体育","SUB9"), - MS(114,"美术","SUB10"), - KX(115,"科学","SUB11"), - LJ(116,"劳技","SUB12"), - LS(117,"历史","SUB13"), - DL(118,"地理","SUB14"), - ZZ(119,"政治","SUB15"); - - private int id; - private String name; - private String code; - - Subject(int id, String name, String code) - { - this.id = id; - this.name = name; - this.code = code; - } - - public int getId() - { - return id; - } - - public String getName() - { - return name; - } - - public String getCode() - { - return code; - } - - public static Subject getByCode(String code) - { - return codeMap.get(code); - } - - private static List list; - private static Map codeMap; - public static List list() - { - if (list != null) return list; - EnumSet statusSet = EnumSet.allOf(Subject.class); - list = new ArrayList<>(statusSet); - codeMap = list.stream().collect(Collectors.toMap(Subject::getCode, Subject -> Subject)); - return list; - } - - static - { - list(); - } - - @Data - public static class Dto - { - private int id; - private String name; - private String code; - } - - public Dto toDto() - { - Dto dto = new Dto(); - dto.setId(id); - dto.setName(name); - dto.setCode(code); - return dto; - } - - private static List dtoList; - public static List dtoList() - { - if (dtoList != null) return dtoList; - List dtoList = new ArrayList<>(); - - for (Subject subject: list()) - dtoList.add(subject.toDto()); - - return dtoList; - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/TimeTypeEnum.java b/src/main/java/com/bestsch/classicalchinese/enums/TimeTypeEnum.java deleted file mode 100644 index db7710b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/enums/TimeTypeEnum.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.bestsch.classicalchinese.enums; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; - -public enum TimeTypeEnum -{ - CURRENT_TERM(1, "本学期"), CURRENT_MONTH(2, "本月"), CURRENT_WEEK(3, "本周"), - TODAY(4, "今日"),TOTAL(5,"累计"),CUSTOM(6,"自定义"); - - private int id; - private String name; - - private TimeTypeEnum(int id, String name) - { - setId(id); - setName(name); - } - - public int getId() - { - return id; - } - - public void setId(int id) - { - this.id = id; - } - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public static String nameById(int id) - { - for(TimeTypeEnum type : list()) - { - if(type.getId()==id) return type.getName(); - } - return null; - - } - - public static Integer IdByName(String name) - { - for(TimeTypeEnum type : list()) - { - if(type.getName().equals(name)) return type.getId(); - } - return null; - - } - - private static List list; - public static List list() - { - if (list != null) return list; - list = new ArrayList<>(); - EnumSet typeSet = EnumSet.allOf(TimeTypeEnum.class); - for (TimeTypeEnum type : typeSet) - list.add(type); - - return list; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java b/src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java deleted file mode 100644 index 7aacd1f..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.bestsch.classicalchinese.model; - - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Date; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class AcademicYear { - private Integer id; - private String name; - private Date startDate; - private Date endDate; - private Date progressionDate; - private Integer year; - private Date firstSemesterStartDate; - private Date firstSemesterEndDate; - private Date secondSemesterStartDate; - private Date secondSemesterEndDate; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/AiAsk.java b/src/main/java/com/bestsch/classicalchinese/model/AiAsk.java deleted file mode 100644 index 6150b40..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/AiAsk.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.bestsch.classicalchinese.model; - - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class AiAsk { - @NotNull(message="请选择模型!") - @Size(max = 20, message = "模型错误!") - private String model; - @NotNull(message="请输入问题内容!") - @Size(max = 8000, message = "问题长度超出限制(8000字符)!") - private String prompt; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/BaseTree.java b/src/main/java/com/bestsch/classicalchinese/model/BaseTree.java deleted file mode 100644 index dd56bfa..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/BaseTree.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class BaseTree { - public Integer id; - public String name; - public Integer pid ; - public List children; -} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/model/ClassInfo.java b/src/main/java/com/bestsch/classicalchinese/model/ClassInfo.java deleted file mode 100644 index a936886..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/ClassInfo.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -import java.util.List; - -@Data -public class ClassInfo -{ - private Integer classId; - private Integer gradeId; - private String className; - private String gradeName; - private Integer teacherId; - private Integer schoolId; - - @Data - public static class ClassInfoWithStu - { - private Integer classId; - private Integer gradeId; - private String className; - private String gradeName; - private List children; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/ClassModel.java b/src/main/java/com/bestsch/classicalchinese/model/ClassModel.java deleted file mode 100644 index 4808cff..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/ClassModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -@Data -public class ClassModel { - private Integer classId; - private String className; - private String gradeName; - private String name; - private Integer gradeId; - private String classIds; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/DateModel.java b/src/main/java/com/bestsch/classicalchinese/model/DateModel.java deleted file mode 100644 index bcf64b4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/DateModel.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -import java.util.Date; - -@Data -public class DateModel { - private int year; - private int semester; - private Date startDate; - private Date endDate; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/DateTimeModel.java b/src/main/java/com/bestsch/classicalchinese/model/DateTimeModel.java deleted file mode 100644 index 4ee4294..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/DateTimeModel.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -import java.util.Date; - -@Data -public class DateTimeModel { - private int timeIndex; - private Date startDate; - private Date endDate; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/Example.java b/src/main/java/com/bestsch/classicalchinese/model/Example.java deleted file mode 100644 index 3b71326..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/Example.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class Example { - private String name; - private String config; - private String answer; - private String solve; - private Integer difficultLevelId; -// private String difficultLevelName; -// private String questionTypeName; - private Integer questionTypeId; - private DifficultLevel difficultLevel; - private QuestionType questionType; - private List solveQuestionFiles; - - @Data - static public class DifficultLevel{ - private Integer id; - private String name; - } - - @Data - static public class QuestionType{ - private Integer id; - private String name; - private Date cdate; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/ExcelBschLeadlearning.java b/src/main/java/com/bestsch/classicalchinese/model/ExcelBschLeadlearning.java deleted file mode 100644 index 63c1377..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/ExcelBschLeadlearning.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import cn.afterturn.easypoi.excel.annotation.Excel; -import lombok.Data; - -/** - * @Author wanghu - * @Date 2025-11-7 13:26 (可以根据需要修改) - * @Description: - */ - -@Data -public class ExcelBschLeadlearning { - @Excel(name = "章节名称") - private String cname; - - @Excel(name = "导学内容") - private String bschLeadlearning; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/ExcelPunitTreeTea.java b/src/main/java/com/bestsch/classicalchinese/model/ExcelPunitTreeTea.java deleted file mode 100644 index 03caa11..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/ExcelPunitTreeTea.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import cn.afterturn.easypoi.excel.annotation.Excel; -import lombok.Data; - -/** - * @Author wanghu - * @Date 2025-11-7 13:26 (可以根据需要修改) - * @Description: - */ - -@Data -public class ExcelPunitTreeTea { - @Excel(name = "章节名称") - private String cname; - - @Excel(name = "教师(“,”英文逗号隔开)") - private String teaNames; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/FileMessage.java b/src/main/java/com/bestsch/classicalchinese/model/FileMessage.java deleted file mode 100644 index 2fae6c4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/FileMessage.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.bestsch.classicalchinese.model; - - -import lombok.Data; - -@Data -public class FileMessage { - - private String fileName; - private String pictureName; - private Long videoSize; - private Integer imgWidth; - private Integer imgHeight; - private String size; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/Grade.java b/src/main/java/com/bestsch/classicalchinese/model/Grade.java deleted file mode 100644 index a174de2..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/Grade.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.bestsch.classicalchinese.model; - - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class Grade { - private Integer gradeId;//1-12年级 - - private String name; - private Integer term;//学期 - private Integer id;//年级ID 唯一 - - - public Grade(Integer id, String name) { - this.gradeId = id; - this.name = name; - } - -} - - diff --git a/src/main/java/com/bestsch/classicalchinese/model/Page.java b/src/main/java/com/bestsch/classicalchinese/model/Page.java deleted file mode 100644 index f305fc2..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/Page.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import org.apache.commons.lang.StringUtils; - -public class Page { - private int current; - private int pageSize; - private long count; - - public Page() { - } - - public int getCurrent() { - return this.current; - } - - public void setCurrent(int current) { - this.current = current; - } - - public int getPageSize() { - return this.pageSize == 0 ? 10 : this.pageSize; - } - - public void setPageSize(int pageSize) { - this.pageSize = pageSize; - } - - public void setPageSize(String pageSize) { - if (!StringUtils.isEmpty(pageSize) && StringUtils.isNumeric(pageSize)) { - this.pageSize = Integer.valueOf(pageSize); - } - - } - - public long getCount() { - return this.count; - } - - public void setCount(long count) { - this.count = count; - } - - - - public int getPageCount() { - return this.getPageSize() != 0 ? (int)Math.ceil((double)this.count / (double)this.getPageSize()) : 0; - } - - public int getStartIndex() { - return (this.getCurrent() - 1) * this.getPageSize(); - } - - public void setCurrent(String current) { - if (!StringUtils.isEmpty(current) && StringUtils.isNumeric(current)) { - this.current = Integer.valueOf(current); - } - - } - - public void setCount(String count) { - if (!StringUtils.isEmpty(count) && StringUtils.isNumeric(count)) { - this.count = Long.valueOf(count); - } - - } - - public int getEndIndex() { - return this.getStartIndex() + this.getPageSize(); - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java b/src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java deleted file mode 100644 index a4f7ba8..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -@Data -public class SchClassModel { - public Integer classID; - public Integer gradeID; - public String gradeName; - public String className; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/SchSub.java b/src/main/java/com/bestsch/classicalchinese/model/SchSub.java deleted file mode 100644 index 95c8545..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/SchSub.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -@Data -public class SchSub { - private String subId; - private String subName; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/SchTeaSubGrade.java b/src/main/java/com/bestsch/classicalchinese/model/SchTeaSubGrade.java deleted file mode 100644 index c6868fc..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/SchTeaSubGrade.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -@Data -public class SchTeaSubGrade { - public Integer gradeID; - public String subID; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/StartEndDate.java b/src/main/java/com/bestsch/classicalchinese/model/StartEndDate.java deleted file mode 100644 index d0cecb9..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/StartEndDate.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import java.util.Date; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class StartEndDate { - private Date startDate; - private Date endDate; -} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/model/StudentInfo.java b/src/main/java/com/bestsch/classicalchinese/model/StudentInfo.java deleted file mode 100644 index a80396a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/StudentInfo.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -@Data -public class StudentInfo -{ - private Integer id; - private String name; - private Integer claId; - private String claName; - private Integer gradeId; - private String profilePicture; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/SubGroupTeaIds.java b/src/main/java/com/bestsch/classicalchinese/model/SubGroupTeaIds.java deleted file mode 100644 index 595fb24..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/SubGroupTeaIds.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -import java.util.List; - -/** - * @Author wanghu - * @Date 2025-11-18 16:18 (可以根据需要修改) - * @Description: - */ -@Data -public class SubGroupTeaIds { - public List gradeIds; - public List subIds; - public List teaIds; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/SystemGrade.java b/src/main/java/com/bestsch/classicalchinese/model/SystemGrade.java deleted file mode 100644 index b6c010d..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/SystemGrade.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@NoArgsConstructor -@Getter -public enum SystemGrade { - - one(1,"一年级"),two(2,"二年级"), - three(3,"三年级"),four(4,"四年级"), - five(5,"五年级"),six(6,"六年级"), - seven(7,"七年级"),eight(8,"八年级"), - nine(9,"九年级"),ten(10,"高一年级"), - eleven(11,"高二年级"),twelve(12,"高三年级"); - - private Integer gradeId; - private String gradeName; - - public static String getName(Integer gradeId) { - for (SystemGrade grade : SystemGrade.values()) { - if (grade.getGradeId().equals(gradeId)) { - return grade.gradeName; - } - } - return null; - } - -} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/model/TeaFirstClass.java b/src/main/java/com/bestsch/classicalchinese/model/TeaFirstClass.java deleted file mode 100644 index e80106a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/TeaFirstClass.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -@Data -public class TeaFirstClass { - public String gradeName; - public int gradeId ; - public String alias; - public String className ; - public String subName ; - public String subId ; - public String name ; - public int id ; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/TreeDept.java b/src/main/java/com/bestsch/classicalchinese/model/TreeDept.java deleted file mode 100644 index 6086534..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/TreeDept.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class TreeDept { - private int schoolId; - private String name; - private int pId; - private int id; - private Integer type; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/TreeUser.java b/src/main/java/com/bestsch/classicalchinese/model/TreeUser.java deleted file mode 100644 index 1bec5f3..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/TreeUser.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class TreeUser { - private int UserID; - private String Name; - private String Photo; - private Integer type; - private int id; - private int GroupID; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/UserGradeClassSub.java b/src/main/java/com/bestsch/classicalchinese/model/UserGradeClassSub.java deleted file mode 100644 index e83736e..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/UserGradeClassSub.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -/** - * @Author wanghu - * @Date 2025-11-18 16:18 (可以根据需要修改) - * @Description: - */ -@Data -public class UserGradeClassSub { - public Integer gradeId; - public Integer classId; - public String subId; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/YearSemester.java b/src/main/java/com/bestsch/classicalchinese/model/YearSemester.java deleted file mode 100644 index 81010a9..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/YearSemester.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.bestsch.classicalchinese.model; - -import lombok.Data; - -import java.util.Date; - -@Data -public class YearSemester { - private Integer year; - private Integer semester; - private String name; - private Date startDate; - private Date endDate; - - @Data - static public class AcademicYear { - private Integer id; - private String name; - private Date startDate; - private Date endDate; - private Date progressionDate; - private Integer year; - private Date firstSemesterStartDate; - private Date firstSemesterEndDate; - private Date secondSemesterStartDate; - private Date secondSemesterEndDate; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/dto/PunitDto.java b/src/main/java/com/bestsch/classicalchinese/model/dto/PunitDto.java deleted file mode 100644 index 9f6ddab..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/dto/PunitDto.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.bestsch.classicalchinese.model.dto; - -import com.bestsch.classicalchinese.entity.PunitQuestion; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.util.List; - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class PunitDto { - - public Integer nodeId; - - @NotNull(message="导学内容不允许为空!") - @Size(max = 8000, message = "导学内容超出长度限制(8000字符)!") - public String connect; - - public List questions; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/vo/AiQuestionsVo.java b/src/main/java/com/bestsch/classicalchinese/model/vo/AiQuestionsVo.java deleted file mode 100644 index fcf0dd3..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/vo/AiQuestionsVo.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.bestsch.classicalchinese.model.vo; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - - -@AllArgsConstructor -@NoArgsConstructor -@Data -public class AiQuestionsVo { - - private String type; - - private String difficulty; - - private String question; - - private String[] options; - - // ["",""],[""] 一级表示答案有多种解析方式 或者关系, 二级表示答案属于并且关系答案同时存在 - private String answer; - - private String analysis; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/vo/BschFormQuestionVo.java b/src/main/java/com/bestsch/classicalchinese/model/vo/BschFormQuestionVo.java deleted file mode 100644 index 3f67761..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/vo/BschFormQuestionVo.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.bestsch.classicalchinese.model.vo; - -import com.bestsch.classicalchinese.entity.BschQuestion; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; -import java.util.List; - - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class BschFormQuestionVo implements Serializable { - - public Integer nodeId; - - public String content; - //小题 - public List questionList; - - public String path; - - public Integer textbookId; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFilesVo.java b/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFilesVo.java deleted file mode 100644 index baf0946..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFilesVo.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.bestsch.classicalchinese.model.vo; - -import lombok.Data; - -@Data -public class PunitFilesVo { - public Integer id; - - public Integer nodeId; - - public String fileName; - - public String fileCode; - - public String filePath; - - public Integer fileSize; - - public String fileType; - - public Integer sort; - - public boolean displayDel; - - public boolean show; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFormVo.java b/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFormVo.java deleted file mode 100644 index f2f2514..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFormVo.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.bestsch.classicalchinese.model.vo; - -import com.bestsch.classicalchinese.entity.PunitQuestion; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; -import java.util.List; - - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class PunitFormVo implements Serializable { - - public Integer id; - - public String name; - - public Integer nodeId; - - public String content; - //小题 - public List questionList; - - private Integer textBookId; - - - public String path; - - public PunitFormVo(Integer id,String content,List questionList) - { - this.id=id; - this.content=content; - this.questionList=questionList; - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/vo/PunitNodeStuQuestion.java b/src/main/java/com/bestsch/classicalchinese/model/vo/PunitNodeStuQuestion.java deleted file mode 100644 index 2645919..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/vo/PunitNodeStuQuestion.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.bestsch.classicalchinese.model.vo; - -import com.fasterxml.jackson.annotation.JsonAlias; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; - - -@Data -@NoArgsConstructor -@AllArgsConstructor -@JsonIgnoreProperties(ignoreUnknown = true) -public class PunitNodeStuQuestion implements Serializable { - - public Integer id; - - public String name; - - @JsonAlias("node_id") - public Integer nodeId; - - public String content; - - @JsonAlias("subject_id") - public String subjectId; - - @JsonAlias("grade_id") - public Integer gradeId ; - - @JsonAlias("is_review") - public Integer isReview; - - @JsonAlias("qcount") - public String qCount; - - @JsonAlias("stucount") - public String stuCount; - - @JsonAlias("duicount") - public String duiCount; - - @JsonAlias("cuocount") - public String cuoCount; - - @JsonAlias("elecount") - public String eleCount; -} diff --git a/src/main/java/com/bestsch/classicalchinese/model/vo/SubmitStuQuestionVo.java b/src/main/java/com/bestsch/classicalchinese/model/vo/SubmitStuQuestionVo.java deleted file mode 100644 index 959d253..0000000 --- a/src/main/java/com/bestsch/classicalchinese/model/vo/SubmitStuQuestionVo.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.bestsch.classicalchinese.model.vo; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.io.Serializable; - - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class SubmitStuQuestionVo implements Serializable { - - public Integer qId; - - public Integer textbookId; - - public Integer nodeId; - - public String answer; - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IBschExplanationService.java b/src/main/java/com/bestsch/classicalchinese/service/IBschExplanationService.java deleted file mode 100644 index e4775b4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IBschExplanationService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.BschVideoExplanation; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.Map; - -public interface IBschExplanationService { - - List findTextBookAll(Integer textbookId); - - Object getExplanationList(int textbookId, int userId, Integer nodeId, Pageable pageable); - - void saveExplanation(int userId, List list); - - void saveExplanation1(int userId, Map map); - - void deleteExplanation(int userId, Integer id); - - Object pdfPreview(Integer id); - - // Object getZYKVideoList(int schId, int userId, int roleId, Integer nodeId, Integer page, Integer count); - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IBschKnowledgeService.java b/src/main/java/com/bestsch/classicalchinese/service/IBschKnowledgeService.java deleted file mode 100644 index 3682be4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IBschKnowledgeService.java +++ /dev/null @@ -1,237 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.BschKnowledge; - -import javax.servlet.http.HttpServletResponse; -import java.util.List; -import java.util.Map; - -/** - * @ Description : 知识节点表service层 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:41 - * @ Company : bestsch - */ -public interface IBschKnowledgeService { - - /** 功能描述: 添加 - * @param knowledge - * @return: - * @Author: cls - * @Date: 2021/3/20 14:15 - */ - BschKnowledge add(BschKnowledge knowledge); - -// /** 功能描述: 获取知识树结构 -// * 用户 api/GetTree接口 -// * @param textbookId -// * @param source -// * @return: -// * @Author: cls -// * @Date: 2021/4/12 15:07 -// */ -// Map getOrCreateTreeForApi(int textbookId, String source); -// - /** 功能描述: 获取知识节点所在知识树的结构 - * @param knowledgeId - * @return: - * @Author: cls - * @Date: 2021/4/12 14:50 - */ - Map getTreeForApi(int knowledgeId); -// -// /** 功能描述: 获取教材知识树根节点,没有则创建一个 -// * @return: -// * @Author: cls -// * @Date: 2020/5/20 9:08 -// */ -// BschKnowledge getOrCreateRootOfSystem(int bookId); - - /** 功能描述: 获取知识树结构 没有则创建 - * @param textbookId - * @return: - * @Author: cls - * @Date: 2021/3/17 17:07 - */ - Map getTreeOfSystem(int textbookId); - - Map getTreeOfSystemForApi(int bookId); - - /** 功能描述: 获取知识树结构,没有则创建 - * 与getOrCreateRootTree的区别在于针对的前端组件不同,返回参数名称不同 - * @param textbookId - * @param source - * @return: - * @Author: cls - * @Date: 2021/4/12 14:36 - */ - //Map getOrCreateTree2(int schoolSid, int textbookId, String source); - - /** 功能描述: 获取节点路径 - * @param knowledgeId - * @param separator 分割符 - * @return: - * @Author: cls - * @Date: 2020/11/24 11:22 - */ - String getNamePath(int knowledgeId, String separator); - - /** - * 获取节点路径20240116 - * @param knowledgeId - * @param separator - * @param knowledgeList - * @return - */ - String getNamePath(int knowledgeId, String separator, List knowledgeList); - - List getByIds(List ids); - - - /** - * 获取知识节点路径 - * @param knowledgeId - * @param separator - * @return - */ - String getIdPath(int knowledgeId, String separator); - - /** - * 添加知识节点 - * @param parentId - * @param name - * @return - */ - BschKnowledge addKnowledge(int parentId, String name); - - /** - * 删除知识节点 - * @param id - */ - void delKnowledge(int id); - - /** - * 修改知识节点 - * @param id - * @param knowledge - * @return - */ - BschKnowledge setKnowledge(int id, BschKnowledge knowledge); - - /** - * 获取任意节点所处的根节点 - * @param id - * @return - */ - BschKnowledge getRoot(int id); - - /** - * 获取包括不同层级的所有子知识节点,并且包括本身 - * @param id - * @return - */ - List getAllChildWithSelf(int id); - - /** - * 把资源分享到学校某知识章节下 - * @param schoolSid - * @param userId - * @param resourceId - * @param knowledgeId - * @param schoolBookId 教材定义id - */ - // void shareToSchool(int schoolSid, int userId, int resourceId, int knowledgeId, int schoolBookId); - - /** 功能描述: 来自其他系统的资源的分享 - * @param schoolSid - * @param userId - * @param resourceId - * @param grade - * @param semester - * @param subject - * @param knowledgeId - * @param schoolBookId - * @return: - * @Author: cls - * @Date: 2020/11/9 10:20 - */ -// void shareToSchoolForOtherSystem(int schoolSid, int userId, int resourceId, int grade, -// int semester, String subject, int knowledgeId, int schoolBookId); - - /** 功能描述: 批量分享 - * @param schoolSid - * @param userId - * @param resourceIds - * @param grade - * @param semester - * @param subject - * @param knowledgeId - * @param schoolBookId - * @return: - * @Author: cls - * @Date: 2020/12/1 15:29 - */ -// void shareAllToSchoolForOtherSystem(int schoolSid, int userId, String resourceIds, int grade, -// int semester, String subject, int knowledgeId, int schoolBookId); - - /** - * 修改排序 - * @param id 移动的知识节点id - * @param replaceId 位置被替换的知识节点id - */ - void setOrder(int id, int replaceId); - - /** - * 获取同层级排序码区间内的知识节点 - * @param parentId - * @param begin 起始值 - * @param flag1 是否包括 0不包括 1包括 - * @param end 终止值 - * @param flag2 是否包括 0不包括,1包括 - * @return - */ - List selectKnowledgeInOrderSection(int parentId, int begin, int flag1, int end, int flag2); - - /** 功能描述: 创建根节点 - * @param name - * @return: - * @Author: cls - * @Date: 2021/4/19 18:35 - */ - BschKnowledge createRoot(String name); - - /** 功能描述: 获取节点信息 - * @param id - * @return: - * @Author: cls - * @Date: 2021/5/7 15:10 - */ - BschKnowledge get(int id); - - /** 功能描述: 导出指定教材的知识树结构 - * @param textbookId - * @param source - * @param response - * @return: - * @Author: cls - * @Date: 2021/7/2 15:21 - */ - // void exportTree(Integer textbookId, String source, HttpServletResponse response); - - /** 功能描述: 获取知识树结构 Node节点数据(转换实体格式) - * @param textbookId - * @param source - * @return: - * @Author: cls - * @Date: 2021/3/17 17:07 - */ - // List getNodeTree(int textbookId, String source); - - List> getSubdirectoryList(int bookId); - - /** 功能描述: 获取章节点末尾课文名称*/ - List getEndNodeList(int textbookId); - - /** 功能描述: 获取章节点列表 扁平化*/ - List getTreeOfSystemToList(int textbookId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IBschLeadlearningService.java b/src/main/java/com/bestsch/classicalchinese/service/IBschLeadlearningService.java deleted file mode 100644 index 21ccf5c..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IBschLeadlearningService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.BschLeadlearning; -import com.bestsch.classicalchinese.entity.PunitLeadlearning; -import com.bestsch.classicalchinese.model.ExcelBschLeadlearning; - -import java.util.List; -import java.util.Optional; - -public interface IBschLeadlearningService { - void save(BschLeadlearning entity); - - void saveAll(List entitys); - - Optional findOne(Integer textbookId,Integer nodeId); - - List findTextbookAll(Integer textbookId); - - //List getExcelBschLeadlearning(Integer textbookId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IBschQuestionService.java b/src/main/java/com/bestsch/classicalchinese/service/IBschQuestionService.java deleted file mode 100644 index 4aed9a3..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IBschQuestionService.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.BschQuestion; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public interface IBschQuestionService { - - void save(BschQuestion entity); - - void saveAll(List entitys); - - Optional findOne(Integer id, Integer textbookId); - - List findNoteAll(Integer nodeId,Integer textbookId); - - - List findGradeMapAll(Integer nodeId, Integer textbookId); - - //List findTextbookIdAll(Integer textbookId); - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IBschTextbookService.java b/src/main/java/com/bestsch/classicalchinese/service/IBschTextbookService.java deleted file mode 100644 index 6318fd1..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IBschTextbookService.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.BschTextbook; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletResponse; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -/** - * @ Description : java类作用描述 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:48 - * @ Company : bestsch - */ -public interface IBschTextbookService { - - /** - * 获取教材 - * @param id - * @return - */ - BschTextbook getOne(int id); - - Optional findOne(int id); - - /** - * 获取教材 - * @param ids - * @return - */ - List getList(List ids); - - List getAllList(); - - /** 功能描述: 以map的形式返回教材信息,有一些额外参数 - * @param id - * @return: - * @Author: cls - * @Date: 2021/4/13 10:26 - */ - //Map getOneMap(int id); - - /** - * 保存/修改教材信息 - * @param book - * @return - */ - BschTextbook saveAndFlush(BschTextbook book); - - /** - * 添加教材 - * @param textbook - * @return - */ - BschTextbook addTextbook(BschTextbook textbook); - - /** 功能描述: 添加教材并且创建根节点 - * @param textbook - * @return: - * @Author: cls - * @Date: 2021/4/19 18:35 - */ - BschTextbook addAndCreateKnowledge(BschTextbook textbook); - - /** - * 删除教材 - * @param id - */ - void delTextbook(Integer id); - - /** - * 修改教材信息 - * @param id - * @param textbook - * @return - */ - BschTextbook setTextbook(Integer id, BschTextbook textbook); - - /** - * 查询教材 - * @param grade - * @param subjectName - * @param semester - * @param press - * @param outTime - * @param keyword - * @param orderKey - * @param order - * @param pageIndex - * @param pageSize - * @return - */ - Map selectTextbook(Integer grade, String subjectName, Integer semester, String press, String outTime, - String keyword, String orderKey, Integer order, Integer pageIndex, Integer pageSize); - - - - /** 功能描述: 获取教材对应的学科 - * @param treeId - * @return: - * @Author: cls - * @Date: 2021/7/5 9:38 - */ - String getSubjectByTree(int treeId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/ICommonService.java b/src/main/java/com/bestsch/classicalchinese/service/ICommonService.java deleted file mode 100644 index 2a8cff0..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/ICommonService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import java.util.List; -import java.util.Map; - -public interface ICommonService { - // Object getSubjectGradeTerm(int schId, int roleId, int userId, Integer gradeId); - - // Object getChapterWrongQuestNumTree(int schId, Integer year, Integer term, String checkedIds); - - //Object getChapterWrongQuestNumTree(int schId, int userId, String subjectId,String checkedIds); - //Map getTeaSubGradeTrem(int roleId,int schId,int userId); - - //List getTeachSubGrade(int schId, int userId); - - //Object getGradeTerm(int schId, int userId, Integer gradeId); - - List getGradeClass(int schId,int role, int userId); - - List getClassStuList(int schId,Integer classId); - - Object getSchTeaTree(int schId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IExplanationService.java b/src/main/java/com/bestsch/classicalchinese/service/IExplanationService.java deleted file mode 100644 index 8a1ed54..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IExplanationService.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.VideoExplanation; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.Map; - -public interface IExplanationService { - - Object getExplanationList(int schId, int userId, Integer nodeId, Pageable pageable); - - void saveExplanation(int schId, int userId, List list); - - void saveExplanation1(int schId, int userId, Map map); - - void deleteExplanation(int userId, Integer id); - - void deleteExplanation(Integer id); - - Object pdfPreview(int schId, Integer id); - - Object getZYKSubjectTree(int schId, int userId, Integer nodeId); - - Object getZYKVideoList(int schId, int userId, int roleId, Integer nodeId, Integer page, Integer count); - - void initialization(Integer year,Integer schId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IFeedBackService.java b/src/main/java/com/bestsch/classicalchinese/service/IFeedBackService.java deleted file mode 100644 index 7f83aff..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IFeedBackService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.FeedBack; - -public interface IFeedBackService { - - void addFeedBack(FeedBack feedBack); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IOcrDataCacheService.java b/src/main/java/com/bestsch/classicalchinese/service/IOcrDataCacheService.java deleted file mode 100644 index db8fcc0..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IOcrDataCacheService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.enums.OcrDataCache; - -import java.util.Optional; - -/** - * @author CHY - * @date 2024/7/18 16:37 - */ -public interface IOcrDataCacheService { - - public void save(OcrDataCache ocrDataCache); - - public Optional findDataByImgUrl(String imgUrl); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IPunitCommunicationService.java b/src/main/java/com/bestsch/classicalchinese/service/IPunitCommunicationService.java deleted file mode 100644 index 542e596..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IPunitCommunicationService.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.PunitCommunication; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public interface IPunitCommunicationService { - void save(PunitCommunication entity); - - void delete(PunitCommunication entity); - - Optional findOne(Integer id, Integer userId, Integer schId); - - List findNodeStuCOne( Integer nodeId, Integer userId, Integer schId); - - List findNodesClassOne(List nodeIds, Integer classId , Integer schId); - - List findNodeClassOne( Integer nodeId, Integer classId , Integer schId); - - List findNodeCAll(List cIds, Integer schId); - - List getCommunicationClassStu(Integer schId,Integer classId,Integer nodeId); - - public List getClassCommunicationList(Integer nodeId,Integer classId,Integer schId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IPunitLeadlearningService.java b/src/main/java/com/bestsch/classicalchinese/service/IPunitLeadlearningService.java deleted file mode 100644 index 967373a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IPunitLeadlearningService.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.BschLeadlearning; -import com.bestsch.classicalchinese.entity.PunitLeadlearning; -import com.bestsch.classicalchinese.model.ExcelPunitTreeTea; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public interface IPunitLeadlearningService { - void save(PunitLeadlearning entity); - - void saveAll(List entitys); - - List findSchAll(Integer schId); - - Optional findOne(Integer textbookId,Integer nodeId,Integer schId); - - Optional findOne(Integer id, Integer schId); - - - //List getPunitList(Integer role,Integer userid,Integer year,Integer term,Integer schId); - -// Map getTeaPunitList(Integer role, Integer userid, Integer year, Integer term, Integer gradeId, String subjectId, Integer nodeId, -// Integer classId, Integer schId, Pageable pageable); - -// List getPunitAllList(Integer year,Integer term,Integer gradeId,String subjectId,Integer schId); -// -// List getExcelPunitTreeTea(Integer userid, Integer year, Integer term, Integer gradeId, String subId, Integer schId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IPunitQuestionService.java b/src/main/java/com/bestsch/classicalchinese/service/IPunitQuestionService.java deleted file mode 100644 index 31b51f9..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IPunitQuestionService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.PunitQuestion; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public interface IPunitQuestionService { - void save(PunitQuestion entity); - - void saveAll(List entitys); - - Optional findOne(Integer id, Integer schId); - - List findSchAll(Integer nodeId, Integer schId); - - List findMapAll(Integer nodeId, Integer schId); - - List findSchAll(Integer schId); - - void initialization(Integer year,Integer schId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IPunitStuAnswerService.java b/src/main/java/com/bestsch/classicalchinese/service/IPunitStuAnswerService.java deleted file mode 100644 index b930fb8..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IPunitStuAnswerService.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.PunitStuAnswer; -import org.springframework.data.domain.Pageable; - -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -public interface IPunitStuAnswerService { - void save(PunitStuAnswer entity); - - Map getPunitNodeInfo(int textbookId,int schId,Integer userId,Integer nodeId); - - List findAll(Integer stuId, List nodeIds, Integer schId); - - List findAll(Integer stuId, Integer schId); - - Optional findOne(Integer nodeId,Integer qId,Integer stuId,Integer schId); - - List findClassAll(Integer nodeId,Integer classId, Integer schId); - - List findClassAll(Integer classId,Integer schId); - - List findClassAll(Integer classId,Date startDate, Date endDate,Integer schId); - - List findStuAll(Integer stuId,String startDate, String endDate, Integer schId); - - Map getPageBySchId(int schId,Integer nodeId,Integer stuId, List isReview, Pageable pageable); - - Map getStuPageByList(int textbookId,int schId, Integer nodeId, Integer stuId, Date startDate, List status, Pageable pageable); - - Map getTeaPageBySchId(int schId,Integer classId,Integer nodeId, Pageable pageable); - - List findStuAnswerRecordAll(Integer nodeId,int stuId,int schId); - - List> tkRightAnswerList(String answerStr); - - String unescapeHtml(String text); - - boolean containImgOrFomula(String text); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IPunitZiYuanTreeTeaService.java b/src/main/java/com/bestsch/classicalchinese/service/IPunitZiYuanTreeTeaService.java deleted file mode 100644 index 2c7dd1c..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IPunitZiYuanTreeTeaService.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.PunitZiYuanTreeTea; - -import java.util.List; - -public interface IPunitZiYuanTreeTeaService { - void save(PunitZiYuanTreeTea entity); - - void saveAll(List entitys); - - List findNodeAll(Integer year,Integer term,Integer gradeId,String subId,Integer nodeId,Integer schId); - - List findNodeIdsAll(Integer year,Integer term,Integer gradeId,String subId,List nodeIds,Integer schId); - - void deleteAll(List entitys); - - void saveTreeNodeTea(Integer userid,Integer year,Integer term,Integer gradeId,String subId,Integer nodeId,List teaIds,Integer schId); -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/IStatisticsService.java b/src/main/java/com/bestsch/classicalchinese/service/IStatisticsService.java deleted file mode 100644 index d93294f..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/IStatisticsService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.bestsch.classicalchinese.service; - -import com.bestsch.classicalchinese.entity.PunitQuestion; -import com.bestsch.classicalchinese.entity.PunitStuAnswer; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.Map; - -public interface IStatisticsService { - Map getClassWcqk(int schId,Integer noteId,Integer classId); - - List getQuestionStusAnswer(PunitQuestion punitQuestion, List stuAnswerList, List classStuList); - - Map getStuPunitList(int schId,Integer stuId, List status, Pageable pageable); - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/BaseComService.java b/src/main/java/com/bestsch/classicalchinese/service/com/BaseComService.java deleted file mode 100644 index 4042ed4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/BaseComService.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.bestsch.classicalchinese.model.AcademicYear; -import com.bestsch.classicalchinese.model.DateModel; -import com.bestsch.classicalchinese.model.DateTimeModel; -import com.bestsch.classicalchinese.model.TreeUser; -import com.bestsch.classicalchinese.utils.TimeUtils; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class BaseComService { - @Autowired - private DeptSchService deptSchService; - private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); - - @Value("${FILE_PATH}") - private String FILE_PATH; - - @Value("${FILE_WEB_PATH}") - private String FILE_WEB_PATH; - - /** - * 获取当前学年学期 - * @return - */ - public DateModel getCurYearSemesterDate() { - DateModel map = new DateModel(); - List list = deptSchService.getAcademicYear(); - if (list.size() > 0) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - String times = sdf.format(new Date()); - Date time = sdf.parse(times); - for (AcademicYear item : list) { - DateModel dateMap = getStartEndDate(item.getStartDate(), item.getEndDate()); - if (time.after(dateMap.getStartDate()) && time.before(dateMap.getEndDate())) { - Integer year = item.getYear(); - Date firstStartDate = item.getFirstSemesterStartDate(); - Date firstEndDate = item.getFirstSemesterEndDate(); - DateModel dateMap2 = getStartEndDate(firstStartDate, firstEndDate); - - if (time.after(dateMap2.getStartDate()) && time.before(dateMap2.getEndDate())) { - map.setStartDate(firstStartDate); - map.setEndDate(firstEndDate); - map.setYear(year); - map.setSemester(1); - } else { - map.setStartDate(item.getSecondSemesterStartDate()); - map.setEndDate(item.getSecondSemesterEndDate()); - map.setYear(year); - map.setSemester(2); - } - } - } - } catch (ParseException e) { - } - } -// System.out.println("获取本学期开始结束日期map=========" + JSON.toJSONString(map)); - return map; - } - private DateModel getStartEndDate(Date startDate, Date endDate) { - Date fStartDate = getCalendar(startDate,-1); - Date fEndDate = getCalendar(endDate,1); - - DateModel _pram = new DateModel(); - _pram.setStartDate(fStartDate); - _pram.setEndDate(fEndDate); - - return _pram; - } - - - public Date getCalendar(Date date,int amount){ - Calendar c = Calendar.getInstance(); - c.setTime(date); - c.add(Calendar.DATE, amount); - return c.getTime(); - } - - - - /** - * 根据时间类型,获取时间 - */ - public DateTimeModel getDateTime(Integer timeIndex, String sDate, String eDate) { - Map time = TimeUtils.getTime(timeIndex.toString(), sDate, eDate); -// System.out.println("time==========="+ JSON.toJSONString(time)); - DateTimeModel pram = new DateTimeModel(); - if (time != null && time.size() > 0) { - pram.setTimeIndex(timeIndex); - try { - if (!time.get("startTime").equals("")) { - pram.setStartDate(sdf1.parse(time.get("startTime"))); - } - if (!time.get("endTime").equals("")) { - pram.setEndDate(sdf1.parse(time.get("endTime"))); - } - } catch (ParseException e) { - System.out.println("日期转换报错:"+e); - } - } -// System.out.println("pram==========="+ JSON.toJSONString(pram)); - - return pram; - } - - - public String getTeaName(List teaList, Integer teaId){ - String teaName = null; - if (teaId != null) { - List teaList1 = teaList.stream().filter(x -> x.getId() == teaId).collect(Collectors.toList()); - if (teaList1 != null && teaList1.size() > 0) - teaName = teaList1.get(0).getName(); - } - return teaName; - } - - - public Integer getWeek(String weeklyName){ - String name = weeklyName.replace("第","").replace("周",""); - Integer week = Integer.valueOf(name); - return week; - } - - public String getImgUrl(String imgUrl) { - if (imgUrl != null && StringUtils.isNotBlank(imgUrl)) - imgUrl = FILE_WEB_PATH + imgUrl; - return imgUrl; - } - - public String getFileUrl(Integer type, String url){ - - if (url != null && StringUtils.isNotBlank(url) && !url.equals("null")) { - if(type.equals(1)) - url = FILE_WEB_PATH + url; - } else{ - url = null; - } - return url; - } - public String getFilePath(Integer type, String url){ - - if (url != null && StringUtils.isNotBlank(url) && !url.equals("null")) { - if(type.equals(1)) - url = FILE_PATH + url; - } else{ - url = ""; - } - return url; - } - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/ClassService.java b/src/main/java/com/bestsch/classicalchinese/service/com/ClassService.java deleted file mode 100644 index c2fc59b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/ClassService.java +++ /dev/null @@ -1,813 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.alibaba.fastjson.JSON; -import com.bestsch.classicalchinese.model.*; -import com.bestsch.utils.BschUtils; -import com.bestsch.utils.DException; -import com.bestsch.utils.DHttp; -import com.bestsch.utils.LocalMemCache; -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class ClassService { - @Value("${bsch.open.schbase-host}") - private String BSCH_SCHBASE_HOST; - private LocalMemCache localMemCache = new LocalMemCache(); - - @Autowired - private UserGradeClassSubService userGradeClassSubService; - - public int GetSchId(String uuid) - { - String cacheKey = "sch_"+uuid; - String cache = (String)localMemCache.get(cacheKey); - if(cache != null && !cache.isEmpty()){ - return Integer.parseInt(cache); - } - String apiUrl = BSCH_SCHBASE_HOST+ "/oapi/SchGroup/GetSchoolIdByUUid?uuid=" + uuid; - String data = DHttp.get(apiUrl); - if(org.apache.commons.lang3.StringUtils.isEmpty(data)) throw new DException("BschClass返回值为null"); - int schid=Integer.parseInt(data); - localMemCache.cache(cacheKey,schid, 600000); - return schid; - } - - public String GetSchuuId (Integer schId) - { - String cacheKey = "schuuid_"+schId; - String cache = (String)localMemCache.get(cacheKey); - if(cache != null && !cache.isEmpty()){ - return cache; - } - String apiUrl = BSCH_SCHBASE_HOST+ "/oapi/SchGroup/GetSchoolUUidById?id=" + schId; - String uuid = DHttp.get(apiUrl); - if(org.apache.commons.lang3.StringUtils.isEmpty(uuid)) throw new DException("BschClass返回值为null"); - localMemCache.cache(cacheKey,uuid, 600000); - return uuid; - } - /** - * 获取学年信息 - * http://base.bestsch.com/BschClass/oapi/SchGroup/getAcademicYear - */ - public List getAcademicYear() { - String ret = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/SchGroup/getAcademicYear"); - List list = com.alibaba.fastjson.JSONArray.parseArray(ret, YearSemester.AcademicYear.class); - return list; - } - - public List> getTeaClasses(Integer roleId,Integer userId, Integer schId) - { - String key="tea_class_" + schId + "_"+ userId; - List> object = (List>) localMemCache.get(key); - if (object != null) - return object; - - Integer year=getCurYearSemesterDate().getYear(); - Integer term=getCurYearSemesterDate().getSemester(); - - List lists = getAllClassSubject(schId); - //List list = lists.stream().filter(x -> Objects.equals(x.get("teaId").toString(), userId.toString())&&Objects.equals(x.get("subId").toString(),subjectId)).collect(Collectors.toList());; - - object=new ArrayList<>(); - - //List classIds=getTeaClasses(userId,schId).stream().map(x->x.get("id").toString()).distinct().collect(Collectors.toList());; - //list=list.stream().filter(s->classIds.contains(s.get("classId").toString())).collect(Collectors.toList()); - - List gradelist = JSONArray.toList(getSchGrade(schId), Map.class); - List ulist=userGradeClassSubService.GetList(roleId,userId,schId); - //ulist=ulist.stream().filter(s->s.getGradeId().equals(gradeId)).collect(Collectors.toList()); - - for (Object obj : lists) - { - - Map cla = new HashMap<>(); - JSONObject jsonObject = JSONObject.fromObject(obj); - Map firstgrade= gradelist.stream().filter(s->s.get("Id").toString().equals(jsonObject.get("gradeId").toString())).findFirst().get(); - - Integer gradeId=(Integer)firstgrade.get("systemGrade"); - Integer classId=(Integer) jsonObject.get("classId"); - if(object.stream().filter(s->s.get("classId").toString().equals(classId.toString())).count()==0) - { - if(userGradeClassSubService.exists(ulist,classId)) - { - cla.put("classId", (Integer) jsonObject.get("classId")); - cla.put("gradeId", gradeId); - cla.put("className", jsonObject.get("gradeName") + ((String) jsonObject.get("className"))); - cla.put("gradeName", jsonObject.getString("gradeName")); - cla.put("year", year); - cla.put("term", term); - object.add(cla); - } - } - - } - localMemCache.cache(key, object, 60*1000); - - return object; - } - - - - public List> getTeaClasses(Integer userId, Integer schId) - { - List> object = (List>) localMemCache.get("tea_class_" + schId + "_"+ + userId); - if (object != null) - return object; - - object = getRemoteTeaClasses(userId, schId); - - localMemCache.cache("tea_class_" + schId + "_" + userId, object, 600000); - - return object; - } - - public List> getRemoteTeaClasses(Integer userId, Integer schId) - { - String resultData = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/Home/getGradeClassByTeacherId?userId=" + userId + "&schoolId=" + schId); - System.out.println("获取远程教师任教班级:" + userId + "_" + schId); - JSONArray jsonArray = JSONArray.fromObject(resultData); - Integer year=getCurYearSemesterDate().getYear(); - Integer term=getCurYearSemesterDate().getSemester(); - List> classList = new ArrayList<>(); - if (jsonArray.size() != 0) - { - for (Object obj : jsonArray) - { - Map cla = new HashMap<>(); - JSONObject jsonObject = JSONObject.fromObject(obj); - cla.put("id", (Integer) jsonObject.get("id")); - cla.put("name", ((String) jsonObject.get("gradeName")) + ((String) jsonObject.get("name"))); - cla.put("type", 0);//班级:0 学生:1(前端为了区分班级学生) - cla.put("gradeId", (Integer) jsonObject.get("systemGrade")); - cla.put("year", year); - cla.put("term", term); - classList.add(cla); - } - } - return classList; - } - /** - * 获取当前学年学期 - * @return - */ - public YearSemester getCurYearSemesterDate() { - YearSemester map = new YearSemester(); - List list = getAcademicYear(); - if (list.size() > 0) { - try { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - String times = sdf.format(new Date()); - Date time = sdf.parse(times); - for (YearSemester.AcademicYear item : list) { - YearSemester dateMap = getStartEndDate(item.getStartDate(), item.getEndDate()); - if (time.after(dateMap.getStartDate()) && time.before(dateMap.getEndDate())) { - Integer year = item.getYear(); - Date firstStartDate = item.getFirstSemesterStartDate(); - Date firstEndDate = item.getFirstSemesterEndDate(); - YearSemester dateMap2 = getStartEndDate(firstStartDate, firstEndDate); - - if (time.after(dateMap2.getStartDate()) && time.before(dateMap2.getEndDate())) { - map.setStartDate(firstStartDate); - map.setEndDate(firstEndDate); - map.setYear(year); - map.setSemester(1); - } else { - map.setStartDate(item.getSecondSemesterStartDate()); - map.setEndDate(item.getSecondSemesterEndDate()); - map.setYear(year); - map.setSemester(2); - } - } - } - } catch (ParseException e) { - } - } -// System.out.println("获取本学期开始结束日期map=========" + JSON.toJSONString(map)); - return map; - } - private YearSemester getStartEndDate(Date startDate, Date endDate) { - Date fStartDate = getCalendar(startDate,-1); - Date fEndDate = getCalendar(endDate,1); - - YearSemester _pram = new YearSemester(); - _pram.setStartDate(fStartDate); - _pram.setEndDate(fEndDate); - - return _pram; - } - public Date getCalendar(Date date,int amount){ - Calendar c = Calendar.getInstance(); - c.setTime(date); - c.add(Calendar.DATE, amount); - return c.getTime(); - } - - /** - * 年级信息 - * @return - */ - public Object getSchGradeTerm(Integer schId) { - JSONArray jsonArray = getSchGrade(schId); - - List graList = new ArrayList<>(); - if (jsonArray.size() != 0) { - for (Object obj : jsonArray) { - JSONObject jsonObject = JSONObject.fromObject(obj); - for (int i = 1; i <= 2; i++) { - Grade grade = new Grade(); - - grade.setId((Integer) jsonObject.get("Id")); - grade.setGradeId((Integer) jsonObject.get("systemGrade")); - String termName = (i == 1 ? "上" : "下"); - grade.setName((String) jsonObject.get("Name") + termName); - grade.setTerm(i); - graList.add(grade); - } - } - } - return graList; - } - private JSONArray getSchGrade(Integer schId){ - String resultData = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/Gradeinfo/GetSchGradeinfoBySchId?id=" + schId); - JSONArray jsonArray = JSONArray.fromObject(resultData); - return jsonArray; - } - - /** - * 年级信息 - * @return - */ - public List getGradeListBySchoolId(int schId) { - JSONArray jsonArray = getSchGrade(schId); - - List graList = new ArrayList<>(); - if (jsonArray.size() != 0) { - for (Object obj : jsonArray) { - Grade grade = new Grade(); - JSONObject jsonObject = JSONObject.fromObject(obj); - grade.setId((Integer) jsonObject.get("Id")); - grade.setGradeId((Integer) jsonObject.get("systemGrade")); - grade.setName((String) jsonObject.get("Name")); - grade.setTerm(1); - graList.add(grade); - } - } - return graList; - } - - - /** - * 获取学校学科 - * https://base.bestsch.com/BschClass/oapi/SubInfo/getSubjectBySchoolId?id=3260 - */ - public Object getSchoolSubject(Integer schId) - { - JSONArray new_array = new JSONArray(); - - // String resultData = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/SubInfo/getSubjectBySchoolId?id=" + schId); - String resultData = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/SubInfo/getSubjectBySchoolId?id=" + schId); - JSONArray jsonArray = JSONArray.fromObject(resultData); - if (BschUtils.isNotEmpty(jsonArray)) - { - for (int i = 0; i < jsonArray.size(); i++) - { - Map map = new HashMap(); - JSONObject o = (JSONObject) jsonArray.get(i); - String name = (String) o.get("name"); - String id = (String) (o.get("subId")); - if(new_array.stream().filter(s->((JSONObject)s).get("subId").equals(id)).count()==0) - { - map.put("name", name); - map.put("subId", id); - new_array.add(map); - } - } - } - return new_array; - } - - - /** - * 获取学校教师信息 - * https://base.bestsch.com/BschClass/oapi/DbClass/GetSchteaList?Group=3260 - */ - public List getSchteaList(Integer schId) { - List object = (List) localMemCache.get("GetSchteaList_" + schId); - if (object != null) - return object; - - String ret = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/DbClass/GetSchteaList?Group=" + schId); - List list = com.alibaba.fastjson.JSONArray.parseArray(ret, Map.class); - - localMemCache.cache("GetSchteaList_" + schId, list, 600000); - - return list; - } - - - public Set getSchoolSection(int schoolId) - { - try - { - //读缓存 - String cacheKey = "school_section_" + schoolId; - Set cached = (Set) localMemCache.get(cacheKey); - if (cached != null) - return cached; - - //远程获取 - String resultData = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/Schoolen/GetSectionBySchoolId?schoolId=" + schoolId); - - //解析 - Set sectionSet = new HashSet<>(JSON.parseArray(resultData, Integer.class)); - - //存缓存 - localMemCache.cache(cacheKey, sectionSet, 18000000); - - return sectionSet; - } - catch (Exception e) - { - return new HashSet<>(); - } - } - - - - public ClassInfo getClassInfo(int classId) - { - Map classInfoMap = getClassInfoMap(Collections.singletonList(classId)); - return classInfoMap.get(classId); - } - - //获取行政班班级信息 - public Map getClassInfoMap(List classIds) - { - Map retMap = new LinkedHashMap<>(); - List unCachedIds = new ArrayList<>(); - for (Integer classId : classIds) - { - Object object = localMemCache.get("class_" + classId); - if (object == null) - unCachedIds.add(classId); - else if (object.getClass() == ClassInfo.class) - retMap.put(classId, (ClassInfo) object); - } - - if (BschUtils.isEmpty(unCachedIds)) - return retMap; - - List> remoteList = getRemoteClassInfo(unCachedIds); - for (Map map : remoteList) - { - ClassInfo classInfo = BschUtils.copyObject(map, ClassInfo.class); - retMap.put(classInfo.getClassId(), classInfo); - localMemCache.cache("class_" + classInfo.getClassId(), classInfo, 600000); - unCachedIds.remove(classInfo.getClassId()); - } - - //那些取不到的,不管什么原因,也缓存后再取 - for (Integer id : unCachedIds) - localMemCache.cache("class_" + id, new Object(), 600000); - - return retMap; - } - private List> getRemoteClassInfo(List classIds) - { - String claId = StringUtils.join(classIds, ","); - - String resultData = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/VSchClass/getClassByClassIds?classIds=" + claId); - System.out.println("获取远程行政班信息:" + classIds + "," + resultData); - JSONArray jsonArray = JSONArray.fromObject(resultData); - List> classList = new ArrayList<>(); - if (jsonArray.size() == 0) - return classList; - - for (Object obj : jsonArray) - { - Map cla = new HashMap<>(); - JSONObject jsonObject = JSONObject.fromObject(obj); - cla.put("classId", (Integer) jsonObject.get("userClassID")); - cla.put("gradeId", (Integer) jsonObject.get("systemId")); - cla.put("className", jsonObject.get("gradeName") + ((String) jsonObject.get("className"))); - cla.put("gradeName", jsonObject.getString("gradeName")); - String teacherIdStr=jsonObject.optString("teacherId"); - cla.put("teacherId",teacherIdStr.isEmpty()||teacherIdStr=="null"?0:(Integer) jsonObject.get("teacherId")); - cla.put("schoolId",(Integer) jsonObject.get("schoolId")); - classList.add(cla); - } - - return classList; - } - - public List getTeachSubIds(int schId,Integer teaUserId) - { - List object = (List) localMemCache.get("GetSchTeachlist" + schId); - if (object != null) - { - List subIds=object.stream().filter(s->s.get("UserTeaSerID").equals(teaUserId.toString())) - .map(x -> x.get("SubID").toString()).distinct().collect(Collectors.toList()); - return subIds; - } - String ret = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/TeachInfo/GetSchTeachlist?SchID=" + GetSchuuId(schId)); - List list = com.alibaba.fastjson.JSONArray.parseArray(ret, Map.class); - - localMemCache.cache("GetSchTeacherList_" + schId, list, 600000); - - List subIds=list.stream().filter(s->s.get("UserTeaSerID").toString().equals(teaUserId.toString())) - .map(x -> x.get("SubID").toString()).distinct().collect(Collectors.toList()); - return subIds; - } - - public List getTeachGradeIds(int schId,Integer teaUserId,String subId) - { - List object = (List) localMemCache.get("GetSchTeachlist" + schId); - if (object != null) - { - List classIds=object.stream().filter(s->s.get("UserTeaSerID").equals(teaUserId.toString())&& - s.get("SubID").toString().equals(subId)) - .map(x -> Integer.parseInt(x.get("UserClassID").toString())) - .distinct().collect(Collectors.toList()); - List> vClassList= getRemoteClassInfo(classIds); - List gradeIds= vClassList.stream().map(s->Integer.parseInt(s.get("gradeId").toString())).distinct().collect(Collectors.toList()); - return gradeIds; - } - String ret = DHttp.get(BSCH_SCHBASE_HOST + "/oapi/TeachInfo/GetSchTeachlist?SchID=" + GetSchuuId(schId)); - List list = com.alibaba.fastjson.JSONArray.parseArray(ret, Map.class); - - localMemCache.cache("GetSchTeacherList_" + schId, list, 600000); - - List classIds=list.stream().filter(s->s.get("UserTeaSerID").toString().equals(teaUserId.toString())&& - s.get("SubID").toString().equals(subId)) - .map(x -> Integer.parseInt(x.get("UserClassID").toString())) - .distinct().collect(Collectors.toList()); - List> vClassList= getRemoteClassInfo(classIds); - List gradeIds= vClassList.stream().map(s->Integer.parseInt(s.get("gradeId").toString())).distinct().collect(Collectors.toList()); - return gradeIds; - } - -// public List GetTeaSubClassList(Integer schId, Integer teaId){ -// String apiUrl = BSCH_SCHBASE_HOST + "/oapi/Home/getGradeClassByTeacherId?schoolId=" + schId + "&userId=" + teaId; -// String resultData = DHttp.get(apiUrl); -// List list = new ArrayList<>(); -// List classList = com.alibaba.fastjson.JSONArray.parseArray(resultData, TeaFirstClass.class); -// for (TeaFirstClass cla : classList) { -// SchClassModel model = new SchClassModel(); -// model.setClassID(cla.getId()); -// model.setClassName(cla.getName()); -// model.setGradeID(cla.getGradeId()); -// model.setGradeName(cla.getGradeName()); -// list.add(model); -// } -// return list; -// } - /** - * 获取所有任教 - * https://base.bestsch.com/BschClass/oapi/Schoolen/GetAllClassSubject?schId=3260 - */ - public List getAllClassSubject(Integer schId) { - List object = (List) localMemCache.get("getAllClassSubject_" + schId); - if (object != null) - return object; -// -// YearSemester ytdate=getCurYearSemesterDate(); -// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); -// String myDate = sdf.format(DateUtils.addMonths(ytdate.getStartDate(),-1)); - - String url = BSCH_SCHBASE_HOST + "/oapi/Schoolen/GetAllClassSubject?schId=" + schId; - String ret = DHttp.get(url); - - List list = com.alibaba.fastjson.JSONArray.parseArray(ret, Map.class); - localMemCache.cache("getAllClassSubject_" + schId, list, 600000); - - return list; - } - - public Map getTeaSubjectGrade(Integer schId,Integer roleId,Integer userId) { - - List ulist = userGradeClassSubService.GetList(roleId,userId,schId); - if (ulist != null && ulist.size() > 0) { - Map map = new HashMap(); - map.put("subId", ulist.get(0).getSubId()); - map.put("gradeId", ulist.get(0).getGradeId()); - return map; - } - return null; - } - - /** - * 获取教师任教 - * subId subName classId className - */ - public List getTeaClassSubject(Integer schId,Integer gradeId,Integer userId) { - List lists = getAllClassSubject(schId); - List list = lists.stream().filter(x -> Objects.equals(x.get("teaId").toString(), userId.toString())&&x.get("gradeId").toString().equals(gradeId.toString())).collect(Collectors.toList()); - List teaClassSubList=new ArrayList<>(); - if (list != null && list.size() > 0) { - for (Map map : list) { - Map teachcs=new HashMap(); - teachcs.put("classId",Integer.parseInt(map.get("classId").toString())); - teachcs.put("className",map.get("className").toString()); - teachcs.put("subId",map.get("subId").toString()); - teachcs.put("subName",map.get("subName").toString()); - teaClassSubList.add(teachcs); - } - } - return teaClassSubList; - } - - public List getTeaSubject(Integer schId,Integer roleId,Integer userId) { - // List lists = getAllClassSubject(schId); - //List list = lists.stream().filter(x -> Objects.equals(x.get("teaId").toString(), userId.toString())).collect(Collectors.toList()); - List list = (List) getSchoolSubject(schId); - List ulist=userGradeClassSubService.GetList(roleId,userId,schId); - List subIds=ulist.stream().map(s->s.getSubId()).distinct().collect(Collectors.toList()); - list=list.stream().filter(s->subIds.contains(s.get("subId").toString())).collect(Collectors.toList()); - List subarr=new ArrayList<>(); - Integer i=1; - if (list != null && list.size() > 0) { - for (Map map : list) { - Map sub=new HashMap(); - //teachcs.put("classId",Integer.parseInt(map.get("classId").toString())); - //teachcs.put("className",map.get("className").toString()); - sub.put("id",i++); - sub.put("code",map.get("subId").toString()); - sub.put("name",map.get("name").toString()); - subarr.add(sub); - } - } - return subarr; - } - - public List getTeaGrade(Integer schId,Integer roleId,Integer userId,String subjectId) { - - List ulist=userGradeClassSubService.GetList(roleId,userId,schId); - List gradeIds=ulist.stream().filter(s->s.getSubId().equals(subjectId)).map(s->s.getGradeId()).distinct().collect(Collectors.toList()); - return getGradeListBySchoolId(schId).stream().filter(s->gradeIds.contains(s.getGradeId())).collect(Collectors.toList()); - } - - //获取任教年级学科-教师 - public List getGradeSubTeaList(Integer schId,Integer gradeId,String subId) { - List lists = getAllClassSubject(schId); - - Integer gId = 0; - List gradeList = getGradeListBySchoolId(schId); - List gradeList1 = gradeList.stream().filter(x -> Objects.equals(x.getGradeId().toString(), gradeId.toString())).collect(Collectors.toList()); - if (gradeList1 != null && gradeList1.size() > 0) { - gId = gradeList1.get(0).getId(); - } - String grId=gId.toString(); - - List list = lists.stream().filter(x -> Objects.equals(x.get("subId").toString(), subId.toString())&&grId.equals(x.get("gradeId").toString())).collect(Collectors.toList()); - List teaClassSubList=new ArrayList<>(); - if (list != null && list.size() > 0) { - for (Map map : list) { - Map teachcs=new HashMap(); - teachcs.put("teaId",map.get("teaId").toString()); - teachcs.put("teaName",map.get("teaName").toString()); - teaClassSubList.add(teachcs); - } - } - return teaClassSubList; - } - - - public List getClassStuList(Integer classId){ - return getClassStuList(new Integer[]{classId}); - } - - public List getClassStuList(Integer[] classIds) - { - String apiUrl = BSCH_SCHBASE_HOST + "/oapi/OAStu/GetClaArrStulist?clagroupids=" + StringUtils.join(classIds, ","); - String resultData = DHttp.get(apiUrl); - JSONArray jsonArray = JSONArray.fromObject(resultData); - List list = new ArrayList<>(); - if (jsonArray.size() != 0) { - for (Object obj : jsonArray) { - JSONObject jsonObject = JSONObject.fromObject(obj); - Map map = new HashMap(); - map.put("id",jsonObject.getInt("UserStuSerID")); - map.put("name",jsonObject.getString("StuName")); - map.put("classId",jsonObject.getInt("GroupID")); - map.put("xuehaoId",jsonObject.getString("ClassStuID")); - map.put("photo",jsonObject.getString("StuPhoto")); - list.add(map); - } - } - return list; - } - - - public List GetSchTeaTree(Integer schId) { - String groupApiUrl = BSCH_SCHBASE_HOST + "/oapi/OptCourse/getSchoolGroupByschId?id=" + schId, - teaApiUrl = BSCH_SCHBASE_HOST + "/oapi/OATea/GetSchTeainfoById?id=" + schId; - String groupResultData = DHttp.get(groupApiUrl); - String teaResultData = DHttp.get(teaApiUrl); - JSONArray groupJsonArray = JSONArray.fromObject(groupResultData); - JSONArray teaJsonArray = JSONArray.fromObject(teaResultData); - List list = new ArrayList<>(); - if (groupJsonArray.size() != 0) { - for (Object obj : groupJsonArray) { - JSONObject jsonObject = JSONObject.fromObject(obj); - BaseTree model = new BaseTree(); - model.setId(jsonObject.getInt("id")); - model.setName(jsonObject.getString("name")); - model.setPid(jsonObject.getInt("pId")); - list.add(model); - } - } - if (teaJsonArray.size() != 0) { - for (Object obj : teaJsonArray) { - JSONObject jsonObject = JSONObject.fromObject(obj); - BaseTree model = new BaseTree(); - model.setId(jsonObject.getInt("UserID")); - model.setName(jsonObject.getString("Name")); - model.setPid(jsonObject.getInt("GroupID")); - list.add(model); - } - } - //生成树形结构 - List tree = FormatTree(list, 0); - if (tree == null) tree = new ArrayList<>(); - return tree; - } - - /** - * 将扁平数组格式化为tree - * - * @param trees - * @param pid - * @return - */ - private List FormatTree(List trees, Integer pid) { - List list = new ArrayList<>(); - List glist = trees.stream().filter(x -> x.getPid().equals(pid)).collect(Collectors.toList()); - for (BaseTree item : glist) { - BaseTree model = new BaseTree(); - model.setId(item.getId()); - model.setName(item.getName()); - model.setPid(item.getPid()); - model.setChildren(FormatTree(trees, item.getId())); - list.add(model); - } - return list.size() > 0 ? list : null; - } - - public Map> getSchGradeGroup(Integer schId) - { - String key="getSchGradeGroup_"+schId; - Map> result = (Map>) localMemCache.get(key); - if (result != null) - return result; - result = new HashMap<>(); - - String apiUrl = BSCH_SCHBASE_HOST + "/oapi/SchGroup/getGradeGroup?schoolId=" +schId; - String resultData = DHttp.get(apiUrl); - - // 解析JSON数组 - JSONArray jsonArray = JSONArray.fromObject(resultData); - for (int i = 0; i < jsonArray.size(); i++) { - JSONObject item = jsonArray.getJSONObject(i); - - // 获取systemGrade - JSONObject grade = item.getJSONObject("grade"); - Integer systemGrade = Integer.parseInt(grade.get("systemGrade").toString()); - - // 获取teamLeaders的id集合 - List leaderIds = new ArrayList<>(); - JSONArray teamLeaders = item.getJSONArray("teamLeaders"); - if (teamLeaders != null) { - for (int j = 0; j < teamLeaders.size(); j++) { - JSONObject leader = teamLeaders.getJSONObject(j); - Integer id = Integer.parseInt(leader.get("id").toString()); - if (id != null) { - leaderIds.add(id); - } - } - } - - // 获取teamMembers的id集合 - List memberIds = new ArrayList<>(); - JSONArray teamMembers = item.getJSONArray("teamMembers"); - if (teamMembers != null) { - for (int j = 0; j < teamMembers.size(); j++) { - JSONObject member = teamMembers.getJSONObject(j); - Integer id = Integer.parseInt(member.get("id").toString()); - if (id != null) { - memberIds.add(id); - } - } - } - // 合并两个id集合 - List allIds = new ArrayList<>(); - allIds.addAll(leaderIds); - allIds.addAll(memberIds); - // 放入结果Map - result.put(systemGrade, allIds); - } - - if(result.size()>0) - localMemCache.cache(key, result, 5 * 60 * 1000); - return result; - } - - public List getSchSubGroup(Integer schId) - { - String key="getSchSubGroup"+schId; - List result = (List) localMemCache.get(key); - if (result != null) - return result; - result = new ArrayList<>(); - - - - String apiUrl = BSCH_SCHBASE_HOST + "/oapi/ziyuan/getSubjectGroupBySchoolId?schoolId=" +schId; - String resultData = DHttp.get(apiUrl); - - // 解析JSON数组 - JSONArray jsonArray = JSONArray.fromObject(resultData); - for (int i = 0; i < jsonArray.size(); i++) { - - JSONObject item = jsonArray.getJSONObject(i); - - // 获取systemGrade - List systemGrades = new ArrayList<>(); - JSONArray grades = item.getJSONArray("grades"); - if (grades != null) { - for (int j = 0; j < grades.size(); j++) { - JSONObject gradeobj = grades.getJSONObject(j); - Integer id = Integer.parseInt(gradeobj.get("systemGrade").toString()); - if (id != null) { - systemGrades.add(id); - } - } - } - - List subIds = new ArrayList<>(); - JSONArray subjects = item.getJSONArray("subjects"); - if (subjects != null) { - for (int j = 0; j < subjects.size(); j++) { - JSONObject subobj = subjects.getJSONObject(j); - String subId = subobj.get("subId").toString(); - if (subId != null) { - subIds.add(subId); - } - } - } - - // 获取teamLeaders的id集合 - List leaderIds = new ArrayList<>(); - JSONArray teamLeaders = item.getJSONArray("teamLeaders"); - if (teamLeaders != null) { - for (int j = 0; j < teamLeaders.size(); j++) { - JSONObject leader = teamLeaders.getJSONObject(j); - Integer id = Integer.parseInt(leader.get("id").toString()); - if (id != null) { - leaderIds.add(id); - } - } - } - - // 获取teamMembers的id集合 - List memberIds = new ArrayList<>(); - JSONArray teamMembers = item.getJSONArray("teamMembers"); - if (teamMembers != null) { - for (int j = 0; j < teamMembers.size(); j++) { - JSONObject member = teamMembers.getJSONObject(j); - Integer id = Integer.parseInt(member.get("id").toString()); - if (id != null) { - memberIds.add(id); - } - } - } - // 合并两个id集合 - List allIds = new ArrayList<>(); - allIds.addAll(leaderIds); - allIds.addAll(memberIds); - // 放入结果Map - SubGroupTeaIds sgroupt=new SubGroupTeaIds(); - sgroupt.gradeIds=systemGrades; - sgroupt.subIds=subIds; - sgroupt.teaIds=allIds; - result.add(sgroupt); - } - - if(result.size()>0) - localMemCache.cache(key, result, 5 * 60 * 1000); - return result; - } - - -} - - diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/CommonService.java b/src/main/java/com/bestsch/classicalchinese/service/com/CommonService.java deleted file mode 100644 index cddd809..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/CommonService.java +++ /dev/null @@ -1,347 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.alibaba.fastjson.JSON; -import com.bestsch.openapi.sch.BschSchOpenApi; -import com.bestsch.classicalchinese.model.ClassInfo; -import com.bestsch.classicalchinese.model.Grade; -import com.bestsch.classicalchinese.model.UserGradeClassSub; -import com.bestsch.classicalchinese.model.YearSemester; -import com.bestsch.classicalchinese.service.ICommonService; -import com.bestsch.classicalchinese.utils.RedisConstants; -import com.bestsch.classicalchinese.utils.RedisUtil; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class CommonService implements ICommonService { - //@Autowired - //private ZiyuankuService ziyuankuService; - - @Autowired - private ClassService classService; - @Autowired - private DeptSchService deptSchService; - - @Autowired - private RedisUtil redisUtil; - - @Autowired - private BschSchOpenApi bschSchOpenApi; - - @Autowired - private UserGradeClassSubService userGradeClassSubService; - - /** - * 获取学科年级学期 - */ - // @Override -// public Object getSubjectGradeTerm(int schId, int roleId, int userId,Integer gradeId) { -// -// List ulist= userGradeClassSubService.GetList(roleId,userId,schId); -// -// List list = new ArrayList<>(); -// List schSubject_cache = (List)classService.getSchoolSubject(schId); -// List nodeList = ziyuankuService.getCourseNodeSelectionList(schId,null); -// List schGra; -// if (roleId == 3){ -// schGra = (List) classService.getSchGradeTerm(schId); -// }else{ -// schGra = classService.getGradeListBySchoolId(schId); -// } -// -// YearSemester curYear = null; -// if (roleId == 3){ -// curYear = classService.getCurYearSemesterDate(); -// } -// -// List subjects = nodeList.stream().map(x -> x.get("subject").toString()).distinct().collect(Collectors.toList()); -// for (String subject:subjects){ -// Map map = new HashMap(); -// map.put("value",subject); -// String subjectName = schSubject_cache.stream().filter(x -> Objects.equals(x.get("subId").toString(), subject)).map(x->x.get("name").toString()).findFirst().orElse(null); -// map.put("label",subjectName); -// -// List children = new ArrayList<>(); -// if (roleId == 1 || roleId==2 || roleId==7){ -// //教师:获取全部 -// children = getTeaChildrenGradeTerm(ulist,nodeList,schGra,subject); -// } -// else if (roleId == 3) { -// if (gradeId == null || curYear == null) return null; -// //学生:当前年级和历史年级 -// children = getStuChildrenGradeTerm(curYear, schGra, gradeId); -// } -// -// map.put("children",children); -// if(children.size()>0) -// list.add(map); -// } -// return list; -// } -// private List getTeaChildrenGradeTerm(List ulist,List nodeList, List schGra, String subject){ -// -// List children = new ArrayList<>(); -// List grades = nodeList.stream().filter(x->Objects.equals(x.get("subject").toString(),subject)).sorted(Comparator.comparingInt(x->Integer.valueOf(x.get("grade").toString()))).collect(Collectors.toList()); -// for (Map gradeMap:grades){ -// Integer grade = Integer.valueOf(gradeMap.get("grade").toString()); -// -// if(!userGradeClassSubService.exists(ulist,grade,subject,null)) continue; -// -// String gradeNme = schGra.stream().filter(x -> Objects.equals(x.getGradeId(), grade)).map(x -> x.getName()).findFirst().orElse(null); -// int j=0; -// for(int i = 1;i<3;i++) { -// Map map1 = new HashMap(); -// map1.put("value", grade+"_"+gradeMap.get("academicYear")+"_"+i); -// map1.put("year", gradeMap.get("academicYear")); -// if (i == 1 && gradeMap.get("semesterUpNode") != null) { -// map1.put("label", gradeNme + "上"); -// } else if (i == 2 && gradeMap.get("semesterDownNode") != null) { -// map1.put("label", gradeNme + "下"); -// } else j = 1; -// map1.put("term", i); -// if (j == 0) children.add(map1); -// } -// } -// return children; -// } -// private List getStuChildrenGradeTerm(YearSemester curYear, List schGra, Integer gradeId){ -// List list = new ArrayList<>(); -// for (Grade grade : schGra) { -// Map map = new HashMap(); -// map.put("label", grade.getName()); -// map.put("term", grade.getTerm()); -// -// if (grade.getGradeId().compareTo(gradeId) < 0) { -// Integer mYear = curYear.getYear() - (gradeId - grade.getGradeId()); -// map.put("year", mYear); -// map.put("value", grade.getGradeId()+"_"+mYear+"_"+grade.getTerm()); -// list.add(map); -// } else if (Objects.equals(grade.getGradeId(), gradeId) && grade.getTerm().compareTo(curYear.getSemester()) <= 0) { -// //若年级ID相等时,学期小于等于当前学期 -// map.put("year", curYear.getYear()); -// map.put("value", grade.getGradeId()+"_"+curYear.getYear()+"_"+grade.getTerm()); -// list.add(map); -// } -// } -// return list; -// } -// -// -// public Map getTeaSubGradeTrem(int roleId,int schId,int userId) -// { -// YearSemester curYear = classService.getCurYearSemesterDate(); -// Map map=classService.getTeaSubjectGrade(schId,roleId,userId); -// map.put("value",map.get("gradeId")==null?null:(map.get("gradeId")+"_"+curYear.getYear()+"_"+curYear.getSemester())); -// return map; -// } - -// public List getTeachSubGrade(int schId,int userId) -// { -// List subIds= classService.getTeachSubIds(schId,userId); -// List schSubject_cache = (List)classService.getSchoolSubject(schId); -// schSubject_cache=schSubject_cache.stream().filter(s->subIds.contains(s.get("subId").toString())).collect(Collectors.toList()); -// List list=new ArrayList<>(); -// for (Map sub:schSubject_cache){ -// Map map=new HashMap(); -// map.put("children",new ArrayList<>()); -// map.put("label",sub.get("name").toString()); -// map.put("value",sub.get("subId").toString()); -// list.add(map); -// } -// return list; -// } - -// /** -//// * 知识树节点 -//// */ -//// @Override -//// public Object getChapterWrongQuestNumTree(int schId, Integer year, Integer term,String checkedIds) { -//// if (year == null || term == null) { -//// YearSemester curYear = classService.getCurYearSemesterDate(); -//// year = curYear.getYear(); -//// term = curYear.getSemester(); -//// } -//// List list = getTreeList(schId, year, term,checkedIds); -//// return list; -//// } - -// @Override -// public Object getChapterWrongQuestNumTree(int schId,int userId, String subjectId,String checkedIds) { -// YearSemester curYear = classService.getCurYearSemesterDate(); -// Integer year = curYear.getYear(); -// Integer term = curYear.getSemester(); -// List list = new ArrayList<>(); -// List subGradeIds=classService.getTeachGradeIds(schId,userId,subjectId); -// for (Integer gradeId:subGradeIds) -// { -// list.addAll(getTreeList(schId, subjectId, gradeId, year, term,checkedIds)); -// } -// return list; -// } - -// private List getTreeList(Integer schId,String subjectId,Integer gradeId,Integer year,Integer term,String checkedIds){ -// List courseTrees = (List)ziyuankuService.getCourseTree_cache(schId, gradeId, year, term, subjectId); -// -// return courseTrees.stream() -// .map(x -> { -// Map map = new HashMap(); -// map.put("id", x.get("id")); -// map.put("title", x.get("name")); -// map.put("name", x.get("name")); -// map.put("path",x.get("path")); -// map.put("type", 1); -// map.put("expand", true); -// Boolean checked = getChecked(checkedIds, x.get("id").toString()); -// map.put("checked",checked); -// map.put("selected",checked); -// List children1 = com.alibaba.fastjson.JSONArray.parseArray(JSON.toJSONString(x.get("children")),Map.class); -// -// map.put("children", getChildren(children1,2,checkedIds)); -// return map; -// }).collect(Collectors.toList()); -// } -// public List getChildren(List children,int type, String checkedIds){ -// return children.stream() -// .map(child -> { -// Map map = new HashMap(); -// map.put("id", child.get("id")); -// map.put("title", child.get("name")); -// map.put("name", child.get("name")); -// map.put("path",child.get("path")); -// map.put("type", type); -// Boolean checked = getChecked(checkedIds,child.get("id").toString()); -// map.put("checked", checked); -// map.put("selected", checked); -// -// Boolean expand = false; -// if (child.get("children") != null) { -// List children1 = com.alibaba.fastjson.JSONArray.parseArray(JSON.toJSONString(child.get("children")), Map.class); -// List children2 = getChildren(children1, type + 1, checkedIds); -// map.put("children",children2); -// -// long checkedCount = children2.stream().filter(x -> Boolean.valueOf(x.get("expand").toString()).equals(true)).count(); -// if (checkedCount>0)expand = true; -// } -// -// map.put("expand", checked==true || expand==true?true:false); -// return map; -// }).collect(Collectors.toList()); -// } -// private Boolean getChecked(String checkedIds,String id){ -// Boolean checked = false; -// if (checkedIds != null || StringUtils.isNotEmpty(checkedIds)){ -// List checkedIdList = Arrays.asList(checkedIds.split(",")); -// if (checkedIdList.contains(id)){ -// checked = true; -// } -// } -// return checked; -// } -// -// -// -// -// @Override -// public Object getGradeTerm(int schId, int userId, Integer gradeId) { -// YearSemester curYear = classService.getCurYearSemesterDate(); -// -// List schGra = (List) classService.getSchGradeTerm(schId); -// -// if(gradeId==null)gradeId=schGra.stream().sorted(Comparator.comparingInt(Grade::getGradeId).reversed()) // 降序排序 -// .findFirst().get().getGradeId(); -// -// List list = getStudentGradeTerm(curYear,schGra,gradeId); -// return list; -// } -// -// private List getStudentGradeTerm(YearSemester curYear,List schGra,Integer gradeId){ -// //todo 获取资源库设置中,某学年年级是否有,有显示,没有不显示 -// List list = new ArrayList<>(); -// for (Grade grade : schGra) { -// Map map = new HashMap(); -// map.put("grade", grade.getGradeId()); -// map.put("name", grade.getName()); -// map.put("term", grade.getTerm()); -// if (grade.getGradeId().compareTo(gradeId) < 0) { -// map.put("year", curYear.getYear() - (gradeId - grade.getGradeId())); -// list.add(map); -// } else{ -// //if (Objects.equals(grade.getGradeId(), gradeId) && grade.getTerm().compareTo(curYear.getSemester()) <= 0) { -// //若年级ID相等时,学期小于等于当前学期 -// map.put("year", curYear.getYear() + (grade.getGradeId()-gradeId)); -// list.add(map); -// } -// -// } -// return list; -// } - - @Override - public List getGradeClass(int schId,int role, int userId){ - - String cacheKey = RedisConstants.SCH_USER_CLASS + schId + "_" + userId + "_" + role ; - - List gradeClassList=(List)redisUtil.get(cacheKey); - - if (gradeClassList!=null&&gradeClassList.size()>0) - return gradeClassList; - - gradeClassList=new ArrayList<>(); - - List ulist = userGradeClassSubService.GetList(role,userId,schId); - - List uglist=ulist.stream().collect(Collectors.toList()); - List classIds=uglist.stream().map(s->s.getClassId()).distinct().collect(Collectors.toList()); - - Map map= classService.getClassInfoMap(classIds); - - for (Map.Entry entry : map.entrySet()) { - Map claMap=new HashMap(); - claMap.put("id",entry.getKey()); - claMap.put("name",entry.getValue().getClassName()); - gradeClassList.add(claMap); - } - - redisUtil.set(cacheKey, gradeClassList, 5 * 60*1000); - return gradeClassList; - - } - - @Override - public List getClassStuList(int schId,Integer classId){ - - if(classId==null) return new ArrayList<>(); - - String cacheKey = RedisConstants.STUDENT_ALL + schId + "_" + classId; - - - if (redisUtil.hasKey(cacheKey)) - { - List list= (List)redisUtil.get(cacheKey); - if(list!=null&&list.size()>0) - return list; - } - - - List classStuList = classService.getClassStuList(classId); - - System.out.println("classStuList="+JSON.toJSONString(classStuList)); - - if(classStuList.size()>0) - redisUtil.set(cacheKey, classStuList, 24 * 60 * 60 * 1000); - - return classStuList; - } - - @Override - public Object getSchTeaTree(int schId) - { - return classService.GetSchTeaTree(schId); - } - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/DeepSeekApiService.java b/src/main/java/com/bestsch/classicalchinese/service/com/DeepSeekApiService.java deleted file mode 100644 index 882811b..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/DeepSeekApiService.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import cn.hutool.http.HttpUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.bestsch.utils.DException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -public class DeepSeekApiService { - - @Value("${bsch.openai.host}") - private String openaiHost; - - @Value("${bsch.openai.max-tokens}") - private int maxTokens; - - @Value("${bsch.openai.temperature}") - private float temperature; - - @Value("${bsch.openai.api-key}") - private String apiKey; - - - public String send(String prompt) { - - String url = openaiHost; - - List> messages=new ArrayList<>(); - Map msg=new HashMap(); - msg.put("role","user"); - msg.put("role","user"); - messages.add(msg); - - - Map requestBody = new HashMap<>(); - requestBody.put("model", "deepseek-chat"); - requestBody.put("messages",messages); - requestBody.put("max_tokens", maxTokens); - requestBody.put("temperature", temperature); - - Map requestHeader = new HashMap<>(); - requestHeader.put("Authorization","Bearer "+apiKey); - requestHeader.put("Content-Type", "application/json"); - requestHeader.put("Accept", "application/json"); - String body=JSON.toJSONString(requestBody); - try { - System.out.println("open AI 提问:"+prompt); - String responseBody = HttpUtil.post(url,body); - JSONObject jsonObject = JSONObject.parseObject(responseBody); - JSONArray choices = jsonObject.getJSONArray("choices"); - String text = choices.getJSONObject(0).getString("text"); - System.out.println("open AI 请求成功!"+text); - return toTextJson(text, "```json", "```"); - - } catch (Exception e) { - System.out.println("open AI 请求失败!"+e.toString()); - throw new DException("open AI 请求失败!"); - //e.printStackTrace(); - } - } - - - - private String toTextJson(String text, String s, String e) - { - if (text.contains(s) && text.contains(e)) - { - int index = text.indexOf(s); - text = text.substring(index+s.length(),text.length()); - index = text.lastIndexOf(e); - text = text.substring(0, index); - } - return text; - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/DeptSchService.java b/src/main/java/com/bestsch/classicalchinese/service/com/DeptSchService.java deleted file mode 100644 index 6aa53ec..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/DeptSchService.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.bestsch.openapi.sch.BschSchOpenApi; -import com.bestsch.classicalchinese.model.AcademicYear; -import com.bestsch.classicalchinese.model.ClassModel; -import com.bestsch.classicalchinese.model.SchSub; -import com.bestsch.classicalchinese.utils.RedisConstants; -import com.bestsch.classicalchinese.utils.RedisUtil; -import com.bestsch.classicalchinese.utils.Signature; -import com.bestsch.utils.DException; -import com.bestsch.utils.DHttp; -import net.sf.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class DeptSchService { - @Value("${bsch.open.schbase-host}") - private String schHost; - - @Value("${bsch.open.base-host}") - private String baseHost; - - @Value("${bsch.open.app-secret}") - private String app_secret; - - @Value("${bsch.open.app-key}") - private String app_key; - - @Autowired - private RedisUtil redisUtil; - - @Autowired - private BschSchOpenApi bschSchOpenApi; - - //按学校短id取长id - public String getSchUUIDById(int schoolId) - { - String cacheKey = RedisConstants.CachePrefix+".schuuid_" + schoolId; - if (redisUtil.hasKey(cacheKey)) - return redisUtil.get(cacheKey).toString(); - String uuid = bschSchOpenApi.getSchoolUUidById(schoolId); - redisUtil.set(cacheKey, uuid, 24 * 60 * 60); - return uuid; - } - /** - * 获取学年信息 - * http://sch.bestsch.com/oapi/SchGroup/getAcademicYear - */ - public List getAcademicYear() { - String url = schHost + "/oapi/SchGroup/getAcademicYear"; - String ret = DHttp.get(url); - List list = JSONArray.parseArray(ret, AcademicYear.class); - return list; - } - - /** - * 获取学校年级,班级 √ - * http://sch.bestsch.com/oapi/VSchClass/getGradeAndClassBySchoolId?schoolId=3704 - */ - public List getGradeAndClassBySchoolId(Integer schoolId) { - String url = schHost + "/oapi/VSchClass/getGradeAndClassBySchoolId?schoolId=" + schoolId; - String ret = DHttp.get(url); - return JSONArray.parseArray(ret, Map.class); - } - - - /** - * 年级信息 - * http://sch.bestsch.com/oapi/Gradeinfo/GetSchGradeinfoBySchId?id=1410 - */ - public List getSchGradeinfoBySchId(Integer schId) { - String url = schHost + "/oapi/Gradeinfo/GetSchGradeinfoBySchId?id=" + schId; - String ret = DHttp.get(url); - - List mapList = new ArrayList<>(); - List list = JSONArray.parseArray(ret, Map.class); - for (Map map : list) { - Map _map = new HashMap(); - _map.put("id", map.get("Id")); - _map.put("name", map.get("Name")); - _map.put("sysid",map.get("systemGrade")); - mapList.add(_map); - } - return mapList; - } - - public List getSchSub(Integer schId) { - String cacheKey = RedisConstants.CachePrefix+".sublist" + schId; - - if (redisUtil.hasKey(cacheKey)) { - Object obj = redisUtil.get(cacheKey); - String jsonStr = JSON.toJSONString(obj); - return JSONArray.parseArray(jsonStr, SchSub.class); - } - String url = schHost + "/oapi/SubInfo/GetSchSublist?SchID=" + getSchUUIDById(schId); - String ret = DHttp.get(url); - List subList= JSONArray.parseArray(ret, SchSub.class); - redisUtil.set(cacheKey, subList, 24 * 60 * 60); - return subList; - } - - /** - * 获取年级下的班级 - * http://sch.bestsch.com/oapi/VSchClass/getClassByGradeIdAndSchoolId?gradeId=13&schoolId=1410 - */ - public List getClassByGradeIdAndSchoolId(Integer schId, Integer gradeId) { - String url = schHost + "/oapi/VSchClass/getClassByGradeIdAndSchoolId?gradeId=" + gradeId + "&schoolId=" + schId; - String ret = DHttp.get(url); - - List mapList = new ArrayList<>(); - List list = JSONArray.parseArray(ret, Map.class); - for (Map map : list) { - Map _map = new HashMap(); - - _map.put("id", map.get("id")); - _map.put("name",map.get("gradeName").toString()+map.get("name").toString()); - - mapList.add(_map); - } - return mapList; - } - - - /** - * 获取学校班级接口 - * http://sch.bestsch.com/oapi/DbClass/GetSchClass?SchID=3704 - */ - public List getSchClass(Integer schId, Integer gradeId, Integer classId) { - String url = schHost + "/oapi/DbClass/GetSchClass?SchID=" + schId; - String ret = DHttp.get(url); - - List list = new ArrayList<>(); - List mapList = JSONArray.parseArray(ret, Map.class); - for (Map map : mapList) { - ClassModel model = new ClassModel(); - model.setClassId((Integer) map.get("CID")); - model.setClassIds((String) map.get("ClassID")); - model.setClassName((String) map.get("ClassName")); - model.setGradeId((Integer) map.get("GradeID")); - model.setGradeName((String) map.get("GradeName")); - model.setName((String) map.get("GradeName") + map.get("ClassName")); - list.add(model); - } - if (gradeId != null) - list = list.stream().filter(x -> String.valueOf(x.getGradeId()).equals(gradeId.toString())).collect(Collectors.toList()); - - if (classId != null) - list = list.stream().filter(x -> String.valueOf(x.getClassId()).equals(classId.toString())).collect(Collectors.toList()); - - return list; - } - - public Integer getGradeIdByClassId(Integer schId, Integer classId) { - List list = getSchClass(schId, null, classId); - - Integer gradeId = null; - if (list != null && list.size() > 0) - gradeId = list.get(0).getGradeId(); - return gradeId; - } - - - /** - * 获取班级信息通过班级id - * http://sch.bestsch.com/oapi/VSchClass/GetVClass2?groupid=6351 - */ - public List getVClass2(Integer classId) { - String url = schHost + "/oapi/VSchClass/GetVClass2?groupid=" + classId; - String ret = DHttp.get(url); - - List list = new ArrayList<>(); - List mapList = JSONArray.parseArray(ret, Map.class); - for (Map map : mapList) { - ClassModel model = new ClassModel(); - model.setClassId((Integer) map.get("UserClassID")); - model.setClassIds((String) map.get("ClassGUID")); - model.setClassName((String) map.get("ClassName")); - model.setGradeId(null); - model.setGradeName((String) map.get("GradeName")); - model.setName((String) map.get("GradeName") + map.get("ClassName")); - list.add(model); - } - return list; - } - - public List getZiyuanTree(Integer schoolId,Integer beginNode,Integer levelLimit) { - String url = baseHost + "/BschZyk/oapi/base/nodeTree/get?schoolId=" + schoolId + "&beginNode="+(beginNode==null?"":beginNode)+"&levelLimit="+(levelLimit==null?"":levelLimit); - String cacheKey = RedisConstants.ZY_Tree+".url:"+url ; - System.out.println("资源树请求..."); - List cacheList=new ArrayList<>(); - if (redisUtil.hasKey(cacheKey)) { - Object obj = redisUtil.get(cacheKey); - String jsonStr = JSON.toJSONString(obj); - System.out.println("资源树请求jsonStr="+jsonStr); - cacheList =JSONArray.parseArray(jsonStr, Map.class); - if (cacheList.stream().count() > 0) return cacheList; - } - System.out.println("资源树请求url="+url); - String ret = ""; - try { - Signature.getHeaderMap("", app_key, app_secret); - ret = DHttp.get(url); - } catch (Exception e) { - System.out.println("资源树请求失败="+e.toString()); - throw new DException(false, 1, "资源树请求失败!"); - } - JSONObject json = JSONObject.fromObject(ret); - int code=1; - if(json.containsKey("code")){ - code = json.getInt("code"); - if (code == 0) { - net.sf.json.JSONArray data = json.getJSONArray("data"); - String jsonStr = JSON.toJSONString(data); - cacheList = JSONArray.parseArray(jsonStr, Map.class); - redisUtil.set(cacheKey, cacheList, 8 * 60 * 60); - return cacheList; - } - } - String errMsg = "票据校验失败: " + json.getString("msg"); - throw new DException(false, code, errMsg); - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/HyAIService.java b/src/main/java/com/bestsch/classicalchinese/service/com/HyAIService.java deleted file mode 100644 index fd28962..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/HyAIService.java +++ /dev/null @@ -1,314 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.bestsch.classicalchinese.enums.DifficultLevel; -import com.bestsch.classicalchinese.enums.QuestionType; -import com.bestsch.classicalchinese.model.AiAsk; -import com.bestsch.classicalchinese.model.Example; -import com.bestsch.classicalchinese.utils.OrgJsonUtil; -import com.bestsch.utils.DException; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - - -@Service -public class HyAIService { - - @Value("${bsch.openai.host}") - private String openaiHost; - - @Value("${bsch.openai.max-tokens}") - private int maxTokens; - - @Value("${bsch.openai.temperature}") - private float temperature; - - @Value("${bsch.openai.api-key}") - private String apiKey; - - - public String send(AiAsk aiAsk) { - - String url = openaiHost; - - List> messages = new ArrayList<>(); - Map msg = new HashMap(); - msg.put("role", "user"); - msg.put("content", aiAsk.getPrompt()); - messages.add(msg); - - Map requestBody = new HashMap<>(); - requestBody.put("model", aiAsk.getModel()); - requestBody.put("messages", messages); - requestBody.put("max_tokens", maxTokens); - requestBody.put("temperature", temperature); - - Map requestHeader = new HashMap<>(); - requestHeader.put("Authorization", "Bearer " + apiKey); - requestHeader.put("Content-Type", "application/json"); - - String body = JSON.toJSONString(requestBody); - try { - System.out.println("open AI 提问:" + aiAsk.getPrompt()); - - String responseBody = post(url, body, requestHeader); - JSONObject jsonObject = JSONObject.parseObject(responseBody); - JSONArray choices = jsonObject.getJSONArray("choices"); - String message = choices.getJSONObject(0).getString("message"); - JSONObject content = JSONObject.parseObject(message); - String contentVal = content.getString("content"); - System.out.println("open AI 请求成功!" + contentVal); - return toTextJson(contentVal, "```json", "```"); - - } catch (Exception e) { - System.out.println("open AI 请求失败!" + e.toString()); - throw new DException("open AI 请求失败!"); - //e.printStackTrace(); - } - } - - - private String toTextJson(String text, String s, String e) { - if (text.contains(s) && text.contains(e)) { - int index = text.indexOf(s); - text = text.substring(index + s.length(), text.length()); - index = text.lastIndexOf(e); - text = text.substring(0, index); - } - return text; - } - - private static String post(String url, String body, Map requestHeader) { - try { - // 创建URL对象 - URL urlobj = new URL(url); - // 打开连接 - HttpURLConnection conn = (HttpURLConnection) urlobj.openConnection(); - // 设置请求方法为POST - conn.setRequestMethod("POST"); - // 设置请求头(根据需要) - //conn.setRequestProperty("Content-Type", "application/json;"); - //conn.setRequestProperty("Accept", "application/json"); - if (requestHeader != null) { - for (Map.Entry entry : requestHeader.entrySet()) { - conn.setRequestProperty(entry.getKey(), entry.getValue()); - } - } - - - conn.setDoOutput(true); // 允许写入数据到服务器 - - // 准备要发送的数据(这里以JSON为例) - //String input = "{\"key1\":\"value1\", \"key2\":\"value2\"}"; - // 发送数据到服务器 - try (OutputStream os = conn.getOutputStream()) { - byte[] inputBytes = body.getBytes("utf-8"); - os.write(inputBytes); - } - - // 获取响应代码 - int responseCode = conn.getResponseCode(); - System.out.println("Response Code : " + responseCode); - - // 如果需要,读取响应内容 - try (InputStream responseStream = conn.getInputStream()) { - BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream)); - StringBuilder response = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - response.append(line); - } - reader.close(); - return response.toString(); - } - } catch (Exception e) { - e.printStackTrace(); - throw new DException("网络连接失败"); - } - - } - - - public List getQuestionList(List> list) { - List questionList = new ArrayList<>(); - for (Map map : list) { - String questionTypeName = map.get("type").toString(); - String difficultLevelName = map.get("difficulty").toString(); - - Example question = new Example(); - question.setSolve(map.get("analysis").toString().replace("解析:", "")); - Integer difficultLevelId1 = DifficultLevel.getIdByName(difficultLevelName); - - Integer difficultLevelId = difficultLevelId1 == null ? 4 : difficultLevelId1; - question.setDifficultLevelId(difficultLevelId); -// question.setDifficultLevelName(difficultLevelName); - Integer questionTypeId = QuestionType.getIdByName(questionTypeName); - question.setQuestionTypeId(questionTypeId); -// question.setQuestionTypeName(questionTypeName); - - //难易程度 - Example.DifficultLevel difficultLevel = new Example.DifficultLevel(); - difficultLevel.setId(difficultLevelId); - difficultLevel.setName(DifficultLevel.nameById(difficultLevelId)); - question.setDifficultLevel(difficultLevel); - //题型 - Example.QuestionType questionType = new Example.QuestionType(); - questionType.setId(questionTypeId); - questionType.setName(questionTypeName); - question.setQuestionType(questionType); - - question.setSolveQuestionFiles(new ArrayList<>()); - - String questionName = map.get("question").toString(); - if (QuestionType.I.getName().equals(questionTypeName)) { - //单选题 - String answer = map.get("answer").toString(); - List options = JSONArray.parseArray(JSON.toJSONString(map.get("options")), Map.class); -// List oList = getAnswers(options); - Map map1 = getAnswers(questionName,options); - question.setName(map1.get("name").toString()); - question.setConfig(map1.get("config").toString()); -// question.setConfig("{\"options\":" + JSON.toJSONString(oList) + ",\"fileList\":[[],[],[],[]]}"); - - question.setAnswer("[" + getAnswerPosition(answer) + "]"); - } else if (QuestionType.VI.getName().equals(questionTypeName)) { - //填空题 - question.setName(questionName.replaceAll("_+", "___").replaceAll("( )", "___")); - question.setConfig("{\"options\":[],\"fileList\":[[],[],[],[]]}"); - String answer = JSON.toJSONString(map.get("answer")); - String[][] answers = OrgJsonUtil.getJsonStrig(answer); - if (answers.length == 1) { - question.setAnswer(getTKAnswer1(answers)); - } else { - question.setAnswer(getTKAnswer2(answers)); - } - } else if (QuestionType.IV.getName().equals(questionTypeName)) { - //解答题 - question.setName(questionName); - String answer = map.get("answer").toString(); - question.setConfig("{\"required\":true,\"options\":[],\"fileList\":[]}"); - question.setAnswer("[\"" + answer + "\"]"); - } - questionList.add(question); - } - System.out.println("转换成题库json:" + JSON.toJSONString(questionList)); - return questionList; - } - - public int getAnswerPosition(String answer) { - answer=answer.replace("\"","") - .replace("[","").replace("]",""); - - String[] answers = answer.split(","); - - if(answers.length!=1) - throw new NullPointerException("答案输入不合法"); - - answer=answers[0]; - - char letter = answer.charAt(0); - // 将字符转换为小写(可选) - letter = Character.toLowerCase(letter); - // 计算位置 - int position = letter - 'a'; - return position; - } - private String getTKAnswer1(String[][] answers) { - String[][] newArray = new String[answers[0].length][]; - for (String[] innerArray : answers) { - for (int i = 0; i < innerArray.length; i++) { - newArray[i] = new String[]{innerArray[i]}; - } - } - String s = JSON.toJSONString(newArray); - return s; - } - private String getTKAnswer2(String[][] answers) { - String[][] newArray = new String[answers.length][]; - for (int i = 0; i < answers.length; i++) { - newArray[i] = new String[]{answers[i][0]}; - } - String s = JSON.toJSONString(newArray); - return s; - } - private Map getAnswers(String name,List options) { - List oList = new ArrayList<>(); - int i = 0; - for (Map oMap : options) { - String content; - try { - try { - content = oMap.get("content").toString(); - } catch (Exception ex) { - content = oMap.get("内容").toString(); - } - } catch (Exception e) { - content = oMap.get("option").toString(); - } - - String config = getQuestionOption(name, i); - name = name.replace(config, ""); - if (content != null && StringUtils.isNotEmpty(content)) { - oList.add(content); - } else if (config != null && StringUtils.isNotEmpty(config)) { - config = config.replace("\n" + getChar(i), "").replace(".", "").replace(" ", ""); - oList.add(config); - } - i++; - } - Map map = new HashMap(); - map.put("name", name); - map.put("config", "{\"options\":" + JSON.toJSONString(oList) + ",\"fileList\":[[],[],[],[]]}"); - return map; - } - private String getQuestionOption(String name, int i) { - String result = ""; - int startIndex = name.indexOf("\n" + getChar(i)); // 获取"A"后面一个字符的索引 - int endIndex = name.indexOf("\n" + getChar(i + 1), startIndex); // 获取第一个"."的索引 - if (endIndex != -1) { // 确保找到了"." - result = name.substring(startIndex, endIndex); - } else if (name.contains("\n" + getChar(i))) { - result = name.substring(startIndex); - } - return result; - } -// private Map getQuestionAnswer(String name, int size) { -// List oList = new ArrayList<>(); -// for (int i = 0; i < size; i++) { -// int startIndex = name.indexOf("\n" +getChar(i)); // 获取"A"后面一个字符的索引 -// int endIndex = name.indexOf("。", startIndex); // 获取第一个"."的索引 -// if (endIndex != -1) { // 确保找到了"." -// String result = name.substring(startIndex, endIndex + 1); -// oList.add(result); -// name = name.replace(result, ""); -// System.out.println("第"+i+"轮:"+name); -// } -// } -// Map map = new HashMap(); -// map.put("name",name); -// map.put("config","{\"options\":" + JSON.toJSONString(oList) + ",\"fileList\":[[],[],[],[]]}"); -// return map; -// } - private String getChar(int i){ - String str =""; - if (i > 0 && i <= 25){ - char letter = (char) (i + 'A'); - str = String.valueOf(letter); - } - return str; - } -} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/TeaSchService.java b/src/main/java/com/bestsch/classicalchinese/service/com/TeaSchService.java deleted file mode 100644 index fa12765..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/TeaSchService.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.bestsch.classicalchinese.model.TreeDept; -import com.bestsch.classicalchinese.model.TreeUser; -import com.bestsch.classicalchinese.utils.RedisConstants; -import com.bestsch.classicalchinese.utils.RedisUtil; -import com.bestsch.utils.DHttp; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -@Service -public class TeaSchService { - @Value("${bsch.open.schbase-host}") - private String schHost; - - @Autowired - private RedisUtil redisUtil; - /** - * 获取教师组 - * http://sch.bestsch.com//oapi/OptCourse/getSchoolGroupByschId?id=3704 - */ - public List getSchoolGroupByschId(int schId) { - String url = schHost + "/oapi/OptCourse/getSchoolGroupByschId?id=" + schId; - String ret = DHttp.get(url); - List dept = JSONArray.parseArray(ret, TreeDept.class); - return dept; - } - - public String getSchTeaName(Integer schoolId,Integer TeaId) - { - Optional teaOpt=getSchTeainfoById(schoolId).stream().filter(s->s.getUserID()==TeaId).findFirst(); - return teaOpt.map(TreeUser::getName).orElse(""); - } - - /** - * 获取教师 - * http://sch.bestsch.com/oapi/OATea/GetSchTeainfoById?id=3704 - */ - public List getSchTeainfoById(Integer schoolId) { - String cacheKey = RedisConstants.SCH_TEA+":"+schoolId; - if (redisUtil.hasKey(cacheKey)) { - Object obj = redisUtil.get(cacheKey); - String jsonStr = JSON.toJSONString(obj); - List cacheList = com.alibaba.fastjson.JSONObject.parseArray(jsonStr, TreeUser.class); - if (cacheList.size() > 0) return cacheList; - } - String url = schHost + "/oapi/OATea/GetSchTeainfoById?id=" + schoolId; - String ret = DHttp.get(url); - List list=getTreeUser(ret); - redisUtil.set(cacheKey, list, 8 * 60 * 60); - return list; - } - private List getTreeUser(String ret) { - List user = new ArrayList<>(); - List list = JSONArray.parseArray(ret, Map.class); - for (Map map : list) { - TreeUser _pram = new TreeUser(); - _pram.setUserID((Integer) map.get("UserID")); - _pram.setName((String) map.get("Name")); - try { - _pram.setPhoto((String) map.get("Photo")); - } catch (Exception ex) { - _pram.setPhoto(null); - } - _pram.setGroupID((Integer) map.get("GroupID")); - _pram.setType(2); - _pram.setId((Integer) map.get("UserID")); - - user.add(_pram); - } - return user; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/UploadFileService.java b/src/main/java/com/bestsch/classicalchinese/service/com/UploadFileService.java deleted file mode 100644 index 7f55def..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/UploadFileService.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.bestsch.classicalchinese.Repository.UploadFileRepository; -import com.bestsch.classicalchinese.entity.UploadFile; -import com.bestsch.classicalchinese.utils.OkHttpUtil; -import com.bestsch.classicalchinese.utils.FileUtil; -import okhttp3.MultipartBody; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import java.io.*; -import java.text.SimpleDateFormat; -import java.util.*; -import java.io.File; -import java.io.IOException; - -@Service -public class UploadFileService { - - @Autowired - private UploadFileRepository questFileRepository; - - @Autowired - private OkHttpUtil okHttpUtil; - - @Value("${FILE_PATH}") - private String FILE_PATH; - - @Value("${bsch.oahost}") - private String OA_HOST; - - private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/"); - - public List addFile(MultipartFile[] file, HttpServletRequest request) { - if (file.length > 0) { - String list = "";String format = sdf.format(new Date()); - List mapList = new ArrayList<>(); - for (int i = 0; i < file.length; i++) { - MultipartFile uploadFile = file[i]; - - File folder = new File(FILE_PATH + "/uploadFile/" + format); - if (!folder.isDirectory()) { - folder.mkdirs(); - } - - String oldName = uploadFile.getOriginalFilename(); - String fileSuffix = oldName.substring(oldName.lastIndexOf(".") + 1); -// System.out.println("oldName = " + oldName); - String newUUID=UUID.randomUUID().toString(); - String newName = newUUID + oldName. - substring(oldName.lastIndexOf("."), oldName.length()); - -// System.out.println("newName = " + newName); - try {//保存文件 - uploadFile.transferTo(new File(folder, newName)); - //生成上传文件的访问路径 - String filePath = "/uploadFile/" + format + newName; - Map map = new HashMap(); - map.put("fileUrl",filePath); - map.put("fileName",oldName); - map.put("fileSuffix",fileSuffix); - map.put("fileSize",uploadFile.getSize()); - map.put("duration",0); - mapList.add(map); - - String pdfPath=FILE_PATH + "/uploadFile/" + format+newUUID+".pdf"; - SaveUploadFilePdf(1,FILE_PATH+filePath,pdfPath,fileSuffix); - } catch (IOException e) { - } - } - - return mapList; - } else if (file.length == 0) { - throw new NullPointerException("请选择文件"); - } - throw new NullPointerException("上传失败"); - } - - private String[] fileTypes=new String[]{"docx","doc","xls","xlsx","ppt","pptx","pdf"}; - - public Boolean SaveUploadFilePdf(Integer type,String filePath,String pdfPath,String fileSuffix) { - if(type.equals(1)) - { - if (Arrays.asList(fileTypes).contains(fileSuffix)) { - //判断文件是否存在 - if(existsFile(pdfPath)) return true; - try { - Map fromData = new HashMap(); - fromData.put("file",getFile(filePath)); - //String jsonString = JSONObject.toJSONString(fromData); - //convertToByteArray(stream) - String base64String = okHttpUtil.post(OA_HOST + "/ConversionPdf/api/FromOffice", - null,fromData,null, MultipartBody.FORM); - - byte[] decodedBytes = decodeBase64(base64String); - try (FileOutputStream fos = new FileOutputStream(pdfPath)) { - fos.write(decodedBytes); - } - return true; - } catch (Exception e) { - System.out.println("SaveUploadFilePdf error:"+e.toString()); - } - } - }else { - - - } - return false; - } - - - private static byte[] decodeBase64(String base64String) { - // 如果包含数据URI前缀,则去除 - if (base64String.contains(";base64,")) { - base64String = base64String.split(";base64,")[1]; - } - // 去除任何非Base64字符(如空格、换行等) - base64String = base64String.replaceAll("[^A-Za-z0-9+/=]", ""); - try { - return Base64.getDecoder().decode(base64String); - } catch (IllegalArgumentException e) { - // 如果还是失败,尝试使用Base64.getMimeDecoder(),它可以忽略一些非Base64字符 - // 或者使用Base64.getUrlDecoder()如果是URL安全的编码 - // 根据情况选择 - // 例如:return Base64.getMimeDecoder().decode(base64String); - throw new RuntimeException("Failed to decode base64 string", e); - } - } - - private static InputStream getFileStreamUsingFileInputStream(String absolutePath) throws IOException { - File file = new File(absolutePath); - if (!file.exists() || !file.isFile()) { - throw new IOException("文件不存在或不是有效文件: " + absolutePath); - } - return new FileInputStream(file); - } - - private File getFile(String absolutePath) throws IOException { - File file = new File(absolutePath); - if (!file.exists() || !file.isFile()) { - throw new IOException("文件不存在或不是有效文件: " + absolutePath); - } - return file; - } - private Boolean existsFile(String absolutePath){ - File file = new File(absolutePath); - if (!file.exists() || !file.isFile()) - return false; - else - return true; - } - - - private static byte[] convertToByteArray(InputStream inputStream) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - int nRead; - byte[] data = new byte[1024 * 4]; // 4KB的缓冲区 - while ((nRead = inputStream.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, nRead); - } - buffer.flush(); - return buffer.toByteArray(); - } - - public void delete(Integer id) { - - UploadFile questionFile = questFileRepository.findById(id).get(); - if(questionFile!=null) { - String fileName = questionFile.getFileUrl(); - if (!StringUtils.isEmpty(fileName)) - FileUtil.deleteFile(new File(FILE_PATH + "/optionFile/" + fileName)); - String screenFileName = questionFile.getScreenFileName(); - if (!StringUtils.isEmpty(screenFileName)) - FileUtil.deleteFile(new File(FILE_PATH + "/optionFile/" + screenFileName)); - - questFileRepository.deleteInBatch(Arrays.asList(questionFile)); - } - - - } - public UploadFile findById(Integer id) { - return questFileRepository.findById(id).get(); - } - public UploadFile save(UploadFile questionFile) { - return questFileRepository.save(questionFile); - } - - public List save(List questionFile) { - return questFileRepository.saveAll(questionFile); - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/UserGradeClassSubService.java b/src/main/java/com/bestsch/classicalchinese/service/com/UserGradeClassSubService.java deleted file mode 100644 index a64b598..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/UserGradeClassSubService.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.bestsch.openapi.BoaUser; -import com.bestsch.openapi.BschBaseOpenApi; -import com.bestsch.classicalchinese.model.*; -import com.bestsch.utils.LocalMemCache; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class UserGradeClassSubService { - - private LocalMemCache localMemCache = new LocalMemCache(); - - @Autowired - private ClassService classService; - - @Autowired - private BschBaseOpenApi bschBaseOpenApi; - - - //年级 班级 学科 role 1教师 3学生 7管理员 2校领导 班主任 - // 学生 当前年级班级 全部学科 - //1教师 任教班级任教学科 - //班主任 当前班级 - public List GetList(Integer role, Integer userId, int schId) - { - String key="UserGradeClassSub_"+userId+"_"+schId; - List ulist = (List) localMemCache.get(key); - if (ulist != null&&ulist.size()>0) - return ulist; - - BoaUser user= bschBaseOpenApi.getUserInfo(userId); - List roleIds= user.getRoleIds(); - - Set list = new HashSet<>(); - List allGradeList=classService.getGradeListBySchoolId(schId); - List allTeaClassSubList=classService.getAllClassSubject(schId); - List allClassIds=allTeaClassSubList.stream().map(s->Integer.parseInt(s.get("classId").toString())).distinct().collect(Collectors.toList()); - - Map allclassInfoMao=classService.getClassInfoMap(allClassIds); - List allclassInfoList=new ArrayList<>(); - for (Map.Entry entry : allclassInfoMao.entrySet()) { - allclassInfoList .add(entry.getValue()); - } - if(roleIds.contains(7)||roleIds.contains(2)) - { - for (Map map:allTeaClassSubList) { - Integer gradeId=Integer.parseInt(map.get("gradeId").toString()); - Optional GradeOpt=allGradeList.stream().filter(s->s.getId().equals(gradeId)).findFirst(); - - UserGradeClassSub tmp=new UserGradeClassSub(); - tmp.setGradeId(GradeOpt.isPresent()?GradeOpt.get().getGradeId():0); - if(tmp.getGradeId()>0) - { - tmp.setClassId(Integer.parseInt(map.get("classId").toString())); - tmp.setSubId(map.get("subId").toString()); - if(!list.contains(tmp)) - list.add(tmp); - } - } - } - else if( roleIds.contains(1)) - { - //任教和班主任 - List teaClassSubList= allTeaClassSubList.stream().filter(s->s.get("teaId").toString().equals(userId.toString())).collect(Collectors.toList()); - - for (Map map:teaClassSubList) { - Integer gradeId=Integer.parseInt(map.get("gradeId").toString()); - Optional GradeOpt=allGradeList.stream().filter(s->s.getId().equals(gradeId)).findFirst(); - - UserGradeClassSub tmp=new UserGradeClassSub(); - tmp.setGradeId(GradeOpt.isPresent()?GradeOpt.get().getGradeId():0); - if(tmp.getGradeId()>0) - { - tmp.setClassId(Integer.parseInt(map.get("classId").toString())); - tmp.setSubId(map.get("subId").toString()); - if(!list.contains(tmp)) - list.add(tmp); - } - } - - List bzrClassList= allclassInfoList.stream().filter(s->s.getTeacherId().equals(userId)).collect(Collectors.toList()); - for (ClassInfo cla:bzrClassList) - { - //获取班级任教科目 - List subIds= allTeaClassSubList.stream().filter(s->s.get("classId").toString().equals(cla.getClassId().toString())) - .map(s->s.get("subId").toString()).distinct().collect(Collectors.toList()); - - for (String subId:subIds){ - UserGradeClassSub tmp=new UserGradeClassSub(); - tmp.setGradeId(cla.getGradeId()); - tmp.setClassId(cla.getClassId()); - tmp.setSubId(subId); - if(!list.contains(tmp)) - list.add(tmp); - } - } - - //判断教师是否是年级组长 - Map> gradegroupMap= classService.getSchGradeGroup(schId); - for (Grade grade:allGradeList){ - if(gradegroupMap.containsKey(grade.getGradeId())) - { - if(gradegroupMap.get(grade.getGradeId()).contains(userId)) - { - List gradeClassSubList= allTeaClassSubList.stream().filter(s->s.get("gradeId").toString().equals(grade.getId().toString())).collect(Collectors.toList()); - for (Map map:gradeClassSubList) { - UserGradeClassSub tmp=new UserGradeClassSub(); - tmp.setGradeId(grade.getGradeId()); - tmp.setClassId(Integer.parseInt(map.get("classId").toString())); - tmp.setSubId(map.get("subId").toString()); - if(!list.contains(tmp)) - list.add(tmp); - } - } - } - } - - //学科组 - List subgroupList=classService.getSchSubGroup(schId); - List teasubgroupList=subgroupList.stream().filter(s->s.getTeaIds().contains(userId)).collect(Collectors.toList()); - - if(teasubgroupList.size()>0) - { - for (Map map: allTeaClassSubList) - { - String gradeIdstr=map.get("gradeId").toString(); - Optional GradeOpt=allGradeList.stream().filter(s->s.getId().toString().equals(gradeIdstr)).findFirst(); - - Integer gradeId=GradeOpt.isPresent()?GradeOpt.get().getGradeId():0; - if(teasubgroupList.stream().filter(s->s.getSubIds().contains(map.get("subId").toString())&&s.getGradeIds().contains(gradeId)).count()>0) - { - UserGradeClassSub tmp=new UserGradeClassSub(); - tmp.setSubId(map.get("subId").toString());; - tmp.setGradeId(gradeId);; - tmp.setClassId(Integer.parseInt(map.get("classId").toString()));; - if(!list.contains(tmp)) - list.add(tmp); - } - - } - - } - } - else if(role==3) - { - - } - - ulist=new ArrayList<>(list); - localMemCache.cache(key, ulist, 2*60*1000); - return ulist; - } - - - public boolean exists(List list,Integer classId) - { - List listwhere=new LinkedList<>(list); - boolean exs=false; - - if(classId!=null) - listwhere=listwhere.stream().filter(s->s.getClassId().equals(classId)).collect(Collectors.toList()); - - exs=listwhere.size()>0; - return exs; - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/com/ZiyuankuService.java b/src/main/java/com/bestsch/classicalchinese/service/com/ZiyuankuService.java deleted file mode 100644 index c45ed7e..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/com/ZiyuankuService.java +++ /dev/null @@ -1,275 +0,0 @@ -package com.bestsch.classicalchinese.service.com; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.bestsch.classicalchinese.config.FileConfig; -import com.bestsch.classicalchinese.utils.RedisUtil; -import com.bestsch.utils.BschUtils; -import com.bestsch.utils.DHttp; -import com.bestsch.utils.LocalMemCache; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Service -public class ZiyuankuService -{ - @Value("${bsch.open.zyk-host}") - private String zykHost; - - @Autowired - private FileConfig fileConfig; - - @Autowired - private RedisUtil redisUtil; - private LocalMemCache localMemCache = new LocalMemCache(); - private static final String zuoye_key = "bsch_punit"; - private static final String chapt_course_key = zuoye_key + "_bsch_course_chapter_"; - private static final String chapt_textbook_key = zuoye_key + "_bsch_textbook_"; - private static final String chapt_knowledgetree_key = zuoye_key + "_bsch_knowledgetree_"; - private static final String chapt_textbookInfo_key = zuoye_key + "_bsch_textbookInfo_"; - - - public Object getCourseTree_cache(Integer schId,Integer grade,Integer year,Integer term,String subjectId) { - String key = chapt_course_key + schId + "_" + grade + "_" + year + "_" + term + "_" + subjectId; - List list = redisUtil.lGet(key, 0, -1); - if (BschUtils.isNotEmpty(list)) - return list.get(0); - else { - List mapList = getCourseTree(schId, grade, year, term, subjectId); - if (mapList != null && mapList.size() > 0) - redisUtil.lSet(key, mapList, 600); - List list2 = redisUtil.lGet(key, 0, -1); - if (BschUtils.isNotEmpty(list2)) - return list2.get(0); - else if(mapList.stream().count()>0) - return mapList; - } - return new ArrayList<>(); - } - - public List getNodeList(List courseTrees,Integer nodeId) - { - List NodeList=new ArrayList(); - courseTrees.stream().map(item-> { - Map map = new HashMap<>(); - map.put("id", item.get("id")); - map.put("name", item.get("name")); - map.put("pid", nodeId); - if (item.get("children") != null) { - List children1 = JSONArray.parseArray(JSON.toJSONString(item.get("children")), Map.class); - NodeList.addAll(getNodeList(children1, Integer.parseInt(item.get("id").toString()))); - } - NodeList.add(map); - return NodeList; - }).collect(Collectors.toList());; - return NodeList; - } - - /** - * 获取当前课程树 - * https://base.bestsch.com/BschZyk/oapi/base/getCourseTree?schoolId=3260&grade=10&academicYear=2024&semester=1&subject=SUB01 - */ - public List getCourseTree(Integer schId,Integer grade,Integer year,Integer term,String subjectId) { - String resp = DHttp.get(zykHost + "/oapi/base/getCourseTree?schoolId=" + schId + "&grade=" + grade + "&academicYear=" + year + "&semester=" + term + "&subject=" + subjectId+"&sourceType=2"); - return getMapList(resp); - } - - - private List getMapList(String resp){ - Map json = JSONObject.parseObject(resp, Map.class); - List list = new ArrayList<>(); - if ((Integer) json.get("code") == 0 && json.get("data") != null) { - list = JSONArray.parseArray(JSON.toJSONString(json.get("data")), Map.class); - } - return list; - } - - - /** - * 获取学科年级 - * https://base.bestsch.com/BschZyk/oapi/base/getCourseNodeSelectionList?schoolId=3260&academicYear= - */ - public List getCourseNodeSelectionList(Integer schId,Integer year) { - String key = "getCourseNodeSelectionList_schId_" + schId + "_year_" + year; - List data = (List)localMemCache.get(key); - if (data != null) { - return data; - } - String url = zykHost + "/oapi/base/getCourseNodeSelectionList?schoolId=" + schId; - if (year != null) - url += "&academicYear=" + year; - String resp = DHttp.get(url); - - List lists = getMapList(resp); - if (lists != null && lists.size()>0) - { - localMemCache.cache(key, lists, 24 * 60 * 60 * 1000); - } - - return lists; - } - - - /** - * 根据某个节点id,获取视频 - * https://base.bestsch.com/BschZyk/oapi/base/getResourceByNodeId?schoolId=3260&userId=209169&roleId=1&nodeId=2766&resourceType=2&pageIndex=1&pageSize=40 - */ - public Map getResourceByNodeId(Integer schId,Integer userId,Integer roleId,Integer nodeId,Integer page,Integer count) { - String url = zykHost + "/oapi/base/getResourceByNodeId?schoolId=" + schId + "&userId=" + userId + "&roleId=" + roleId + "&nodeId=" + nodeId + "&resourceType=&pageIndex=" + page + "&pageSize=" + count; - String resp = DHttp.get(url); - - Map json = JSONObject.parseObject(resp, Map.class); - Map data = new HashMap(); - if ((Integer) json.get("code") == 0 && json.get("data") != null) { - data = JSONArray.parseObject(JSON.toJSONString(json.get("data")), Map.class); - } - return data; - } - - /** - * 获取知识章节返回2个节点 - * https://base.bestsch.com/BschZyk/api/node/tree/v2?schoolSid=3260&userId=209169&authorityType=ZYLR&levelLimit=2&beginNode=2584 - */ - public List getChapterNew2(Integer schId, Integer userId, Integer chapterId, Integer type) - { - String key = "getChapterNew2_schId_" + schId + "_userId_" + userId + "_chapterId_" + chapterId + "_type_" + type; - List data = (List)localMemCache.get(key); - if (data != null && data.size()>0) { - return data; - } - - String url = zykHost + "/api/node/tree/v2?schoolSid=" + schId + "&userId=" + userId + "&levelLimit=2"; - if (type != null && type.equals(1)) { - url += "&authorityType=ZYLR";// 资源录入权限 - } - if (chapterId != null) { - url += "&beginNode=" + chapterId; - } - String res = DHttp.get(url); - - Map map = JSONObject.parseObject(res,Map.class); - String result = String.valueOf(map.get("data")); - if (!"null".equals(result)) { - localMemCache.cache(key, map.get("data"), 5 * 60 * 1000); - return JSONArray.parseArray(JSON.toJSONString(map.get("data")),Map.class); - } - return new ArrayList<>(); - } - - public void syncZiYuanData(Integer schId,Integer userId, Integer nodeId,String zykType, String fileUrl,String fileName) { - try { - String fileUrls = fileConfig.getWebPath() +fileUrl; - - String url = zykHost + "/oapi/other/SyncResource"; - - Map param = new HashMap<>(); - param.put("type",zykType); - param.put("nodeId", nodeId.toString()); - param.put("userId", userId.toString()); - param.put("schoolId",schId.toString()); - param.put("filename", fileName); - Map streamMap = new HashMap<>(); - streamMap.put("file",getVideoStream(fileUrls)); -// System.out.println("streamMap==========="+JSON.toJSONString(streamMap)); - String res = DHttp.formUploadStream(url, param,streamMap); - - System.out.println("res============="+res); - Map map = JSONObject.parseObject(res, Map.class); - - if ((Integer) map.get("code") != 0) { - throw new NullPointerException("同步资源库失败:" + res); - } - }catch (Exception e){ - throw new NullPointerException("同步资源库报错:" + e); - } - } - private static InputStream getVideoStream(String videoUrl) throws Exception { - URL url = new URL(videoUrl); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setConnectTimeout(3000); - conn.setRequestProperty("User-Agent", "Mozilla/4.0"); - return conn.getInputStream(); - } - - //https://base.bestsch.com/BschZyk/oapi/base/getGradeTextbookAll?grade=10 - - public List getGradeTextbookAll(Integer grade) { - String key = chapt_textbook_key + grade; - List data = (List)localMemCache.get(key); - if (data != null && data.size()>0) { - return data; - } - - String res = DHttp.get(zykHost + "/oapi/base/getGradeTextbookAll?grade=" + grade); - Map map = JSONObject.parseObject(res,Map.class); - String result = String.valueOf(map.get("data")); - if (!"null".equals(result)) { - Map dataMap = JSONObject.parseObject(result,Map.class); - String dataListStr = String.valueOf(dataMap.get("dataList")); - if (!"null".equals(dataListStr)&&!"[]".equals(dataListStr)) - { - localMemCache.cache(key, dataMap.get("dataList"), 24 * 60 * 60 * 1000); - return JSONArray.parseArray(JSON.toJSONString(dataMap.get("dataList")),Map.class); - } - } - return new ArrayList<>(); - } - -//https://base.bestsch.com/BschZyk/oapi/base/getKnowledgeTree?textbookId=19 - private List getKnowledgeTree(Integer textbookId) { - String resp = DHttp.get(zykHost + "/oapi/base/getKnowledgeTree?textbookId=" + textbookId); - return getMapList(resp); - } - - public List getKnowledgeTree_cache(List textbookIds) { - - List maps=new ArrayList<>(); - if(textbookIds.stream().count()==0) return maps; - for (Integer textbookId:textbookIds) { - String key = chapt_knowledgetree_key+ textbookId; - List data = (List)localMemCache.get(key); - if (data != null) { - return data; - } - data=getKnowledgeTree(textbookId); - if (data != null && data.size()>0) - { - localMemCache.cache(key, data, 5 * 60 * 1000); - } - maps.addAll(data); - } - return maps; - } - - - public Map getTextbookInfo(Integer textbookId) - { - String key = chapt_textbookInfo_key+ textbookId; - Map data = (Map)localMemCache.get(key); - if(data!=null) - return data; - - String url = zykHost + "/oapi/base/findTextBookById?id=" + textbookId; - String resp = DHttp.get(url); - Map json = JSONObject.parseObject(resp, Map.class); - if ((Integer) json.get("code") == 0 && json.get("data") != null) { - data = JSONObject.parseObject(JSON.toJSONString(json.get("data")), Map.class); - } - if (data != null) - { - localMemCache.cache(key, data, 5 * 60 * 1000); - } - return data; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/BschExplanationService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/BschExplanationService.java deleted file mode 100644 index fae191f..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/BschExplanationService.java +++ /dev/null @@ -1,284 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.bestsch.classicalchinese.Repository.BschVideoExplanationRepository; -import com.bestsch.classicalchinese.entity.BschVideoExplanation; -import com.bestsch.classicalchinese.service.IBschExplanationService; -import com.bestsch.classicalchinese.service.com.BaseComService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.com.UploadFileService; -import com.bestsch.utils.DException; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class BschExplanationService implements IBschExplanationService { - -// @Value("${FILE_PATH}") -// private String FILE_PATH; - - @Value("${FILE_WEB_PATH}") - private String FILE_WEB_PATH; - @Autowired - private BschVideoExplanationRepository bschVideoExplanationRepository; - - @Autowired - private BaseComService baseComService; - @Autowired - private ClassService classService; - // @Autowired - // private ZiyuankuService ziyuankuService; - @Autowired - private UploadFileService uploadFileService; - - - public List findTextBookAll(Integer textbookId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return bschVideoExplanationRepository.findAll(specification); - } - - /** - * 讲解--列表 - */ - @Override - public Object getExplanationList(int textbooId, int userId, Integer nodeId, Pageable pageable) { - Page lists = bschVideoExplanationRepository.findPageBySchIdAndNodeId(textbooId, nodeId, pageable); - - Map data = new HashMap<>(); - data.put("list", getVideoMapList(lists.getContent(), textbooId)); - data.put("count", lists.getTotalElements()); - return data; - } - - @Override - public Object pdfPreview(Integer id) { - BschVideoExplanation file = bschVideoExplanationRepository.getAllById(id); - if(file==null) throw new DException("附件不存在!"); - - String filePath=baseComService.getFilePath(file.getType(),file.getFileUrl()); - String pdfPath=filePath.replace("."+file.getSuffixName(),".pdf"); - - boolean existsfile= uploadFileService.SaveUploadFilePdf(file.getType(),filePath,pdfPath,file.getSuffixName()); - - if(!existsfile) throw new DException("附件不存在!"); - else return FILE_WEB_PATH+pdfPath; - } - - public List getVideoMapList(List lists, Integer textbookId) { - List mapList = new ArrayList<>(); - List teaList = classService.getSchteaList(textbookId); - for (BschVideoExplanation pram : lists) { - - String filePath=baseComService.getFilePath(pram.getType(),pram.getFileUrl()); - String pdfPath=filePath.replace("."+pram.getSuffixName(),".pdf"); - Boolean pdfreview= uploadFileService.SaveUploadFilePdf(pram.getType(),filePath,pdfPath,pram.getSuffixName()); - - Map map = new HashMap(); - map.put("id", pram.getId()); - map.put("name", pram.getName()); - map.put("createTime", pram.getCreateTime()); - map.put("createUserName", getTeaName(teaList, pram.getCreateUser())); - map.put("createUser", pram.getCreateUser()); - map.put("size", pram.getSize()); - map.put("fileUrl", baseComService.getFileUrl(pram.getType(), pram.getFileUrl())); - map.put("nodeId", pram.getNodeId()); - map.put("suffixName", pram.getSuffixName()); - map.put("preview",pdfreview); - map.put("previewUrl",pdfreview?baseComService.getFileUrl(pram.getType(), pram.getFileUrl()).replace("."+pram.getSuffixName(),".pdf"):""); - mapList.add(map); - } - return mapList; - } - - public String getTeaName(List teaList, Integer teaId) { - String teaName = ""; - List teaList1 = teaList.stream().filter(x -> Objects.equals(x.get("UserTeaSerID").toString(), teaId.toString())).collect(Collectors.toList()); - if (teaList1 != null && teaList1.size() > 0) { - teaName = teaList1.get(0).get("TeaName").toString(); - } - return teaName; - } - - - /** - * 讲解--添加 - */ - @Override - public void saveExplanation(int userId, List list) { - List lists = new ArrayList<>(); - for (BschVideoExplanation pram : list) { - if (pram.getNodeId() == null) throw new NullPointerException("请选择知识树节点"); - pram.setCreateUser(userId); - pram.setCreateTime(new Date()); - lists.add(pram); - } - if (lists != null && lists.size() > 0) { - bschVideoExplanationRepository.saveAll(lists); - BschVideoExplanation model = list.get(0); - if (model.getType() == 1 && model.getIsSyncResource() == 1) { - //todo 同步到资源 - } - } - } - - @Override - public void saveExplanation1(int userId, Map map) { - if (map != null) { - if (map.get("nodeId") == null) throw new NullPointerException("请选择知识树节点"); - - Integer nodeId = Integer.valueOf(map.get("nodeId").toString()); - Integer gradeId = Integer.valueOf(map.get("gradeId").toString()); - String subjectId = (String) map.get("subjectId"); - Integer textbookId = Integer.valueOf(map.get("textbookId").toString()); - String path = (String) map.get("path"); - Integer type = Integer.valueOf(map.get("type").toString()); - - Integer isSyncResource = 0; - String zykType = null; - if (type == 1) { - isSyncResource = Integer.valueOf(map.get("isSyncResource").toString()); - if (isSyncResource == 1) { - zykType = (String) map.get("zykType"); - } - } - - List files = JSONArray.parseArray(JSON.toJSONString(map.get("fils")), Map.class); -// System.out.println("files================="+JSON.toJSONString(files)); - List lists = new ArrayList<>(); - for (Map file : files) { - BschVideoExplanation pram = new BschVideoExplanation(); - pram.setNodeId(nodeId); - pram.setPath(path); - pram.setIsSyncResource(isSyncResource); - pram.setType(type); - - String fileUrl = file.get("downUrl").toString(); - String fileName = file.get("name").toString(); - String suffixName = file.get("suffixName").toString(); - pram.setName(fileName); - pram.setFileUrl(fileUrl); - pram.setSize(file.get("size").toString()); - pram.setSuffixName(suffixName); - pram.setDuration(Long.valueOf(0)); - Integer fileUserId=Integer.valueOf(file.get("userId").toString()); - - pram.setCreateUser(fileUserId); - pram.setTextbookId(textbookId); - pram.setCreateTime(new Date()); - lists.add(pram); - - if (pram.getType() == 1 && pram.getIsSyncResource() == 1) { - //同步到资源 - //ziyuankuService.syncZiYuanData(schId, userId, pram.getNodeId(), zykType, fileUrl,fileName+suffixName); - } - } - if (lists != null && lists.size() > 0) { - bschVideoExplanationRepository.saveAll(lists); - } - } - } - - /** - * 讲解--删除 - */ - @Override - public void deleteExplanation(int userId, Integer id) { - Integer ids = bschVideoExplanationRepository.getIdByIdAndUserId(id,userId); - if (ids != null) { - bschVideoExplanationRepository.deleteAllById(id); - } else throw new NullPointerException("您没有删除该讲解的权限!"); - } - - - -// /** -// * 从资源库选择--知识树 -// */ -// @Override -// public Object getZYKSubjectTree(int schId, int userId, Integer nodeId) { -// List list = (List) ziyuankuService.getChapterNew2(schId, userId, nodeId, null); -// return list; -// } - -// @Override -// public Object getZYKSubjectTree(int textbookId, int userId, Integer nodeId) { -// List list = ziyuankuService.getChapterNew2(textbookId, userId, nodeId, null); -// return getChildren(list,1); -// } - - private List getChildren(List children,int type) { - return children.stream() - .map(child -> { - Map map = new HashMap(); - map.put("id", child.get("id")); - map.put("title", child.get("name")); - if(child.get("isParent").toString().equals("true")) - map.put("loading",false); - map.put("path", child.get("path")); - map.put("level", child.get("level")); - map.put("schoolSid", child.get("schoolSid")); - map.put("originKnowledge", child.get("originKnowledge")); - map.put("localLevel", child.get("localLevel")); - map.put("parentId", child.get("parentId")); - - Boolean expand = false; - if (type == 1) expand = true; - map.put("expand", expand); - - if (child.get("children") != null) { - List children1 = JSONArray.parseArray(JSON.toJSONString(child.get("children")), Map.class); - map.put("children", getChildren(children1,2)); - } else map.put("children", new ArrayList<>()); - return map; - }).collect(Collectors.toList()); - } - - - /** - * 从资源库选择--视频列表 - */ -// @Override -// public Object getZYKVideoList(int textbookId, int userId, int roleId, Integer nodeId, Integer page, Integer count) { -// Map dMap = ziyuankuService.getResourceByNodeId(textbookId, userId, roleId, nodeId, page, count); -// -// -// List mapList = new ArrayList<>(); -// if (dMap.get("dataList") != null) { -// List lists = JSONArray.parseArray(JSON.toJSONString(dMap.get("dataList")), Map.class); -// mapList = getZYKVideoMapList(lists); -// } -// Map data = new HashMap<>(); -// data.put("list", dMap.get("dataList")); -// data.put("count", dMap.get("maxNum")); -// return data; -// } - - private List getZYKVideoMapList(List lists){ - List mapList = new ArrayList<>(); - for (Map pram:lists){ - Map map = pram; - map.put("fileUrl",(String)pram.get("savePath")+pram.get("serialNum")+pram.get("suffixName")); - map.put("duration",pram.get("duration")==null?0:pram.get("duration")); - mapList.add(map); - } - return mapList; - } - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/BschKnowledgeService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/BschKnowledgeService.java deleted file mode 100644 index a9f4a82..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/BschKnowledgeService.java +++ /dev/null @@ -1,875 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.BschKnowledgeRepository; -import com.bestsch.classicalchinese.entity.BschKnowledge; -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.classicalchinese.enums.SourceEnum; -import com.bestsch.classicalchinese.service.IBschKnowledgeService; -import com.bestsch.classicalchinese.utils.DicUtil; -import com.bestsch.classicalchinese.utils.JavaBeanUtil; -import com.bestsch.openapi.BoaUser; -import com.bestsch.utils.DException; -import com.bestsch.utils.ErrorCode; -import com.bestsch.utils.LocalMemCache; -import com.bestsch.utils.Utils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * @ Description : java类作用描述 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:42 - * @ Company : bestsch - */ -@Service -public class BschKnowledgeService implements IBschKnowledgeService { - - @Autowired - private BschKnowledgeRepository knowledgeRepo;; - - @Autowired - private BschTextbookService textbookService; - - private LocalMemCache localMemCache = new LocalMemCache(); - - @Override - @Transactional(rollbackFor = Exception.class) - public BschKnowledge add(BschKnowledge knowledge) { - return knowledgeRepo.save(knowledge); - } - -// @Override -// @Transactional(rollbackFor = Exception.class) -// public Map getOrCreateTreeForApi(int textbookId,String source){ -// if(SourceEnum.SCHOOL.getEnKey().equals(source)){ -// return getTreeOfSchoolForApi(textbookId); -// }else { -// return getTreeOfSystemForApi(textbookId); -// } -// } - - @Override - public Map getTreeForApi(int knowledgeId){ - BschKnowledge knowledge = knowledgeRepo.getById(knowledgeId); - return this.createTreeForApi(knowledge); - } - -// knowledge @Override -// @Transactional(rollbackFor = Exception.class) -// public BschKnowledge getOrCreateRootOfSystem(int bookId) { -// //首先查询当前教材有没有根知识节点 -// Textbook book = textbookService.getOne(bookId); -// Knowledge flag = null; -// if(book.getTreeId() != null){ -// flag = knowledgeRepo.getById(book.getTreeId()); -// } -// //若没有,创建一个 -// if(book.getTreeId() == null || flag == null){ -// Knowledge root = new Knowledge(); -// root.setName(book.getName()); -// root = knowledgeRepo.save(root); -// book.setTreeId(root.getId()); -// textbookService.saveAndFlush(book); -// return root; -// } -// return flag; -// } -// -// @Override -// @Transactional(rollbackFor = Exception.class) -// public Map getOrCreateTree(int textbookId) { -// return this.getTreeOfSystem(textbookId); -// } -// -// @Override -// @Transactional(rollbackFor = Exception.class) -// public Map getOrCreateTree2(int schoolSid,int textbookId,String source) { -// if (SourceEnum.SCHOOL.getEnKey().equals(source)) { -// return this.getTreeOfSchool2(schoolSid,textbookId); -// }else { -// return this.getTreeOfSystem2(schoolSid,textbookId); -// } -// } - - @Override - @Transactional(rollbackFor = Exception.class) - public BschKnowledge addKnowledge(int parentId, String name) { - BschKnowledge parent = knowledgeRepo.getById(parentId); - BschKnowledge knowledge = new BschKnowledge(); - knowledge.setPath(parent.getPath() + parent.getId() + ","); - knowledge.setName(name); - knowledge.setLevel(parent.getLevel() + 1); - knowledge.setParentId(parentId); - //获取同层级所有的知识节点,总大小用作新增的知识节点的排序码 - List knowledges = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(parentId); - if(knowledges != null && !knowledges.isEmpty()){ - knowledge.setOrderCode(knowledges.size()); - }else{ - knowledge.setOrderCode(0); - } - knowledgeRepo.saveAndFlush(knowledge); - return knowledge; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void delKnowledge(int id) { - BschKnowledge knowledge = knowledgeRepo.getById(id); - if(knowledge == null){ - throw new DException(DicUtil.ERROR_MSG_NOT_FOUND); - } - //删除该节点,需要把排序在这个节点之后的节点排序码-1 - List knowledges = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(knowledge.getParentId()); - BschKnowledge last = knowledges.get(knowledges.size() - 1); - List section = this.selectKnowledgeInOrderSection(knowledge.getParentId(),knowledge.getOrderCode(), DicUtil.SECTION_NO_INCLUDE,last.getOrderCode(), DicUtil.SECTION_INCLUDE); - if(section != null && !section.isEmpty()){ - for(BschKnowledge k : section){ - k.setOrderCode(k.getOrderCode() - 1); - } - knowledgeRepo.saveAll(section); - } - knowledgeRepo.deleteById(id); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public BschKnowledge setKnowledge(int id, BschKnowledge knowledge) { - BschKnowledge old = knowledgeRepo.getById(id); - if(old == null){ - throw new DException(DicUtil.ERROR_MSG_NOT_FOUND); - } - if(StringUtils.isNotBlank(knowledge.getName())){ - old.setName(knowledge.getName()); - } - if(knowledge.getOrderCode() != null){ - old.setOrderCode(knowledge.getOrderCode()); - } - return knowledgeRepo.saveAndFlush(old); - } - - @Override - public List getAllChildWithSelf(int id) { - BschKnowledge knowledge = knowledgeRepo.getById(id); - List childs = knowledgeRepo.getAllByPathLikeOrderByOrderCodeAsc(knowledge.getPath() + knowledge.getId() + ",%"); - List list = new ArrayList<>(); - list.add(knowledge); - list.addAll(childs); - return list; - } - - - -// @Override -// @Transactional(rollbackFor = Exception.class) -// public void shareAllToSchoolForOtherSystem(int schoolSid, int userId, String resourceIds, int grade, -// int semester, String subject, int knowledgeId,int schoolBookId) { -// String[] ids = resourceIds.split(","); -// for(String idStr : ids){ -// this.shareToSchoolForOtherSystem(schoolSid,userId,Integer.valueOf(idStr), -// grade,semester,subject,knowledgeId,schoolBookId); -// } -// } - - @Override - public String getIdPath(int knowledgeId, String separator) { - BschKnowledge knowledge = knowledgeRepo.getById(knowledgeId); - return knowledge.getPath() + knowledgeId; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void setOrder(int id, int replaceId) { - BschKnowledge knowledge = knowledgeRepo.getById(id); - BschKnowledge replaceKnowledge = knowledgeRepo.getById(replaceId); - //不能跨层级移动 - if(!knowledge.getParentId().equals(replaceKnowledge.getParentId())){ - throw new DException(DicUtil.ERROR_NO_LEVEL); - } - //当修改位置将数据从x移动到y时,若x小于y,则将(x,y]范围内的数据序号都减1;若x大于y,则将[y,x)范围内的数据序号都加1 - int x = knowledge.getOrderCode(); - int y = replaceKnowledge.getOrderCode(); - if(x - y < 0){ - List list = this.selectKnowledgeInOrderSection(knowledge.getParentId(),x, DicUtil.SECTION_NO_INCLUDE,y, DicUtil.SECTION_INCLUDE); - for(BschKnowledge k : list){ - k.setOrderCode(k.getOrderCode() - 1); - } - knowledge.setOrderCode(y); - list.add(knowledge); - knowledgeRepo.saveAll(list); - }else { - List list = this.selectKnowledgeInOrderSection(knowledge.getParentId(),y, DicUtil.SECTION_INCLUDE,x, DicUtil.SECTION_NO_INCLUDE); - for(BschKnowledge k : list){ - k.setOrderCode(k.getOrderCode() + 1); - } - knowledge.setOrderCode(y); - list.add(knowledge); - knowledgeRepo.saveAll(list); - } - } - - @Override - public List selectKnowledgeInOrderSection(int parentId, int begin, int flag1, int end, int flag2) { - List knowledges = knowledgeRepo.getSection(parentId,begin,end); - if(knowledges == null - || knowledges.isEmpty() - || knowledges.size() == 0){ - return knowledges; - } - if(DicUtil.SECTION_NO_INCLUDE == flag1){ - knowledges.remove(0); - } - if(DicUtil.SECTION_NO_INCLUDE == flag2){ - if(knowledges.size() != 0){ - knowledges.remove(knowledges.size() - 1); - } - } - return knowledges; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public BschKnowledge createRoot(String name) { - BschKnowledge knowledge = new BschKnowledge(); - knowledge.setName(name); - return knowledgeRepo.save(knowledge); - } - - @Override - public BschKnowledge get(int id) { - return knowledgeRepo.getById(id); - } - - - - private List> createTreeForExcel(List> contents, int level, List> child){ - if(contents == null){ - contents = new ArrayList<>(); - } - if(child == null || child.isEmpty()){ - return contents; - } - for(Map map : child){ - List content = new ArrayList<>(); - for(int i=0; i> childs = (List>) map.get("child"); - contents = this.createTreeForExcel(contents,level+1,childs); - } - return contents; - } - - @Override - public BschKnowledge getRoot(int id){ - BschKnowledge knowledge = knowledgeRepo.getById(id); - if(knowledge != null){ - String path = knowledge.getPath(); - //根节点本身是没有path的,所以直接返回 - if(StringUtils.isBlank(path)){ - return knowledge; - } - //path的第一个id即为根节点的id - String[] ids = path.split(","); - Integer rootId = Integer.valueOf(ids[0]); - return knowledgeRepo.getById(rootId); - } - return null; - } - - /** - * 获取知识节点名称路径 - * @param knowledgeId - * @param separator - * @return - * 20240116优化 - */ - @Override - public String getNamePath(int knowledgeId, String separator){ - BschKnowledge knowledge = knowledgeRepo.getById(knowledgeId); - if(knowledge == null){ - return null; - } - //递归性能不好 -// String name = knowledge.getName(); -// Integer parentId = knowledge.getParentId(); -// if(parentId != 0){ -// String parentPath = this.getNamePath(parentId,separator); -// if(StringUtils.isNotBlank(parentPath)){ -// name = parentPath + separator + name; -// } -// } -// return name; - String name = ""; - String path = knowledge.getPath(); - List ids = Utils.idStrToList(path); - List knowledgeList = knowledgeRepo.getAllByIdInOrderByLevelAsc(ids); - for(BschKnowledge knowledge1 : knowledgeList){ - name = name + knowledge1.getName() + separator; - } - name = name + knowledge.getName(); - return name; - } - - @Override - public String getNamePath(int knowledgeId, String separator, List knowledgeList) { - String name = ""; - for (BschKnowledge knowledge : knowledgeList) { - if(knowledge.getId() == knowledgeId) { - String currentName = knowledge.getName(); - if(knowledge.getParentId()!=null && knowledge.getParentId()!=0){ - name = getNamePath(knowledge.getParentId(),separator,knowledgeList); - name = name + separator + currentName; - }else - name = currentName; - } - } - return name; - - } - - @Override - public List getByIds(List ids) { - return knowledgeRepo.getAllByIdInOrderByLevelAsc(ids); - } - - /************************************** 非override方法 ****************************************************/ - - @Override - @Transactional(rollbackFor = Exception.class) - public Map getTreeOfSystemForApi(int bookId) { - //首先查询当前教材有没有根知识节点 - BschTextbook book = textbookService.getOne(bookId); - BschKnowledge flag = null; - if(book.getTreeId() != null){ - flag = knowledgeRepo.getById(book.getTreeId()); - } - //若没有,创建一个 - if(book.getTreeId() == null || flag == null){ - BschKnowledge root = new BschKnowledge(); - root.setLevel(1); - root.setPath(""); - root.setName(book.getName()); - root.setParentId(0); - root = knowledgeRepo.save(root); - book.setTreeId(root.getId()); - textbookService.saveAndFlush(book); - return JavaBeanUtil.beanToMap(root); - } - String cacheKey = book.getTreeId() + "getTreeOfSystemForApi"; - //查询缓存 - Map cache = (Map)localMemCache.get(cacheKey); - if(cache != null){ - return cache; - } - BschKnowledge root = knowledgeRepo.getById(book.getTreeId()); - //若有根节点则生成树结构并返回 - Map rootMap = this.createTreeForApi(root); - //时效2分钟 - long exp = 2 * 60 * 1000; - //localMemCache.cache(cacheKey,rootMap,exp); - return rootMap; - } - - -// @Override -// public List> getSubdirectoryList(int bookId) -// { -// BschTextbook book = textbookService.getOne(bookId); -// if(book== null) throw new DException("学段专项未初始化!"); -// List bschKnowledgeList= knowledgeRepo.getSectionList(book.getTreeId()); -// -// List> mapList=new ArrayList<>(); -// for (BschKnowledge model:bschKnowledgeList) -// { -// Map mapobj=new HashMap<>(); -// mapobj.put("id",model.getId()); -// mapobj.put("name",model.getName()); -// mapList.add(mapobj); -// } -// return mapList; -// } - - @Override - public List> getSubdirectoryList(int bookId) - { - BschTextbook book = textbookService.getOne(bookId); - if(book== null) throw new DException("学段专项未初始化!"); - List bschKnowledgeList= knowledgeRepo.getSectionList(book.getTreeId()); - - List> mapList=new ArrayList<>(); - for (BschKnowledge model:bschKnowledgeList) - { - Map mapobj=new HashMap<>(); - mapobj.put("id",model.getId()); - mapobj.put("name",model.getName()); - mapList.add(mapobj); - } - return mapList; - } - - -// @Override -// public Map getSubdirectoryTree(int treeId) -// { -// BschKnowledge root = knowledgeRepo.getById(treeId); -// //若有根节点则生成树结构并返回 -// return this.createTreeOfSystem(root); -// } - - - - - - // @Transactional(rollbackFor = Exception.class) -// public Map getTreeOfSchoolForApi(int bookId) { -// //首先查询当前教材有没有根知识节点 -// SchoolTextbook book = schoolTextbookService.getOne(bookId); -// Knowledge flag = null; -// if(book.getTreeId() != null){ -// flag = knowledgeRepo.getById(book.getTreeId()); -// } -// //若没有,创建一个 -// if(book.getTreeId() == null || flag == null){ -// Knowledge root = new Knowledge(); -// root.setLevel(1); -// root.setPath(""); -// root.setName(book.getName()); -// root.setParentId(0); -// root = knowledgeRepo.save(root); -// book.setTreeId(root.getId()); -// schoolTextbookService.saveAndFlush(book); -// return JavaBeanUtil.beanToMap(root); -// } -// String cacheKey = config.getMemCachedGlobalTag() + book.getTreeId() + "getTreeOfSchoolForApi"; -// //查询缓存 -// Map cache = (Map)memCachedClient.get(cacheKey); -// if(cache != null){ -// return cache; -// } -// Knowledge root = knowledgeRepo.getById(book.getTreeId()); -// //若有根节点则生成树结构并返回 -// Map rootMap = this.createTreeForApi(root); -// //时效2分钟 -// long exp = 2 * 60 * 1000; -// memCachedClient.set(cacheKey,rootMap,new Date(exp)); -// return rootMap; -// } -// - @Override - @Transactional(rollbackFor = Exception.class) - public Map getTreeOfSystem(int textbookId) { - //首先查询当前教材有没有根知识节点 - BschTextbook book = textbookService.getOne(textbookId); - BschKnowledge flag = null; - if(book.getTreeId() != null){ - flag = knowledgeRepo.getById(book.getTreeId()); - } - //若没有,创建一个 - if(book.getTreeId() == null || flag == null){ - BschKnowledge root = new BschKnowledge(); - root.setLevel(1); - root.setPath(""); - root.setName(book.getName()); - root.setParentId(0); - BschKnowledge root2 = knowledgeRepo.saveAndFlush(root); - book.setTreeId(root2.getId()); - textbookService.saveAndFlush(book); - Map beanMap = JavaBeanUtil.beanToMap(root); - //添加一些前端框架必须的参数名 - beanMap.put("parent_id",beanMap.get("parentId")); - beanMap.put("order",0); - beanMap.put("uri",beanMap.get("path")); - beanMap.put("open",true); - beanMap.put("lists",null); - return beanMap; - } - BschKnowledge root = knowledgeRepo.getById(book.getTreeId()); - //若有根节点则生成树结构并返回 - return this.createTreeOfSystem(root); - } - -// @Transactional(rollbackFor = Exception.class) -// public Map getTreeOfSchool(int textbookId) { -// //首先查询当前教材有没有根知识节点 -// SchoolTextbook book = schoolTextbookService.getOne(textbookId); -// Knowledge flag = null; -// if(book.getTreeId() != null){ -// flag = knowledgeRepo.getById(book.getTreeId()); -// } -// //若没有,创建一个 -// if(book.getTreeId() == null || flag == null){ -// Knowledge root = new Knowledge(); -// root.setLevel(1); -// root.setPath(""); -// root.setName(book.getName()); -// root.setParentId(0); -// Knowledge root2 = knowledgeRepo.saveAndFlush(root); -// book.setTreeId(root2.getId()); -// schoolTextbookService.saveAndFlush(book); -// Map beanMap = JavaBeanUtil.beanToMap(root); -// //添加一些前端框架必须的参数名 -// beanMap.put("parent_id",beanMap.get("parentId")); -// beanMap.put("order",0); -// beanMap.put("uri",beanMap.get("path")); -// beanMap.put("open",true); -// beanMap.put("lists",null); -// //维护人员信息 -// beanMap.put("maintainers",null); -// return beanMap; -// } -// Knowledge root = knowledgeRepo.getById(book.getTreeId()); -// //若有根节点则生成树结构并返回 -// return this.createTreeOfSchool(root,book.getSchoolSid()); -// } - -// @Transactional(rollbackFor = Exception.class) -// public Map getTreeOfSystem2(int schoolSid,int textbookId) { -// //首先查询当前教材有没有根知识节点 -// Textbook book = textbookService.getOne(textbookId); -// Knowledge flag = null; -// if(book.getTreeId() != null){ -// flag = knowledgeRepo.getById(book.getTreeId()); -// } -// //若没有,创建一个 -// if(book.getTreeId() == null || flag == null){ -// Knowledge root = new Knowledge(); -// root.setLevel(1); -// root.setPath(""); -// root.setName(book.getName()); -// root.setParentId(0); -// Knowledge root2 = knowledgeRepo.saveAndFlush(root); -// book.setTreeId(root2.getId()); -// textbookService.saveAndFlush(book); -// Map beanMap = JavaBeanUtil.beanToMap(root); -// //添加一些前端框架必须的参数名 -// beanMap.put("title",beanMap.get("name")); -// beanMap.put("expand",true); -// beanMap.put("children",null); -// beanMap.put("maintainers",null); -// return beanMap; -// } -// Knowledge root = knowledgeRepo.getById(book.getTreeId()); -// //若有根节点则生成树结构并返回 -// Map rootMap = this.createTree2(schoolSid,root); -// return rootMap; -// } -// -// @Transactional(rollbackFor = Exception.class) -// public Map getTreeOfSchool2(int schoolSid,int textbookId) { -// //首先查询当前教材有没有根知识节点 -// SchoolTextbook book = schoolTextbookService.getOne(textbookId); -// Knowledge flag = null; -// if(book.getTreeId() != null){ -// flag = knowledgeRepo.getById(book.getTreeId()); -// } -// //若没有,创建一个 -// if(book.getTreeId() == null || flag == null){ -// Knowledge root = new Knowledge(); -// root.setLevel(1); -// root.setPath(""); -// root.setName(book.getName()); -// root.setParentId(0); -// Knowledge root2 = knowledgeRepo.saveAndFlush(root); -// book.setTreeId(root2.getId()); -// schoolTextbookService.saveAndFlush(book); -// Map beanMap = JavaBeanUtil.beanToMap(root); -// //添加一些前端框架必须的参数名 -// beanMap.put("title",beanMap.get("name")); -// beanMap.put("expand",true); -// beanMap.put("children",null); -// beanMap.put("maintainers",null); -// return beanMap; -// } -// Knowledge root = knowledgeRepo.getById(book.getTreeId()); -// //若有根节点则生成树结构并返回 -// Map rootMap = this.createTree2(schoolSid,root); -// return rootMap; -// } - - /** 功能描述: 创建知识树结构 - * 没有额外的参数 - * @return: - * @Author: cls - * @Date: 2021/4/12 14:40 - * 2023/09/08 优化 - */ - public Map createTreeForApi(BschKnowledge tree){ - if(tree == null){ - return null; - } - String pathKey = tree.getPath() + tree.getId() + ",%"; - List child = knowledgeRepo.getChildByPath(pathKey); - BschKnowledge knowledgeWithChild = getKnowledgeWithChild(child, tree); - Map beanMap = JavaBeanUtil.beanToMap(knowledgeWithChild); -// List> child = new ArrayList<>(); -// -// Integer id = (Integer)beanMap.get("id"); -// List treeList = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(id); -// if(treeList != null && !treeList.isEmpty()){ -// for(Knowledge t : treeList){ -// Map childMap = this.createTreeForApi(t); -// if(childMap != null){ -// child.add(childMap); -// } -// } -// } -// beanMap.put("child",child); - return beanMap; - } - public BschKnowledge getKnowledgeWithChild(List knowledgeList, BschKnowledge tree){ - Map knowledgeMap = knowledgeList.stream().collect(Collectors.toMap(BschKnowledge::getId, BschKnowledge -> BschKnowledge)); - knowledgeMap.put(tree.getId(),tree); - for (BschKnowledge knowledge : knowledgeList) - { - BschKnowledge parent = knowledgeMap.get(knowledge.getParentId()); - if (parent == null) continue; - if(parent.getId() == tree.getId()) tree = parent; - if (parent.getChild() == null) parent.setChild(new ArrayList<>()); - parent.getChild().add(knowledge); - } - return tree; - } - - /** 功能描述: 创建知识树结构 - * 跟createTree的区别在于每个节点信息新增了一些前端框架必须的参数 - * @param tree - * @return: - * @Author: cls - * @Date: 2021/4/12 14:41 - */ - public Map createTreeOfSystem(BschKnowledge tree){ - if(tree == null){ - return null; - } - Map beanMap = JavaBeanUtil.beanToMap(tree); - //添加一些前端框架必须的参数名 - beanMap.put("parent_id",beanMap.get("parentId")); - beanMap.put("order",0); - beanMap.put("uri",beanMap.get("path")); - beanMap.put("open",true); - List> child = new ArrayList<>(); - - Integer id = (Integer)beanMap.get("id"); - List treeList = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(id); - if(treeList != null && !treeList.isEmpty()){ - for(BschKnowledge t : treeList){ - Map childMap = this.createTreeOfSystem(t); - if(childMap != null){ - child.add(childMap); - } - } - } - beanMap.put("lists",child); - return beanMap; - } - - - - - /** 功能描述: 创建知识树结构Knowledge类型返回值 - * 跟createTree的区别在于每个节点信息新增了一些前端框架必须的参数 - * @param tree - * @return: - * @Author: cls - * @Date: 2021/4/12 14:41 - */ - public List createTreeOfSystem2(BschKnowledge tree){ - if(tree == null){ - return new ArrayList<>(); - } - List list = new ArrayList<>(); - List treeList = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(tree.getId()); - if(treeList != null && !treeList.isEmpty()){ - for(BschKnowledge t : treeList){ - List childMap = this.createTreeOfSystem2(t); - if(childMap != null){ - t.setChild(childMap); - } - list.add(t); - } - } - return list; - } - - - - public Map createTree2(int schoolSid,BschKnowledge tree){ - if(tree == null){ - return null; - } - Map beanMap = JavaBeanUtil.beanToMap(tree); - //添加一些前端框架必须的参数名 - beanMap.put("expand",true); - beanMap.put("title",beanMap.get("name")); - //查询该知识节点的维护人员信息 - List> child = new ArrayList<>(); - Integer id = (Integer)beanMap.get("id"); - List treeList = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(id); - if(treeList != null && !treeList.isEmpty()){ - for(BschKnowledge t : treeList){ - Map childMap = this.createTree2(schoolSid,t); - if(childMap != null){ - child.add(childMap); - } - } - } - beanMap.put("children",child); - return beanMap; - } - -// /** 功能描述: 创建知识树结构 -// * 跟createTree的区别在于每个节点信息新增了一些前端框架必须的参数 -// * @param tree -// * @return: -// * @Author: cls -// * @Date: 2021/4/12 14:41 -// */ -// public Map createTreeOfSchool(BschKnowledge tree,int schoolSid){ -// if(tree == null){ -// return null; -// } -// Map beanMap = JavaBeanUtil.beanToMap(tree); -// //添加一些前端框架必须的参数名 -// beanMap.put("parent_id",beanMap.get("parentId")); -// beanMap.put("order",0); -// beanMap.put("uri",beanMap.get("path")); -// beanMap.put("open",true); -// //查询该知识节点的维护人员信息 -// beanMap.put("maintainers",knowledgeMaintainerService.get(tree.getId(),schoolSid)); -// List> child = new ArrayList<>(); -// List treeList = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(tree.getId()); -// if(treeList != null && !treeList.isEmpty()){ -// for(Knowledge t : treeList){ -// Map childMap = this.createTreeOfSchool(t,schoolSid); -// if(childMap != null){ -// child.add(childMap); -// } -// } -// } -// beanMap.put("lists",child); -// return beanMap; -// } - -// /** 功能描述: 创建知识树结构 -// * 跟createTree和createTreeOfSystem,createTreeOfSchool的区别在于每个节点信息新增了一些前端框架必须的参数 -// * @param tree -// * @return: -// * @Author: cls -// * @Date: 2021/4/12 14:41 -// */ -// public Map createTree2(int schoolSid,Knowledge tree){ -// if(tree == null){ -// return null; -// } -// Map beanMap = JavaBeanUtil.beanToMap(tree); -// //添加一些前端框架必须的参数名 -// beanMap.put("expand",true); -// beanMap.put("title",beanMap.get("name")); -// //查询该知识节点的维护人员信息 -// beanMap.put("maintainers",knowledgeMaintainerService.get(tree.getId(),schoolSid)); -// List> child = new ArrayList<>(); -// -// Integer id = (Integer)beanMap.get("id"); -// List treeList = knowledgeRepo.getAllByParentIdOrderByOrderCodeAsc(id); -// if(treeList != null && !treeList.isEmpty()){ -// for(Knowledge t : treeList){ -// Map childMap = this.createTree2(schoolSid,t); -// if(childMap != null){ -// child.add(childMap); -// } -// } -// } -// beanMap.put("children",child); -// return beanMap; -// } - - -// public NodeTree convertTree(BschKnowledge k) { -// if (k == null) { -// return null; -// } -// NodeTree node = new NodeTree(); -// node.setId(k.getId()); -// node.setName(k.getName()); -// node.setLevel(k.getLevel()); -// node.setParentId(k.getParentId()); -// node.setPath(k.getPath()); -// node.setSortCode(k.getOrderCode()); -// node.setOriginKnowledge(k.getId()); // 记录来源主键 -// /* ---------- 递归子节点 ---------- */ -// if (k.getChild() != null && !k.getChild().isEmpty()) { -// node.setChildren(new ArrayList<>()); -// for (Knowledge c : k.getChild()) { -// node.getChildren().add(convertTree(c)); -// } -// } -// return node; -// } - - public List getEndNodeList(int textbookId) - { - List list=getTreeOfSystemToList(textbookId); - return list.stream().filter(s->s.get("end").equals(true)).collect(Collectors.toList()); - } - - public List getTreeOfSystemToList(int textbookId) - { - Map mapTree= getTreeOfSystemForApi(textbookId); - LinkedList list=new LinkedList<>(); - setTreeMapToList(mapTree,list); - setBschNodeLinkName(list); - return list; - } - - private void setTreeMapToList(Map mapTree,LinkedList list){ - - if(mapTree!=null) - { - Map map=new HashMap(); - map.put("id",mapTree.get("id")); - map.put("name",mapTree.get("name")); - map.put("path",mapTree.get("path")); - map.put("end",!(mapTree.get("child")!=null&&((List )mapTree.get("child")).stream().count()>0)); - list.add(map); - if(mapTree.get("child")!=null) - { - List mapTreeList=((List )mapTree.get("child")).stream().collect(Collectors.toList()); - if(mapTreeList.stream().count()>0) - { - for (BschKnowledge mapTreeTem:mapTreeList) - { - setTreeMapToList( JavaBeanUtil.beanToMap(mapTreeTem),list); - } - } - } - - - } - } - private void setBschNodeLinkName (LinkedList nodeList) - { - Integer ord=0; - for (Map map:nodeList) - { - List ids=Arrays.asList(map.get("path").toString().split(",")) - .stream().filter(s->StringUtils.isNotEmpty(s)).collect(Collectors.toList()); - List names=nodeList.stream().filter(s->ids.contains(s.get("id").toString())) - .map(s->s.get("name").toString()).collect(Collectors.toList()); - map.put("names",names); - map.put("cname",String.join(" ",names)); - map.put("ord",ord++); - } - } - - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/BschLeadlearningService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/BschLeadlearningService.java deleted file mode 100644 index a001d5a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/BschLeadlearningService.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.BschKnowledgeRepository; -import com.bestsch.classicalchinese.Repository.BschLeadlearningRepository; -import com.bestsch.classicalchinese.entity.*; -import com.bestsch.classicalchinese.model.ExcelBschLeadlearning; -import com.bestsch.classicalchinese.service.IBschLeadlearningService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; - -@Service -public class BschLeadlearningService implements IBschLeadlearningService { - - @Autowired - private BschLeadlearningRepository bschLeadlearningRepository; - - - public void save(BschLeadlearning entity) { - bschLeadlearningRepository.save(entity); - } - - public void saveAll(List entitys) { - bschLeadlearningRepository.saveAll(entitys); - } - - public Optional findOne(Integer textbookId,Integer nodeId) - { - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return bschLeadlearningRepository.findOne(specification); - } - - public List findTextbookAll(Integer textbookId) - { - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return bschLeadlearningRepository.findAll(specification); - } - -// public List getExcelBschLeadlearning(Integer textbookId) -// { -// List list=new ArrayList<>(); -// -// List treenodelist= bschZiYuanTreeService.getTreeNodeList(textbookId); -// List TextbookAllLeadlearning= findTextbookAll(textbookId); -// for (Map nmap:treenodelist) -// { -// ExcelBschLeadlearning excelBschLeadlearning=new ExcelBschLeadlearning(); -// excelBschLeadlearning.setCname(nmap.get("cname").toString()); -// Optional bschLeadlearningOptional= TextbookAllLeadlearning.stream().filter(s->s.getNodeId().toString().equals(nmap.get("id").toString())).findFirst(); -// String getContent= bschLeadlearningOptional.map(BschLeadlearning::getContent).orElse(""); -// excelBschLeadlearning.setBschLeadlearning(getContent); -// list.add(excelBschLeadlearning); -// } -// return list; -// } - - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/BschQuestionService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/BschQuestionService.java deleted file mode 100644 index cbf16bc..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/BschQuestionService.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.BschQuestionRepository; -import com.bestsch.classicalchinese.entity.BschQuestion; -import com.bestsch.classicalchinese.enums.DifficultLevel; -import com.bestsch.classicalchinese.enums.QuestionType; -import com.bestsch.classicalchinese.service.IBschQuestionService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; - -@Service -public class BschQuestionService implements IBschQuestionService { - - @Autowired - private BschQuestionRepository bschQuestionRepository; - - public void save(BschQuestion entity) { - bschQuestionRepository.save(entity); - } - - public void saveAll(List entitys) { - bschQuestionRepository.saveAll(entitys); - } - - public Optional findOne(Integer id, Integer textbookId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("id"),id)); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return bschQuestionRepository.findOne(specification); - } - - - public List findNoteAll(Integer nodeId, Integer textbookId){ - Sort sort = Sort.by(Sort.Direction.ASC, "sort"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return bschQuestionRepository.findAll(specification,sort); - } - - public List findGradeMapAll(Integer nodeId,Integer textbookId){ - List questionMapList=new ArrayList<>(); - List questionList=findNoteAll(nodeId,textbookId); - for (BschQuestion pram:questionList) - { - Map map = new HashMap(); - map.put("id", pram.getId()); - map.put("name", pram.getName()); - map.put("config", pram.getConfig()); - map.put("answer", pram.getAnswer()); - map.put("solve", pram.getSolve()); - - Map qtMap = new HashMap(); - qtMap.put("id",pram.getQuestionTypeId()); - qtMap.put("name", QuestionType.nameById(pram.getQuestionTypeId())); - qtMap.put("cdate",new Date()); - map.put("questionType",qtMap); - - Map dlMap = new HashMap(); - dlMap.put("id",pram.getDifficultLevelId()); - dlMap.put("name", DifficultLevel.nameById(pram.getDifficultLevelId())); - - map.put("difficultLevel",dlMap); - - map.put("solveQuestionFiles",new ArrayList<>()); - map.put("questionTypeId", pram.getQuestionTypeId()); - map.put("difficultLevelId", pram.getDifficultLevelId()); - map.put("pId",pram.getPId()); - questionMapList.add(map); - } - return questionMapList; - } - - - - public void deleteAll(List entitys) { - bschQuestionRepository.deleteAll(entitys); - } - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/BschTextbookService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/BschTextbookService.java deleted file mode 100644 index d8f311d..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/BschTextbookService.java +++ /dev/null @@ -1,268 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.BschKnowledgeRepository; -import com.bestsch.classicalchinese.Repository.BschTextbookRepository; -import com.bestsch.classicalchinese.entity.BschKnowledge; -import com.bestsch.classicalchinese.entity.BschLeadlearning; -import com.bestsch.classicalchinese.entity.BschTextbook; -import com.bestsch.classicalchinese.enums.AppType; -import com.bestsch.classicalchinese.service.IBschTextbookService; -import com.bestsch.classicalchinese.utils.DicUtil; -import com.bestsch.classicalchinese.utils.EnumUtil; -import com.bestsch.classicalchinese.utils.JavaBeanUtil; -import com.bestsch.classicalchinese.utils.OtherUtil; -import com.bestsch.utils.DException; -import com.bestsch.utils.ErrorCode; -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.xssf.usermodel.XSSFCell; -import org.apache.poi.xssf.usermodel.XSSFRow; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import javax.persistence.criteria.*; -import javax.servlet.http.HttpServletResponse; -import java.util.*; - -/** - * @ Description : java类作用描述 - * @ Author : cls - * @ CreateDate : 2020/2/21 10:49 - * @ Company : bestsch - */ -@Service -public class BschTextbookService implements IBschTextbookService { - - @Autowired - private BschTextbookRepository textbookRepo; - - @Autowired - private BschKnowledgeService bschKnowledgeService; - - /** - * 获取表格标题名称 - * @return - */ - private List getHeadTitle(){ - List headTitle = new ArrayList<>(); - headTitle.add("教材名称"); - headTitle.add("年级"); - headTitle.add("学期"); - headTitle.add("学科"); - headTitle.add("出版社"); - headTitle.add("年份"); - return headTitle; - } - - @Override - public BschTextbook getOne(int id) { - return textbookRepo.getById(id); - } - - @Override - public Optional findOne(int id) { - return textbookRepo.findById(id); - } - - @Override - public List getList(List ids) { - return textbookRepo.findAllById(ids); - } - - @Override - public List getAllList() { - return textbookRepo.findAll(); - } - - - @Override - @Transactional(rollbackFor = Exception.class) - public BschTextbook saveAndFlush(BschTextbook book) { - return textbookRepo.saveAndFlush(book); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public BschTextbook addTextbook(BschTextbook textbook) { - return textbookRepo.save(textbook); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public BschTextbook addAndCreateKnowledge(BschTextbook textbook) { - BschKnowledge root = bschKnowledgeService.createRoot(textbook.getName()); - textbook.setTreeId(root.getId()); - return this.addTextbook(textbook); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void delTextbook(Integer id) { - textbookRepo.deleteById(id); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public BschTextbook setTextbook(Integer id, BschTextbook textbook) { - BschTextbook old = textbookRepo.getById(id); - if(old == null){ - throw new DException(DicUtil.ERROR_MSG_NOT_FOUND); - } - if(StringUtils.isNotBlank(textbook.getName())){ - old.setName(textbook.getName()); - } - if(textbook.getSchParagraph() != null){ - old.setSchParagraph(textbook.getSchParagraph()); - } - if(textbook.getSemester() != null){ - old.setSemester(textbook.getSemester()); - } - if(StringUtils.isNotBlank(textbook.getOutTime())){ - old.setOutTime(textbook.getOutTime()); - } - return textbookRepo.saveAndFlush(old); - } - - @Override - public Map selectTextbook(Integer grade, String subjectName, Integer semester,String press,String outTime, - String keyword,String orderKey, Integer order, Integer pageIndex, Integer pageSize) { - //添加查询条件 - Specification queryCondition = new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - //先确认排序条件 - if(StringUtils.isNotBlank(orderKey)){ - //存放排序条件 - List orderList = new ArrayList<>(); - if(DicUtil.ORDER_DESC.equals(order)){ - orderList.add(criteriaBuilder.desc(root.get(orderKey))); - }else{ - orderList.add(criteriaBuilder.asc(root.get(orderKey))); - } - //设置排序条件 - criteriaQuery.orderBy(orderList); - } - //存放and关系的参数 - List andList = new ArrayList<>(); - if(grade != null){ - andList.add(criteriaBuilder.equal(root.get("grade"), grade)); - } - if(StringUtils.isNotBlank(subjectName) && !"品德".equals(subjectName)){ - andList.add(criteriaBuilder.like(root.get("subjectName"), "%" + subjectName + "%")); - } - if(semester != null){ - andList.add(criteriaBuilder.equal(root.get("semester"), semester)); - } - if(StringUtils.isNotBlank(press)){ - andList.add(criteriaBuilder.equal(root.get("press"), press)); - } - if(StringUtils.isNotBlank(outTime)){ - andList.add(criteriaBuilder.equal(root.get("outTime"),outTime)); - } - //创建and查询条件 - Predicate preAnd = criteriaBuilder.and(andList.toArray(new Predicate[andList.size()])); - //创建or查询条件 - Predicate preOr1 = null; - Predicate preOr2 = null; - //存放or关系的参数 - List orList1 = new ArrayList<>(); - List orList2 = new ArrayList<>(); - //若学科为品德,则搜索时应该包括道德与法治这个学科下的教材 - if(StringUtils.isNotBlank(subjectName) && "品德".equals(subjectName)){ - orList1.add(criteriaBuilder.like(root.get("subjectName"), "%" + subjectName + "%")); - orList1.add(criteriaBuilder.like(root.get("subjectName"), "%道德%")); - } - if(StringUtils.isNotBlank(keyword)){ - orList2.add(criteriaBuilder.like(root.get("name"),"%" + keyword + "%")); - //依据名称模糊搜索出版社信息 - - } - preOr1 = criteriaBuilder.or(orList1.toArray(new Predicate[orList1.size()])); - preOr2 = criteriaBuilder.or(orList2.toArray(new Predicate[orList2.size()])); - if(orList1.size() > 0 && orList2.size() > 0){ - return criteriaQuery.where(preAnd,preOr1,preOr2).getRestriction(); - }else if (orList1.size() > 0 && orList2.size() == 0){ - return criteriaQuery.where(preAnd,preOr1).getRestriction(); - }else if (orList1.size() == 0 && orList2.size() > 0){ - return criteriaQuery.where(preAnd,preOr2).getRestriction(); - } - return preAnd; - } - }; - - Map returnMap = new HashMap<>(); - List textbookList = new ArrayList<>(); - List> beanMaps = new ArrayList<>(); - //添加分页效果 pageIndex=0则不分页 - if(pageIndex == 0){ - textbookList = textbookRepo.findAll(queryCondition); - }else { - textbookList = textbookRepo.findAll(queryCondition, PageRequest.of(pageIndex - 1, pageSize)).getContent(); - } - Long maxNum = textbookRepo.count(queryCondition); - returnMap.put("maxNum",maxNum); - returnMap.put("dataList",beanMaps); - return returnMap; - } - - @Override - public String getSubjectByTree(int treeId) { - BschTextbook textbook = textbookRepo.getFirstByTreeId(treeId); - if(textbook != null){ - return textbook.getSubjectName(); - } - return "无"; - } - -// public Optional findOne() -// { -// Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { -// List predicates = new ArrayList<>(); -// predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); -// predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); -// return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); -// }; -// return textbookRepo.findOne(specification); -// } -// -// @Override -// public BschTextbook getBschTextbook(){ -// String xdcode= OtherUtil.getXdCode(); -// String apptype=OtherUtil.getAppType(); -// -// Optional textbookOptional= -// //getAllList().stream().filter(s->s.getApptype().toString().equals(apptype)&&s.getSchParagraph().toString().equals(xdcode)).findFirst(); -// -// if(textbookOptional.isPresent()) -// { -// return textbookOptional.get(); -// } -// BschTextbook bk=new BschTextbook(); -// bk.setName(EnumUtil.getValue(AppType.class,apptype)); -// bk.setSchParagraph(Integer.parseInt(xdcode)); -// bk.setApptype(Integer.parseInt(apptype)); -// return saveAndFlush(bk); -// } - - - - /** 功能描述: bean to map 对一些参数进行处理 - * @param textbook - * @return: - * @Author: cls - * @Date: 2021/4/13 10:28 - */ -// public Map beanToMap(BschTextbook textbook){ -// Map beanMap = JavaBeanUtil.beanToMap(textbook); -// Integer systemGrade = (Integer) beanMap.get("grade"); -// String gradeName = SystemGrade.getName(systemGrade); -// beanMap.put("gradeName",gradeName); -// return beanMap; -// } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/ExplanationService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/ExplanationService.java deleted file mode 100644 index 46270ee..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/ExplanationService.java +++ /dev/null @@ -1,301 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.bestsch.classicalchinese.Repository.VideoExplanationRepository; -import com.bestsch.classicalchinese.entity.BschVideoExplanation; -import com.bestsch.classicalchinese.entity.VideoExplanation; -import com.bestsch.classicalchinese.service.IExplanationService; -import com.bestsch.classicalchinese.service.com.BaseComService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.com.UploadFileService; -import com.bestsch.classicalchinese.service.com.ZiyuankuService; -import com.bestsch.utils.DException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class ExplanationService implements IExplanationService { - -// @Value("${FILE_PATH}") -// private String FILE_PATH; - - @Value("${FILE_WEB_PATH}") - private String FILE_WEB_PATH; - @Autowired - private VideoExplanationRepository videoExplanationRepository; - @Autowired - private BaseComService baseComService; - @Autowired - private ClassService classService; - @Autowired - private ZiyuankuService ziyuankuService; - @Autowired - private UploadFileService uploadFileService; - - @Autowired - private BschExplanationService bschExplanationService; - /** - * 讲解--列表 - */ - @Override - public Object getExplanationList(int schId, int userId, Integer nodeId, Pageable pageable) { - Page lists = videoExplanationRepository.findPageBySchIdAndNodeId(schId, nodeId, pageable); - - Map data = new HashMap<>(); - data.put("list", getVideoMapList(lists.getContent(),userId, schId)); - data.put("count", lists.getTotalElements()); - return data; - } - - @Override - public Object pdfPreview(int schId, Integer id) { - VideoExplanation file = videoExplanationRepository.getAllById(id); - if(file==null) throw new DException("附件不存在!"); - if(file.getSchId()!=schId) throw new DException("权限不足!"); - - String filePath=baseComService.getFilePath(file.getType(),file.getFileUrl()); - String pdfPath=filePath.replace("."+file.getSuffixName(),".pdf"); - - boolean existsfile= uploadFileService.SaveUploadFilePdf(file.getType(),filePath,pdfPath,file.getSuffixName()); - - if(!existsfile) throw new DException("附件不存在!"); - else return FILE_WEB_PATH+pdfPath; - } - - public List getVideoMapList(List lists,Integer userId, Integer schId) { - List mapList = new ArrayList<>(); - List teaList = classService.getSchteaList(schId); - for (VideoExplanation pram : lists) { - - String filePath=baseComService.getFilePath(pram.getType(),pram.getFileUrl()); - String pdfPath=filePath.replace("."+pram.getSuffixName(),".pdf"); - Boolean pdfreview= uploadFileService.SaveUploadFilePdf(pram.getType(),filePath,pdfPath,pram.getSuffixName()); - - Map map = new HashMap(); - map.put("id", pram.getId()); - map.put("name", pram.getName()); - map.put("createTime", pram.getCreateTime()); - map.put("createUserName", getTeaName(teaList, pram.getCreateUser())); - map.put("createUser", pram.getCreateUser()); - map.put("size", pram.getSize()); - map.put("fileUrl", baseComService.getFileUrl(pram.getType(), pram.getFileUrl())); - map.put("nodeId", pram.getNodeId()); - map.put("suffixName", pram.getSuffixName()); - map.put("preview",pdfreview); - map.put("edit",Objects.equals(userId,pram.getCreateUser())); - map.put("previewUrl",pdfreview?baseComService.getFileUrl(pram.getType(), pram.getFileUrl()).replace("."+pram.getSuffixName(),".pdf"):""); - mapList.add(map); - } - return mapList; - } - - public String getTeaName(List teaList, Integer teaId) { - String teaName = ""; - List teaList1 = teaList.stream().filter(x -> Objects.equals(x.get("UserTeaSerID").toString(), teaId.toString())).collect(Collectors.toList()); - if (teaList1 != null && teaList1.size() > 0) { - teaName = teaList1.get(0).get("TeaName").toString(); - } - return teaName; - } - - - /** - * 讲解--添加 - */ - @Override - public void saveExplanation(int schId, int userId, List list) { - List lists = new ArrayList<>(); - for (VideoExplanation pram : list) { - if (pram.getNodeId() == null) throw new NullPointerException("请选择知识树节点"); - pram.setCreateUser(userId); - pram.setSchId(schId); - pram.setCreateTime(new Date()); - lists.add(pram); - } - if (lists != null && lists.size() > 0) { - videoExplanationRepository.saveAll(lists); - - VideoExplanation model = list.get(0); - if (model.getType() == 1 && model.getIsSyncResource() == 1) { - //todo 同步到资源 - } - } - } - - @Override - public void saveExplanation1(int schId, int userId, Map map) { - if (map != null) { - if (map.get("nodeId") == null) throw new NullPointerException("请选择知识树节点"); - - Integer nodeId = Integer.valueOf(map.get("nodeId").toString()); - Integer gradeId = Integer.valueOf(map.get("gradeId").toString()); - String subjectId = (String) map.get("subjectId"); - String path = (String) map.get("path"); - Integer type = Integer.valueOf(map.get("type").toString()); - Integer isSyncResource = 0; - String zykType = null; - if (type == 1) { - isSyncResource = Integer.valueOf(map.get("isSyncResource").toString()); - if (isSyncResource == 1) { - zykType = (String) map.get("zykType"); - } - } - - List files = JSONArray.parseArray(JSON.toJSONString(map.get("files")), Map.class); -// System.out.println("files================="+JSON.toJSONString(files)); - List lists = new ArrayList<>(); - for (Map file : files) { - VideoExplanation pram = new VideoExplanation(); - pram.setNodeId(nodeId); - pram.setPath(path); - pram.setIsSyncResource(isSyncResource); - pram.setType(type); - - String fileUrl = file.get("downUrl").toString(); - String fileName = file.get("name").toString(); - String suffixName = file.get("suffixName").toString(); - pram.setName(fileName); - pram.setFileUrl(fileUrl); - pram.setSize(file.get("size").toString()); - pram.setSuffixName(suffixName); - pram.setDuration(Long.valueOf(0)); - - Integer fileUserId=Integer.valueOf(file.get("userId").toString()); - - pram.setCreateUser(fileUserId); - pram.setSchId(schId); - pram.setCreateTime(new Date()); - lists.add(pram); - - if (pram.getType() == 1 && pram.getIsSyncResource() == 1) { - //同步到资源 - ziyuankuService.syncZiYuanData(schId, userId, pram.getNodeId(), zykType, fileUrl,fileName+suffixName); - } - } - if (lists != null && lists.size() > 0) { - videoExplanationRepository.saveAll(lists); - } - } - } - - /** - * 讲解--删除 - */ - @Override - public void deleteExplanation(int userId, Integer id) { - Integer ids = videoExplanationRepository.getIdByIdAndUserId(id, userId); - if (ids != null) { - videoExplanationRepository.deleteAllById(id); - } else throw new NullPointerException("您没有删除该讲解的权限!"); - } - - - @Override - public void deleteExplanation(Integer id) { - VideoExplanation explanation = videoExplanationRepository.getAllById(id); - if (explanation != null) { - videoExplanationRepository.deleteAllById(id); - } - } - -// /** -// * 从资源库选择--知识树 -// */ -// @Override -// public Object getZYKSubjectTree(int schId, int userId, Integer nodeId) { -// List list = (List) ziyuankuService.getChapterNew2(schId, userId, nodeId, null); -// return list; -// } - - @Override - public Object getZYKSubjectTree(int schId, int userId, Integer nodeId) { - List list = ziyuankuService.getChapterNew2(schId, userId, nodeId, null); - return getChildren(list,1); - } - - private List getChildren(List children,int type) { - return children.stream() - .map(child -> { - Map map = new HashMap(); - map.put("id", child.get("id")); - map.put("title", child.get("name")); - if(child.get("isParent").toString().equals("true")) - map.put("loading",false); - map.put("path", child.get("path")); - map.put("level", child.get("level")); - map.put("schoolSid", child.get("schoolSid")); - map.put("originKnowledge", child.get("originKnowledge")); - map.put("localLevel", child.get("localLevel")); - map.put("parentId", child.get("parentId")); - - Boolean expand = false; - if (type == 1) expand = true; - map.put("expand", expand); - - if (child.get("children") != null) { - List children1 = com.alibaba.fastjson.JSONArray.parseArray(JSON.toJSONString(child.get("children")), Map.class); - map.put("children", getChildren(children1,2)); - } else map.put("children", new ArrayList<>()); - return map; - }).collect(Collectors.toList()); - } - - - /** - * 从资源库选择--视频列表 - */ - @Override - public Object getZYKVideoList(int schId, int userId, int roleId, Integer nodeId, Integer page, Integer count) { - Map dMap = ziyuankuService.getResourceByNodeId(schId, userId, roleId, nodeId, page, count); - - - List mapList = new ArrayList<>(); - if (dMap.get("dataList") != null) { - List lists = JSONArray.parseArray(JSON.toJSONString(dMap.get("dataList")), Map.class); - mapList = getZYKVideoMapList(lists); - } - Map data = new HashMap<>(); - data.put("list", mapList); - data.put("count", dMap.get("maxNum")); - return data; - } - - private List getZYKVideoMapList(List lists){ - List mapList = new ArrayList<>(); - for (Map pram:lists){ - Map map = pram; - //map.put("fileUrl",(String)pram.get("savePath")+pram.get("serialNum")+pram.get("suffixName")); - //map.put("duration",pram.get("duration")==null?0:pram.get("duration")); - map.put("name",pram.get("name").toString()+pram.get("suffixName").toString()); - mapList.add(map); - } - return mapList; - } - - - //初始化 - public void initialization(Integer year,Integer schId) - { - - - } - - private List findTextbookSchAll(Integer textbookId,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return videoExplanationRepository.findAll(specification); - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/FeedBackService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/FeedBackService.java deleted file mode 100644 index a79ec25..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/FeedBackService.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - - -import com.bestsch.classicalchinese.Repository.FeedBackRepository; -import com.bestsch.classicalchinese.entity.FeedBack; -import com.bestsch.classicalchinese.service.IFeedBackService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; - -@Service -public class FeedBackService implements IFeedBackService { - - @Autowired - private FeedBackRepository feedBackRepository; - - public void addFeedBack(FeedBack feedBack) { - feedBack.setCreateDateTime(LocalDateTime.now()); - feedBackRepository.save(feedBack); - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/OcrDataCacheServiceImpl.java b/src/main/java/com/bestsch/classicalchinese/service/impl/OcrDataCacheServiceImpl.java deleted file mode 100644 index 8a2f9e9..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/OcrDataCacheServiceImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.OcrDataCacheRepository; -import com.bestsch.classicalchinese.enums.OcrDataCache; -import com.bestsch.classicalchinese.service.IOcrDataCacheService; -import com.bestsch.utils.LocalMemCache; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.Optional; - -/** - * @author CHY - * @date 2024/7/18 16:37 - */ -@Service -public class OcrDataCacheServiceImpl implements IOcrDataCacheService { - - private static LocalMemCache localMemCache = new LocalMemCache(); - - @Autowired - private OcrDataCacheRepository ocrDataCacheRepository; - - @Override - public void save(OcrDataCache ocrDataCache) { - ocrDataCacheRepository.save(ocrDataCache); - } - - /** - * 根据图片url,获取图片文字 - */ - @Override - public Optional findDataByImgUrl(String imgUrl) { - // 从内存中拿 - String cache = (String) localMemCache.get(imgUrl); - if (!StringUtils.isBlank(cache)) { - return Optional.of(cache); - } - Optional optional = ocrDataCacheRepository.findDataByImgUrl(imgUrl); - // 存内存 - optional.ifPresent((data) -> { - if (!StringUtils.isBlank(data)) { - localMemCache.cache(imgUrl, data, 7 * 24 * 60 * 60 * 1000); - } - }); - return optional; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitCommunicationService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitCommunicationService.java deleted file mode 100644 index cb65e26..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitCommunicationService.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.PunitCommunicationRepository; -import com.bestsch.classicalchinese.entity.PunitCommunication; -import com.bestsch.classicalchinese.service.IPunitCommunicationService; -import com.bestsch.classicalchinese.service.com.CommonService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class PunitCommunicationService implements IPunitCommunicationService { - - @Autowired - private PunitCommunicationRepository PunitCommunicationRepository; - - @Autowired - private CommonService commonService; - - public void save(PunitCommunication entity) { - PunitCommunicationRepository.save(entity); - } - - public void delete(PunitCommunication entity) { - PunitCommunicationRepository.delete(entity); - } - - public Optional findOne(Integer id, Integer userId, Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("id"),id)); - predicates.add(criteriaBuilder.equal(root.get("cUserId"),userId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitCommunicationRepository.findOne(specification); - } - - public List findNodeStuCOne(Integer nodeId, Integer userId, Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("cId"),0)); - predicates.add(criteriaBuilder.equal(root.get("cUserId"),userId)); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitCommunicationRepository.findAll(specification); - } - - - - public List findNodeClassOne(Integer nodeId, Integer classId , Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("cId"),0)); - predicates.add(criteriaBuilder.equal(root.get("classId"),classId)); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitCommunicationRepository.findAll(specification); - } - - - public List findNodesClassOne(List nodeIds,Integer classId ,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("cId"),0)); - predicates.add(criteriaBuilder.equal(root.get("classId"),classId)); - predicates.add(criteriaBuilder.in(root.get("nodeId")).value(nodeIds)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitCommunicationRepository.findAll(specification); - } - - public List findNodeCAll(List cIds, Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.in(root.get("cId")).value(cIds)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitCommunicationRepository.findAll(specification); - } - - - public List getCommunicationClassStu(Integer schId,Integer classId,Integer nodeId) - { - //获取班级学生 - List classStuList= commonService.getClassStuList(schId,classId); - //List stuIds=classStuList.stream().map(a->Integer.parseInt(a.get("id").toString())).collect(Collectors.toList()); - List stuCommunications=findNodeClassOne(nodeId,classId,schId); - - for (Map stumap: classStuList ){ - stumap.put("status",stuCommunications.stream().filter(s->s.getCUserId().toString().equals(stumap.get("id").toString())).count()>0); - } - return classStuList; - } - - - public List getCommunicationList(Integer nodeId,Integer userId,Integer schId){ - List pcomms= findNodeStuCOne(nodeId,userId, schId); - List cIds=pcomms.stream().map(s->s.getId()).collect(Collectors.toList()); - pcomms.addAll(findNodeCAll(cIds,schId)); - return getCommunicationPList(pcomms,0); - } - - public List getClassCommunicationList(Integer nodeId,Integer classId,Integer schId){ - List pcomms= findNodeClassOne(nodeId,classId, schId); - List cIds=pcomms.stream().map(s->s.getId()).collect(Collectors.toList()); - pcomms.addAll(findNodeCAll(cIds,schId)); - return getCommunicationPList(pcomms,0); - } - - - - private List getCommunicationPList(List plist, int pid) - { - List mlist=new ArrayList<>(); - List p2list=plist.stream().filter(s->s.getCId().equals(pid)).collect(Collectors.toList()); - for (PunitCommunication pitem:p2list){ - Map mp=new HashMap(); - mp.put("id",pitem.getId()); - mp.put("cId",pitem.getCId()); - mp.put("content",pitem.getContent()); - mp.put("classId",pitem.getClassId()); - mp.put("userName",pitem.getUserName()+(!pitem.getRole().equals(3)?"老师":"")); - mp.put("userId",pitem.getCUserId()); - mp.put("photo",pitem.getUserPhoto()); - mp.put("date",pitem.getCDate()); - mp.put("plist",getCommunicationPList(plist,pitem.getId())); - mlist.add(mp); - } - return mlist; - } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitLeadlearningService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitLeadlearningService.java deleted file mode 100644 index 75310e7..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitLeadlearningService.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.PunitLeadlearningRepository; -import com.bestsch.classicalchinese.Repository.PunitQuestionRepository; -import com.bestsch.classicalchinese.entity.*; -import com.bestsch.classicalchinese.model.ExcelPunitTreeTea; -import com.bestsch.classicalchinese.service.IPunitLeadlearningService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.com.CommonService; -import com.bestsch.classicalchinese.utils.PageUtil; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class PunitLeadlearningService implements IPunitLeadlearningService { - - @Autowired - private PunitLeadlearningRepository punitLeadlearningRepository; - - @Autowired - private BschLeadlearningService bschLeadlearningService; - - @Autowired - private ClassService classService; - - @Autowired - private CommonService commonService; - @Autowired - private PunitStuAnswerService punitStuAnswerService; - - @Autowired - private PunitQuestionRepository punitQuestionRepository; - - @Autowired - private PunitCommunicationService punitCommunicationService; - - @Autowired - private BschKnowledgeService bschKnowledgeService; - - public void save(PunitLeadlearning entity) { - punitLeadlearningRepository.save(entity); - } - - public void saveAll(List entitys) { - punitLeadlearningRepository.saveAll(entitys); - } - - //Integer textbookId 99 - public Optional findOne(Integer textbookId,Integer nodeId,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitLeadlearningRepository.findOne(specification); - } - - public Optional findOne(Integer id,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("id"),id)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitLeadlearningRepository.findOne(specification); - } - - public List findSchAll(Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitLeadlearningRepository.findAll(specification); - } - - -// public List getPunitList(int textbookId,Integer role,Integer userid,Integer year,Integer term,Integer schId) { -// -// List punitlist = new ArrayList<>(); -// for (Map nmap : nodeList) { -// if (nmap.get("tealist") != null) { -// List teas = (List) nmap.get("tealist"); -// nmap.put("edit",role.equals(7) || teas.stream().filter(s -> s.get("teaId").toString().equals(userid.toString())).count()>0); -// punitlist.add(nmap); -// } -// } -// return punitlist; -// } - - - - public Map getTeaPunitList(Integer textbookId,Integer role,Integer userid,Integer nodeId, - Integer classId,Integer schId,Pageable pageable) { - - List treenodelist= bschKnowledgeService.getEndNodeList(textbookId); - - if(nodeId!=null) - treenodelist=treenodelist.stream().filter(s->(","+s.get("path").toString()).contains(","+nodeId+",")).collect(Collectors.toList()); - - List schLeadlearning=findSchAll(schId); - - List NodeQcount=punitQuestionRepository.findByNodeQcount(schId); - - List stuAnswersList=punitStuAnswerService.findClassAll(classId,schId); - - List pagelist= PageUtil.paginate(treenodelist,pageable); - List nodeIds=pagelist.stream().map(s->(Integer)s.get("id")).collect(Collectors.toList()); - - List classStuList= commonService.getClassStuList(schId,classId); - - List stuAskList=punitCommunicationService.findNodesClassOne(nodeIds,classId,schId); - - for (Map map:pagelist) - { - Integer qcount=0; - String mnodeId=map.get("id").toString(); - - Optional qOptional= NodeQcount.stream().filter(s->s.get("node_id").toString().equals(mnodeId)).findFirst(); - if(qOptional.isPresent()) - { - qcount=Integer.parseInt(qOptional.get().get("qcount").toString()); - } - List stuAnswersNodeList= stuAnswersList.stream().filter(s->s.getNodeId().toString().equals(mnodeId)&&Objects.equals(s.getIsReview(),1)).collect(Collectors.toList()); - - long stucount=stuAnswersNodeList.stream().filter(s-> Objects.equals(s.getStatus(),1)).map(s->s.getStuId()).distinct().count(); - - String Leadlearning=""; - Optional LeadlearningOptional= schLeadlearning.stream().filter(s->s.getNodeId().toString().equals(mnodeId)&&Objects.equals(s.getTextbookId(),textbookId)).findFirst(); - - if(LeadlearningOptional.isPresent()) - { - Leadlearning=LeadlearningOptional.get().getContent(); - } - if(StringUtils.isEmpty(Leadlearning)) - { - Optional bschLeadlearningOpt= bschLeadlearningService.findOne(textbookId,Integer.parseInt(mnodeId)); - Leadlearning= bschLeadlearningOpt.map(BschLeadlearning::getContent).orElse(""); - } - - map.put("qcount",qcount); - map.put("stucount",stucount); - map.put("askcount",stuAskList.stream().filter(s->s.getNodeId().toString().equals(mnodeId)).count()); - map.put("Leadlearning",Leadlearning); - } - Map data = new HashMap<>(); - data.put("content",pagelist); - data.put("total", treenodelist.stream().count()); - return data; - } - -// public List getExcelPunitTreeTea(Integer userid, Integer year, Integer term, Integer schId) -// { -// List list=new ArrayList<>(); -// -// List treenodelist= getPunitList(7,userid,year,term,schId); -// -// for (Map nmap:treenodelist) -// { -// ExcelPunitTreeTea excelPunitTreeTea=new ExcelPunitTreeTea(); -// excelPunitTreeTea.setCname(nmap.get("cname").toString()); -// List teaNames=new ArrayList<>(); -// if(nmap.get("tealist")!=null) -// { -// List tealist=(List)nmap.get("tealist"); -// for (Map tmap:tealist) -// { -// teaNames.add(tmap.get("teaName").toString()); -// } -// } -// excelPunitTreeTea.setTeaNames(String.join(",",teaNames)); -// list.add(excelPunitTreeTea); -// } -// return list; -// } - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitQuestionService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitQuestionService.java deleted file mode 100644 index dcd9483..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitQuestionService.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.PunitQuestionRepository; -import com.bestsch.classicalchinese.entity.PunitQuestion; -import com.bestsch.classicalchinese.enums.DifficultLevel; -import com.bestsch.classicalchinese.enums.QuestionType; -import com.bestsch.classicalchinese.service.IPunitQuestionService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class PunitQuestionService implements IPunitQuestionService { - - @Autowired - private PunitQuestionRepository punitQuestionRepository; - - @Autowired - private BschQuestionService bschQuestionService; - - - public void save(PunitQuestion entity) { - punitQuestionRepository.save(entity); - } - - public void saveAll(List entitys) { - punitQuestionRepository.saveAll(entitys); - } - - public Optional findOne(Integer id,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("id"),id)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitQuestionRepository.findOne(specification); - } - - - public List findSchAll(Integer nodeId, Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "sort"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitQuestionRepository.findAll(specification,sort); - } - - public List findNoteAll(Integer nodeId,Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "sort"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitQuestionRepository.findAll(specification,sort); - } - - public List findSchAll(Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "sort"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitQuestionRepository.findAll(specification,sort); - } - - - public void deleteAll(List entitys) { - punitQuestionRepository.deleteAll(entitys); - } - - public List findMapAll(Integer nodeId,Integer schId){ - List questionMapList=new ArrayList<>(); - List questionList=findSchAll(nodeId,schId); - for (PunitQuestion pram:questionList) - { - Map map = new HashMap(); - map.put("id", pram.getId()); - map.put("name", pram.getName()); - map.put("config", pram.getConfig()); - map.put("answer", pram.getAnswer()); - map.put("solve", pram.getSolve()); - - Map qtMap = new HashMap(); - qtMap.put("id",pram.getQuestionTypeId()); - qtMap.put("name", QuestionType.nameById(pram.getQuestionTypeId())); - qtMap.put("cdate",new Date()); - map.put("questionType",qtMap); - - Map dlMap = new HashMap(); - dlMap.put("id",pram.getDifficultLevelId()); - dlMap.put("name", DifficultLevel.nameById(pram.getDifficultLevelId())); - - map.put("difficultLevel",dlMap); - - map.put("solveQuestionFiles",new ArrayList<>()); - map.put("questionTypeId", pram.getQuestionTypeId()); - map.put("difficultLevelId", pram.getDifficultLevelId()); - map.put("pId",pram.getPId()); - questionMapList.add(map); - } - return questionMapList; - } - - //初始化 - public void initialization(Integer year,Integer schId) - { - - } - - private List findTextbookSchAll(Integer textbookId,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - predicates.add(criteriaBuilder.equal(root.get("textbookId"),textbookId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitQuestionRepository.findAll(specification); - } - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitStuAnswerService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitStuAnswerService.java deleted file mode 100644 index 0af43f4..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitStuAnswerService.java +++ /dev/null @@ -1,699 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import cn.hutool.core.date.DateUtil; -import com.alibaba.fastjson.JSONArray; -import com.bestsch.classicalchinese.Repository.PunitLeadlearningRepository; -import com.bestsch.classicalchinese.Repository.PunitQuestionRepository; -import com.bestsch.classicalchinese.Repository.PunitStuAnswerRepository; -import com.bestsch.classicalchinese.Repository.VideoExplanationRepository; -import com.bestsch.classicalchinese.baidu.AipOcrComponent; -import com.bestsch.classicalchinese.entity.*; -import com.bestsch.classicalchinese.enums.AnswerStatus; -import com.bestsch.classicalchinese.enums.ReviewStatus; -import com.bestsch.classicalchinese.enums.Subject; -import com.bestsch.classicalchinese.enums.QuestionType; -import com.bestsch.classicalchinese.model.ClassInfo; -import com.bestsch.classicalchinese.model.vo.PunitNodeStuQuestion; -import com.bestsch.classicalchinese.model.vo.SubmitStuQuestionVo; -import com.bestsch.classicalchinese.service.IPunitStuAnswerService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.com.ZiyuankuService; -import com.bestsch.classicalchinese.utils.ListMapSortUtil; -import com.bestsch.classicalchinese.utils.ModelMapperUtil; -import com.bestsch.classicalchinese.utils.OtherUtil; -import com.bestsch.classicalchinese.utils.PageUtil; -import com.bestsch.utils.BschUtils; -import com.bestsch.utils.DException; -import org.apache.commons.lang.StringUtils; -import org.apache.http.client.utils.DateUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -@Service -public class PunitStuAnswerService implements IPunitStuAnswerService { - - @Autowired - private PunitStuAnswerRepository punitStuAnswerRepository; - - @Autowired - private PunitLeadlearningRepository punitLeadlearningRepository; - - @Autowired - private PunitQuestionRepository punitQuestionRepository; - - @Autowired - private VideoExplanationRepository videoExplanationRepository; - - @Autowired - private PunitLeadlearningService punitLeadlearningService; - @Autowired - private PunitQuestionService punitQuestionService; - - @Autowired - private ClassService classService; - - @Autowired - private AipOcrComponent aipOcrComponent; - - - @Autowired - private BschLeadlearningService bschLeadlearningService; - - @Autowired - private BschKnowledgeService bschKnowledgeService; - - @Autowired - private ZiyuankuService ziyuankuService; - - public void save(PunitStuAnswer entity) { - punitStuAnswerRepository.save(entity); - } - - public List findAll(Integer stuId,List nodeIds,Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "cDate"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("stuId"),stuId)); - predicates.add(criteriaBuilder.in(root.get("nodeId")).value(nodeIds)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findAll(specification,sort); - } - - public List findAll(Integer stuId, Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "cDate"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("stuId"),stuId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findAll(specification,sort); - } - - public List findClassAll(Integer nodeId,Integer classId, Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "cDate"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("classId"),classId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findAll(specification,sort); - } - - public List findClassAll(Integer classId,Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "cDate"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("classId"),classId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findAll(specification,sort); - } - - public List findClassAll(Integer classId,Date startDate, Date endDate,Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "cDate"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("classId"),classId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - - if (startDate != null && endDate != null) { - // 筛选在开始日期和结束日期之间的记录 - predicates.add(criteriaBuilder.between(root.get("cDate"), startDate, endDate)); - } else if (startDate != null) { - // 只筛选开始日期之后的记录 - predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("cDate"), startDate)); - } else if (endDate != null) { - // 只筛选结束日期之前的记录 - predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("cDate"), endDate)); - } - - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findAll(specification,sort); - } - - public List findStuAll(Integer stuId,String startDate,String endDate, Integer schId){ - Sort sort = Sort.by(Sort.Direction.ASC, "cDate"); - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("stuId"),stuId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - if (StringUtils.isNotEmpty(startDate)&&StringUtils.isNotEmpty(endDate)) { - // 筛选在开始日期和结束日期之间的记录 - predicates.add(criteriaBuilder.between(root.get("cDate"),DateUtils.parseDate(startDate) , DateUtils.parseDate(endDate))); - } else if (StringUtils.isNotEmpty(startDate)) { - // 只筛选开始日期之后的记录 - predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("cDate"), DateUtils.parseDate(startDate))); - } else if (StringUtils.isNotEmpty(endDate)) { - // 只筛选结束日期之前的记录 - predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("cDate"), DateUtils.parseDate(endDate))); - } - - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findAll(specification,sort); - } - - - public Map getPageBySchId(int schId,Integer nodeId,Integer stuId, List status, Pageable pageable) { - Page> lists = punitLeadlearningRepository.findPageBySchId(schId,nodeId,stuId,status, pageable); - //当前学年学期 - Map data = new HashMap<>(); - data.put("content",OtherUtil.mapToList(lists.getContent(),PunitNodeStuQuestion.class)); - data.put("total", lists.getTotalElements()); - return data; - } - - public Map getStuPageByList(int textbookId,int schId,Integer nodeId,Integer stuId,Date startDate, List status, Pageable pageable) { - //Page> lists = punitLeadlearningRepository.findPageBySchId(schId,gradeId,subjectId,nodeId,stuId,status, pageable); - - List treenodelist= bschKnowledgeService.getEndNodeList(textbookId); - - if(nodeId!=null) - treenodelist=treenodelist.stream().filter(s->(","+s.get("path").toString()).contains(","+nodeId+",")).collect(Collectors.toList()); - - List schLeadlearning=punitLeadlearningService.findSchAll(schId); - - List NodeQcount=punitQuestionRepository.findByNodeQcount(schId); - - List stuAnswersList=findAll(stuId,schId); - - //Integer textbookId= bschZiYuanTreeService.findTextbookId(nodeId); - for (Map map:treenodelist) - { - Integer qcount=0; - String mnodeId=map.get("id").toString(); - - Optional qOptional= NodeQcount.stream().filter(s->s.get("node_id").toString().equals(mnodeId)).findFirst(); - if(qOptional.isPresent()) - { - qcount=Integer.parseInt(qOptional.get().get("qcount").toString()); - } - List stuAnswersNodeList= stuAnswersList.stream().filter(s->s.getNodeId().toString().equals(mnodeId)).collect(Collectors.toList()); - - long duicount=stuAnswersNodeList.stream().filter(s->s.getStatus().equals(1)).count(); - long cuocount=stuAnswersNodeList.stream().filter(s->s.getStatus().equals(2)).count(); - long elecount=stuAnswersNodeList.stream().filter(s->!s.getStatus().equals(1)&&!s.getStatus().equals(2)).count(); - - Integer is_review=0; - Optional stuAnswersNodeOptional= stuAnswersNodeList.stream().findFirst(); - Date reviewDate=null; - if(stuAnswersNodeOptional.isPresent()) - { - is_review= stuAnswersNodeOptional.get().getIsReview(); - reviewDate=is_review==1?stuAnswersNodeOptional.get().getCDate():null; - } - String Leadlearning=""; - Optional LeadlearningOptional= schLeadlearning.stream().filter(s->s.getNodeId().toString().equals(mnodeId)&&Objects.equals(s.getTextbookId(), textbookId)).findFirst(); - - if(LeadlearningOptional.isPresent()) - { - Leadlearning=LeadlearningOptional.get().getContent(); - } - if(StringUtils.isEmpty(Leadlearning)) - { - Optional bschLeadlearningOpt= bschLeadlearningService.findOne(textbookId,Integer.parseInt(mnodeId)); - Leadlearning= bschLeadlearningOpt.map(BschLeadlearning::getContent).orElse(""); - } - map.put("qcount",qcount); - map.put("stucount",stuAnswersNodeList.stream().count()); - map.put("duicount",duicount); - map.put("cuocount",cuocount); - map.put("elecount",elecount); - //map.put("askcount",askcount); - map.put("is_review",is_review); - map.put("reviewDate", DateUtil.formatDate(reviewDate)); - map.put("Leadlearning",Leadlearning); - } - - treenodelist=treenodelist.stream().filter(s->s.get("is_review")!=null&&status.contains(Integer.parseInt(s.get("is_review").toString()))).collect(Collectors.toList()); - - if(startDate!=null) - treenodelist=treenodelist.stream().filter(s->s.get("reviewDate")!=null&&s.get("reviewDate").toString().equals(DateUtil.formatDate(startDate))).collect(Collectors.toList()); - - ListMapSortUtil.sortByIntegerKey(treenodelist, "ord"); - - List pagelist= PageUtil.paginate(treenodelist,pageable); - - Map data = new HashMap<>(); - data.put("content",pagelist); - data.put("total", treenodelist.stream().count()); - return data; - } - - public Map getTeaPageBySchId(int schId,Integer classId,Integer nodeId, Pageable pageable) { - Page> lists = punitLeadlearningRepository.findTeaPageBySchId(schId,nodeId,classId,pageable); - //当前学年学期 - Map data = new HashMap<>(); - data.put("content",OtherUtil.mapToList(lists.getContent(),PunitNodeStuQuestion.class)); - data.put("total", lists.getTotalElements()); - return data; - } - - public Optional findOne(Integer nodeId,Integer qId,Integer stuId,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("questionId"),qId)); - predicates.add(criteriaBuilder.equal(root.get("stuId"),stuId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return punitStuAnswerRepository.findOne(specification); - } - - - public Map getPunitNodeInfo(int textbookId,int schId,Integer userId,Integer nodeId) - { - Map map = new HashMap(); - - //Integer textbookId= bschZiYuanTreeService.findTextbookId(nodeId); - - Optional LeadlearningOpt = punitLeadlearningService.findOne(textbookId,nodeId,schId); - List QuestionList = punitQuestionService.findNoteAll(nodeId,schId); - //if(!LeadlearningOpt.isPresent()) throw new DException("id query record is null!"); - - String content=LeadlearningOpt.isPresent()?LeadlearningOpt.get().getContent():null; - if(StringUtils.isEmpty(content)){ - Optional bschLeadlearningOpt= bschLeadlearningService.findOne(textbookId,nodeId); - content= bschLeadlearningOpt.map(BschLeadlearning::getContent).orElse(""); - } - map.put("content",content); - - - //List courseTrees = (List)ziyuankuService.getCourseTree_cache(schId, gradeId, year, term, subjectId); - // List clist=ziyuankuService.getNodeList(courseTrees,0); - //Optional nodeFirst=clist.stream().filter(s->s.get("id").toString().equals(nodeId.toString())).findFirst(); - //Integer pid=nodeFirst.isPresent()?Integer.parseInt(nodeFirst.get().get("pid").toString()):0; - //Optional pNodeFirst=clist.stream().filter(s->s.get("id").toString().equals(pid.toString())).findFirst(); - - List nodeIds=Arrays.asList(nodeId); - List stuAnswersList=findAll(userId,nodeIds,schId); - Boolean isReview=stuAnswersList.stream().filter(a->(a.getIsReview()==null?0:a.getIsReview())==1).count()>0; - map.put("isReview",isReview); - map.put("cDate",LeadlearningOpt.isPresent()?LeadlearningOpt.get().getCDate():null); - map.put("wcDate",isReview?stuAnswersList.stream().filter(a->a.getIsReview().equals(1)).findFirst().get().getCDate():null); - map.put("ydt",stuAnswersList.stream().filter(s->s.getCDate()!=null).count()>0); - map.put("qcount",QuestionList.stream().count()); - - //map.put("name",((pNodeFirst.isPresent()?pNodeFirst.get().get("name"):""))+" "+LeadlearningOpt.map(PunitLeadlearning::getName).orElse("")); - //List nlist= bschZiYuanTreeService.getTreeNodeList(textbookId); - List nlist = bschKnowledgeService.getEndNodeList(textbookId); - Optional mapOpt= nlist.stream().filter(s->Objects.equals(nodeId.toString(),s.get("id").toString())).findFirst(); - map.put("name",mapOpt.isPresent()?mapOpt.get().get("name"):""); - map.put("cname",mapOpt.isPresent()?(String.join("/",(List)mapOpt.get().get("names"))):""); - return map; - } - - public Map getStuSeeQuestion(Integer nodeId,int stuId,int schId) - { - Map map=new HashMap(); - - List punitQuestionList = punitQuestionService.findMapAll(nodeId,schId); - - for (Map item:punitQuestionList) - { - item.put("bigQuestionId",nodeId); - } - map.put("name","专项"); - map.put("zuoyeQestionList",punitQuestionList); - map.put("zuoyeSet","[1,2]"); - map.put("paperType",2); - - List bigQuestions=new ArrayList<>(); - Map bigQuestion=new HashMap(); - bigQuestion.put("id",nodeId); - bigQuestion.put("zuoyeId",nodeId); - bigQuestions.add(bigQuestion); - map.put("bigQuestions",bigQuestions); - List nodeIds=Arrays.asList(nodeId); - List punitStuAnswerList=findAll(stuId,nodeIds,schId); - - List userZuoyes=new ArrayList<>(); - Map userZuoye=new HashMap(); - userZuoye.put("id",nodeId); - userZuoye.put("userId",stuId); - List userAnswers=new ArrayList<>(); - for (PunitStuAnswer item:punitStuAnswerList) - { - Map userAnswer=new HashMap(); - userAnswer.put("id", item.getId()); - userAnswer.put("zuoyeQestId", item.getQuestionId()); - userAnswer.put("userZuoyeId",nodeId); - userAnswer.put("answer", item.getStuAnalysis()); - userAnswer.put("status",item.getStatus()); - userAnswer.put("isReview",item.getIsReview()); - userAnswer.put("zuoyeQuestionFiles",item); - userAnswer.put("solveZuoyeQuestionFiles",new ArrayList<>()); - userAnswers.add(userAnswer); - } - userZuoye.put("userAnswers",userAnswers); - userZuoyes.add(userZuoye); - - map.put("userZuoyes",userZuoyes); - - return map; - } - public List findStuAnswerRecordAll(Integer nodeId,int stuId,int schId) - { - List stuAnswers=new ArrayList<>(); - - List nodeIds=Arrays.asList(nodeId); - List punitStuAnswerList=findAll(stuId,nodeIds,schId); - List punitQuestionList = punitQuestionService.findMapAll(nodeId,schId); - - for (PunitStuAnswer item:punitStuAnswerList) - { - Optional OptQuestion=punitQuestionList.stream().filter(s->s.get("id").toString().equals(item.getQuestionId().toString())).findFirst(); - //record 最后一次做题记录 - Map stuAnswer=new HashMap(); - List record=new ArrayList<>(); - Map stuAnswerRecord=new HashMap(); - stuAnswerRecord.put("answer",item.getStuAnalysis()); - stuAnswerRecord.put("answerFile",new ArrayList<>()); - stuAnswerRecord.put("answerpyFile",new ArrayList<>()); - record.add(stuAnswerRecord); - stuAnswer.put("record",record); - Map userAnswer=new HashMap(); - userAnswer.put("id",item.getId()); - userAnswer.put("zuoyeQestId",item.getQuestionId()); - userAnswer.put("userZuoyeId",nodeId); - userAnswer.put("answer",item.getStuAnalysis()); - userAnswer.put("tkStatus",item.getTkStatus()); - userAnswer.put("status",item.getStatus()); - userAnswer.put("isReview",item.getIsReview()); - userAnswer.put("zuoyeQuestionFiles",new ArrayList<>()); - userAnswer.put("solveZuoyeQuestionFiles",new ArrayList<>()); - userAnswer.put("zuoyeQestion",OptQuestion); - stuAnswer.put("userAnswer",userAnswer); - stuAnswers.add(stuAnswer); - } - return stuAnswers; - } - - - public void saveStuAnswerRecord(SubmitStuQuestionVo model, - int stuId,String stuName,int groupId,int year,int term, int schId) - { - Optional OptStuAnswer= findOne(model.nodeId,model.qId,stuId,schId); - PunitStuAnswer punitStuAnswer=new PunitStuAnswer(); - if(OptStuAnswer.isPresent()) - punitStuAnswer= ModelMapperUtil.map(OptStuAnswer.get(), PunitStuAnswer.class); - - if(StringUtils.isEmpty(model.answer)) throw new DException("答案不能为空!"); - - punitStuAnswer.setStuAnalysis(model.answer); - punitStuAnswer.setQuestionId(model.qId); - punitStuAnswer.setNodeId(model.nodeId); - punitStuAnswer.setSchId(schId); - punitStuAnswer.setYear(year); - punitStuAnswer.setTerm(term); - punitStuAnswer.setStuId(stuId); - punitStuAnswer.setStuName(stuName); - ClassInfo classInfo = classService.getClassInfo(groupId); - if(classInfo!=null) - { - punitStuAnswer.setCDate(new Date()); - punitStuAnswer.setStuGradeId(classInfo.getGradeId()); - punitStuAnswer.setClassId(classInfo.getClassId()); - punitStuAnswer.setGClassName(classInfo.getClassName()); - } - //Optional punitQuestion = punitQuestionService.findOne(model.qId,schId); - //if(!punitQuestion.isPresent()) throw new DException("题目不存在!"); - - save(punitStuAnswer); - } - - public void correctStuAnswer(Integer stuId,int schId,Integer nodeId) - { - List nodeIds=Arrays.asList(nodeId); - List stuAnswerList= findAll(stuId,nodeIds,schId); - - for (PunitStuAnswer punitStuAnswer:stuAnswerList) - { - Optional punitQuestion = punitQuestionService.findOne(punitStuAnswer.getQuestionId(),schId); - if(punitQuestion.isPresent()) - { - if (punitQuestion.get().getQuestionTypeId() == QuestionType.I.getId() || punitQuestion.get().getQuestionTypeId() == QuestionType.III.getId()) { - singleChoiceAnswer(punitQuestion.get(), punitStuAnswer); - } else if (punitQuestion.get().getQuestionTypeId() == QuestionType.II.getId()) { - multipleChoiceAnswer(punitQuestion.get(), punitStuAnswer); - } else if (punitQuestion.get().getQuestionTypeId() == QuestionType.VI.getId()) { - blankFillingAnswer(punitQuestion.get(), punitStuAnswer); - } else if (punitQuestion.get().getQuestionTypeId() == QuestionType.IV.getId()) { - punitStuAnswer.setStatus(1); - // writtenQuestionAnswer(punitQuestion.get(), punitStuAnswer); - } - punitStuAnswer.setIsReview(1); - save(punitStuAnswer); - } - } - } - - - - //单选题 - private void singleChoiceAnswer(PunitQuestion pQuestion, PunitStuAnswer punitStuAnswer) - { - //单选题,判断题 - if (pQuestion.getAnswer().equals(punitStuAnswer.getStuAnalysis())) - { - punitStuAnswer.setStatus(AnswerStatus.I.getId()); - punitStuAnswer.setScore(pQuestion.getScore()); - } - else - { - punitStuAnswer.setStatus(AnswerStatus.II.getId()); - punitStuAnswer.setScore(0.0); - } - } - private void multipleChoiceAnswer(PunitQuestion pQuestion, PunitStuAnswer punitStuAnswer) - { - //多选题得分规则 - //全对得满分 - //多选得0分 - //漏选:如果设置了漏选得分,就按设置值 - //漏选:如果未设置漏选得分,用平均值乘选择个数 - - //正确答案 - List rightAnswerList = com.alibaba.fastjson.JSONArray.parseArray(pQuestion.getAnswer(), Integer.class); - //用户答题 - List userAnswerList = com.alibaba.fastjson.JSONArray.parseArray(punitStuAnswer.getStuAnalysis(), Integer.class); - - //选择正确的项 - List rightSelect = rightAnswerList.stream().filter(userAnswerList::contains).collect(Collectors.toList()); - //多选的项 - List excessSelect = userAnswerList.stream().filter(num -> !rightAnswerList.contains(num)).collect(Collectors.toList()); - - if (BschUtils.isNotEmpty(excessSelect) || BschUtils.isEmpty(rightSelect)) - { - //多选或未选,判错 - punitStuAnswer.setStatus(AnswerStatus.II.getId()); - //得0分 - punitStuAnswer.setScore(0.0); - } - else - { - if (rightSelect.size() == rightAnswerList.size()) - { - //选对数量匹配,判对 - punitStuAnswer.setStatus(AnswerStatus.I.getId()); - //满分 - punitStuAnswer.setScore(pQuestion.getScore()); - } - else if (rightSelect.size() < rightAnswerList.size()) - { - //漏选,半对 - punitStuAnswer.setStatus(AnswerStatus.III.getId()); - //计算得分 - double score = pQuestion.getScore() / rightAnswerList.size() * rightSelect.size();//单个选项分数 - punitStuAnswer.setScore(score); - } - else - { - //异常,一般不会有这种条件 - punitStuAnswer.setStatus(AnswerStatus.II.getId()); - punitStuAnswer.setScore(0.0); - } - } - } - - //填空题订正 - private void blankFillingAnswer(PunitQuestion pQuestion, PunitStuAnswer punitStuAnswer) - { - //填空题正确答案有两种情况,一种是字符串数组的数组,一种是字符串数组 - //两种情况统一到‘字符串数组的数组’ - - //正确答案 - List> rightAnswerList = tkRightAnswerList(pQuestion.getAnswer()); - - //用户答题 - List userAnswerList = com.alibaba.fastjson.JSONArray.parseArray(punitStuAnswer.getStuAnalysis(), String.class); - - //boolean needTeachReview = false;//是否需要教师手动批改,在错误情况下,有公式或图片的,转老师批 - int rightCount = 0;//答对的空数 - double totalScore = 0;//总得分 - List tkStatus = new ArrayList<>(); - - if (BschUtils.isNotEmpty(rightAnswerList) && BschUtils.isNotEmpty(userAnswerList)) - { - //单项得分,每空平均分配 - Double fenshu = (pQuestion.getScore()==null?0:pQuestion.getScore()) / rightAnswerList.size(); - for (int i = 0; i < rightAnswerList.size() && i < userAnswerList.size(); i++) - { - List rightAnswers = rightAnswerList.get(i); - String answer = userAnswerList.get(i); - answer = unescapeHtml(answer); - - boolean imgOrFomula = containImgOrFomula(answer); - - if (imgOrFomula) { - // 语文题目的填空,并且学生是手写的答案,调用ocr接口识别手写的文字 - // 使用正则表达式匹配 src 属性的值 - String regex = "src=\"([^\"]+)\""; - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(answer); - // 如果匹配到了,则输出 src 属性的值 - if (matcher.find()) { - String imageSrc = matcher.group(1); - answer = aipOcrComponent.handwriting(imageSrc); - } - } - - if (rightAnswers.contains(answer.trim())) - { - rightCount++; - totalScore += fenshu; - tkStatus.add(AnswerStatus.I.getId()); - } - else - { - tkStatus.add(AnswerStatus.II.getId()); - } - } - } - else - { - for (int i = 0; i < userAnswerList.size(); i++) - tkStatus.add(AnswerStatus.II.getId()); - } - punitStuAnswer.setTkStatus(tkStatus.toString()); - - //答对数与正确答案数量相同判对 - if (rightCount == rightAnswerList.size()) - { - punitStuAnswer.setStatus(AnswerStatus.I.getId()); - punitStuAnswer.setScore(pQuestion.getScore()); - } - else - { - if (rightCount > 0) - punitStuAnswer.setStatus(AnswerStatus.III.getId());//半对 - else - punitStuAnswer.setStatus(AnswerStatus.II.getId());//错误 - - punitStuAnswer.setScore(totalScore); - punitStuAnswer.setIsReview(ReviewStatus.REVIEW.getId()); - - } - } - - //解答题订正 -// private void writtenQuestionAnswer(PunitQuestion pQuestion, PunitStuAnswer punitStuAnswer) -// { -// //List scoreSets = zuoyeQuestion.getScoreSets(); -// -// Optional punitQuestionFirst= punitQuestionService.findOne(pQuestion.getId(),pQuestion.getSchId()); -// -// if (punitQuestionFirst.isPresent()) -// { -// double totalScore = 0; -// for (ScoreSet scoreSet : scoreSets) -// { -// String keyword2 = scoreSet.getKeyword(); -// String keyword = keyword2.replaceAll("\\\\", "\\\\\\\\"); -// double score = pQuestion.getScore() * scoreSet.getScore() / 100;//单个选项分数 -// if (punitStuAnswer.getStuAnalysis().contains(keyword)) -// totalScore += score; -// } -// if (pQuestion.getScore().equals(totalScore)) -// { -// punitStuAnswer.setStatus(AnswerStatus.I.getId()); -// punitStuAnswer.setScore(pQuestion.getScore()); -// } -// else -// { -// if (totalScore > 0) -// punitStuAnswer.setStatus(AnswerStatus.III.getId()); -// else -// punitStuAnswer.setStatus(AnswerStatus.II.getId()); -// punitStuAnswer.setScore(totalScore); -// } -// punitStuAnswer.setIsReview(ReviewStatus.REVIEW.getId()); -// } -// else -// { -// punitStuAnswer.setIsReview(ReviewStatus.UNREVIEW.getId()); -// } -// } - - public List> tkRightAnswerList(String answerStr) - { - List> rightAnswerList = new ArrayList<>(); - JSONArray tmpJsonArray = JSONArray.parseArray(answerStr); - for (Object object: tmpJsonArray) - { - if (object instanceof JSONArray) - rightAnswerList.add(((JSONArray)object).toJavaList(String.class)); - else - rightAnswerList.add(Collections.singletonList(object.toString())); - } - - //去除前后空格 - List> result = new ArrayList<>(); - for (List list: rightAnswerList) - { - List newList = new ArrayList<>(); - for (String answer: list) - newList.add(unescapeHtml(answer)); - result.add(newList); - } - - return result; - } - public String unescapeHtml(String text) - { - return BschUtils.trim(BschUtils.unescapeHtml(text)); - } - - //字符串有图片或公式 - public boolean containImgOrFomula(String text) - { - if (text.contains("= 0) - { - inx = text.indexOf("\\)", inx + 3); - if (inx > 0) return true; - } - - return false; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitZiYuanTreeTeaService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitZiYuanTreeTeaService.java deleted file mode 100644 index 6cd19e2..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/PunitZiYuanTreeTeaService.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.bestsch.classicalchinese.Repository.PunitZiYuanTreeTeaRepository; -import com.bestsch.classicalchinese.entity.PunitZiYuanTreeTea; -import com.bestsch.classicalchinese.service.IPunitZiYuanTreeTeaService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.stereotype.Service; - -import javax.persistence.criteria.Predicate; -import java.util.*; - -@Service -public class PunitZiYuanTreeTeaService implements IPunitZiYuanTreeTeaService { - - @Autowired - private PunitZiYuanTreeTeaRepository PunitZiYuanTreeTeaRepository; - - - public void save(PunitZiYuanTreeTea entity) { - PunitZiYuanTreeTeaRepository.save(entity); - } - - public void saveAll(List entitys) { - PunitZiYuanTreeTeaRepository.saveAll(entitys); - } - - public List findNodeAll(Integer year,Integer term,Integer gradeId,String subId,Integer nodeId,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.equal(root.get("nodeId"),nodeId)); - predicates.add(criteriaBuilder.equal(root.get("year"),year)); - predicates.add(criteriaBuilder.equal(root.get("term"),term)); - predicates.add(criteriaBuilder.equal(root.get("gradeId"),gradeId)); - predicates.add(criteriaBuilder.equal(root.get("subId"),subId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitZiYuanTreeTeaRepository.findAll(specification); - } - - public List findNodeIdsAll(Integer year,Integer term,Integer gradeId,String subId,List nodeIds,Integer schId){ - Specification specification = (Specification) (root, criteriaQuery, criteriaBuilder) -> { - List predicates = new ArrayList<>(); - predicates.add(criteriaBuilder.in(root.get("nodeId")).value(nodeIds)); - predicates.add(criteriaBuilder.equal(root.get("year"),year)); - predicates.add(criteriaBuilder.equal(root.get("term"),term)); - predicates.add(criteriaBuilder.equal(root.get("gradeId"),gradeId)); - predicates.add(criteriaBuilder.equal(root.get("subId"),subId)); - predicates.add(criteriaBuilder.equal(root.get("schId"),schId)); - return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); - }; - return PunitZiYuanTreeTeaRepository.findAll(specification); - } - - public void deleteAll(List entitys) { - PunitZiYuanTreeTeaRepository.deleteAll(entitys); - } - - - public void saveTreeNodeTea(Integer userid,Integer year,Integer term,Integer gradeId,String subId,Integer nodeId,List teaIds,Integer schId) - { - - List list=findNodeAll(year,term,gradeId,subId,nodeId,schId); - - if(list.stream().count()>0) - deleteAll(list); - - List entitys=new ArrayList<>(); - Date date=new Date(); - for (Integer tid:teaIds) - { - PunitZiYuanTreeTea ent=new PunitZiYuanTreeTea(); - ent.setNodeId(nodeId); - ent.setTeaId(tid); - ent.setCDate(date); - ent.setCUserId(userid); - ent.setSchId(schId); - entitys.add(ent); - } - saveAll(entitys); - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/service/impl/StatisticsService.java b/src/main/java/com/bestsch/classicalchinese/service/impl/StatisticsService.java deleted file mode 100644 index 6c15eef..0000000 --- a/src/main/java/com/bestsch/classicalchinese/service/impl/StatisticsService.java +++ /dev/null @@ -1,363 +0,0 @@ -package com.bestsch.classicalchinese.service.impl; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.bestsch.classicalchinese.Repository.PunitLeadlearningRepository; -import com.bestsch.classicalchinese.baidu.AipOcrComponent; -import com.bestsch.classicalchinese.entity.PunitLeadlearning; -import com.bestsch.classicalchinese.entity.PunitQuestion; -import com.bestsch.classicalchinese.entity.PunitStuAnswer; -import com.bestsch.classicalchinese.enums.QuestionType; -import com.bestsch.classicalchinese.enums.Subject; -import com.bestsch.classicalchinese.model.YearSemester; -import com.bestsch.classicalchinese.model.vo.PunitNodeStuQuestion; -import com.bestsch.classicalchinese.service.IStatisticsService; -import com.bestsch.classicalchinese.service.com.ClassService; -import com.bestsch.classicalchinese.service.com.CommonService; -import com.bestsch.classicalchinese.utils.OtherUtil; -import com.bestsch.utils.BschUtils; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; - -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -@Service -public class StatisticsService implements IStatisticsService { - - - @Autowired - private CommonService commonService; - - @Autowired - private PunitQuestionService punitQuestionService; - - @Autowired - private AipOcrComponent aipOcrComponent; - - @Autowired - private PunitStuAnswerService punitStuAnswerRService; - - @Autowired - private PunitLeadlearningRepository punitLeadlearningRepository; - - @Autowired - private PunitLeadlearningService punitLeadlearningService; - - @Autowired - private ClassService classService; - - public Map getClassWcqk(int schId,Integer noteId,Integer classId){ - - //获取当前班级学生 (获取历史学生待定) - List classStuList=commonService.getClassStuList(schId,classId).stream() - .map(map -> { - Map newMap = new HashMap<>(map); - newMap.remove("classId"); - newMap.remove("photo"); - newMap.remove("xuehaoId"); - return newMap; - }) - .collect(Collectors.toList()); - - //章节题目 - List noteQuestions=punitQuestionService.findNoteAll(noteId,schId); - - //班级答题情况 - List classPunitAnswerList=punitStuAnswerRService.findClassAll(noteId,classId,schId) - .stream().filter(s->s.getIsReview()!=null&&s.getIsReview().equals(1)).collect(Collectors.toList()); - - List ystuIds=new ArrayList<>(); - List wstuIds=new ArrayList<>(); - - if(noteQuestions.stream().count()>0){ - for (Map stu:classStuList) - { - Integer stuId=Integer.parseInt(stu.get("id").toString()); - if(classPunitAnswerList.stream().filter(s->s.getStatus()>0&&s.getStuId().equals(stuId)).count()>=noteQuestions.stream().count()) - ystuIds.add(stuId); - else - wstuIds.add(stuId); - } - } - - - Map map=new HashMap(); - map.put("yCount",ystuIds.stream().count()); - map.put("yList",ystuIds.stream().count()==0?new Object[]{}:classStuList.stream().filter(s->ystuIds.contains(Integer.parseInt(s.get("id").toString())))); - map.put("wCount",wstuIds.stream().count()); - map.put("wList",wstuIds.stream().count()==0?new Object[]{}:classStuList.stream().filter(s->wstuIds.contains(Integer.parseInt(s.get("id").toString())))); - - List cyclassStuList=classStuList.stream().filter(s->ystuIds.contains(Integer.parseInt(s.get("id").toString()))).collect(Collectors.toList()); - - - List questionList=new ArrayList<>(); - for (PunitQuestion ques:noteQuestions) - { - Map qMap=new HashMap(); - qMap.put("id",ques.getId()); - qMap.put("typeId", ques.getQuestionTypeId()); - qMap.put("typeName", QuestionType.nameById(ques.getQuestionTypeId())); - qMap.put("name",ques.getName()); - qMap.put("answer",ques.getAnswer()); - - List qAccuracys=new ArrayList<>(); - for (Map stu:cyclassStuList){ - - Optional stuAnswerOptional=classPunitAnswerList.stream(). - filter(s->s.getStuId().toString().equals(stu.get("id").toString())&& - s.getQuestionId().equals(ques.getId())).findFirst(); - - if(stuAnswerOptional.isPresent()) - { - if(stuAnswerOptional.get().getStatus().equals(1)) - qAccuracys.add(1.0); - else if(stuAnswerOptional.get().getStatus().equals(3)) - qAccuracys.add(0.5); - else - qAccuracys.add(0.0); - }else - qAccuracys.add(0.0); - } - double zbCount=qAccuracys.stream().mapToDouble(Double::doubleValue).sum(); - double zsCount=(double)qAccuracys.stream().count(); - String accuracy2f =getNumberBfb2f(zbCount,zsCount); - - qMap.put("accuracy",accuracy2f); - - List qPunitStuAnswerList=classPunitAnswerList.stream().filter(s->s.getQuestionId().equals(ques.getId())).collect(Collectors.toList()); - - - qMap.put("config",ques.getConfig()); - qMap.put("answer",ques.getAnswer()); - - qMap.put("analyzeList",getQuestionStusAnswer(ques,qPunitStuAnswerList,cyclassStuList)); - - questionList.add(qMap); - } - map.put("questionList",questionList); - return map; - } - - // - public List getQuestionStusAnswer(PunitQuestion punitQuestion,List stuAnswerList,List classStuList) - { - List list=new ArrayList<>(); - //单选 - if (punitQuestion.getQuestionTypeId() == QuestionType.I.getId()||punitQuestion.getQuestionTypeId() == QuestionType.II.getId() || punitQuestion.getQuestionTypeId() == QuestionType.III.getId()) { - list= singleChoiceStatics(punitQuestion,stuAnswerList,classStuList); - } - //多选 - else if (punitQuestion.getQuestionTypeId() == QuestionType.VI.getId()) { - //填空题 - list= blankFillingStatics(punitQuestion,stuAnswerList,classStuList); - } else if (punitQuestion.getQuestionTypeId() == QuestionType.IV.getId()) { - //解答题 - // list= writtenQuestionStatics(punitQuestion,stuAnswerList,classStuList); - } - return list; - } - - public Map getStuPunitList(int schId,Integer stuId,List status,Pageable pageable){ - Page> lists = punitLeadlearningRepository.findPageBySchId(schId,null,stuId,status, pageable); - //当前学年学期 - Map data = new HashMap<>(); - data.put("content", OtherUtil.mapToList(lists.getContent(), PunitNodeStuQuestion.class)); - data.put("total", lists.getTotalElements()); - return data; - } - -// public Map getStuPunitList(int schId, Integer year, Integer term, Integer gradeId, String subjectId, Integer stuId,List status,Pageable pageable){ -// //Page> lists = punitLeadlearningRepository.findPageBySchId(schId,gradeId,subjectId,null,stuId,status, pageable); -// //当前学年学期 -// -// List nodeList = punitZiYuanTreeService.getTreeNodeList(userid, year, term, gradeId, subjectId, schId); -// -// List treemap=(List) commonService.getChapterWrongQuestNumTree(schId,userid,subjectId,gradeId,year,term,null); -// -// //List treeList=punitZiYuanTreeService.getTreeNodeNameList(treemap,0); -// LinkedList treeList=new LinkedList<>(); -// punitZiYuanTreeService.getTreeNodeNameList(treeList,treemap); -// -// List punitlist = new ArrayList<>(); -// for (Map nmap : nodeList) { -// if (nmap.get("tealist") != null) { -// List teas = (List) nmap.get("tealist"); -// if (role.equals(7)|| teas.stream().count() > 0) { -// if (role.equals(7) || teas.stream().filter(s -> s.get("teaId").toString().equals(userid.toString())).count() > 0) { -// Map pmap = new HashMap(); -// List nams=getNodeLinkName(nmap.get("id").toString(),treeList); -// pmap.put("id", nmap.get("id")); -// pmap.put("name",nmap.get("name")); -// pmap.put("cname",String.join(" ",nams)); -// pmap.put("names",nams); -// pmap.put("path", nmap.get("path")); -// punitlist.add(pmap); -// } -// } -// } -// } -// -// -// Map data = new HashMap<>(); -// data.put("content", OtherUtil.mapToList(lists.getContent(), PunitNodeStuQuestion.class)); -// data.put("total", lists.getTotalElements()); -// return data; -// } - - - private List singleChoiceStatics(PunitQuestion pQuestion,List stuAnswerList,List classStuList) - { - List qAnalyzeStus=new ArrayList<>(); - //单选题,判断题 - //获取答案 - List answers = JSONArray.parseArray(pQuestion.getAnswer(),Integer.class); - Map map = JSON.parseObject(pQuestion.getConfig(),Map.class); - List options = JSONArray.parseArray(JSON.toJSONString(map.get("options")),String.class); - - for (Integer i = 0; i < options.stream().count(); i++) { - Map optMap= new HashMap<>(); - optMap.put("option",options.get(i)); - Integer val=i; - List optStuIds=stuAnswerList.stream().filter(s->JSONArray.parseArray(s.getStuAnalysis(),Integer.class).get(0).equals(val)) - .map(s->s.getStuId().toString()).collect(Collectors.toList()); - List optStus=classStuList.stream().filter(s->optStuIds.contains(s.get("id").toString())).collect(Collectors.toList()); - optMap.put("stus",optStus); - - optMap.put("count",optStus.stream().count()); - optMap.put("correct",answers.get(0).equals(i)); - double zbCount=(double)optStus.stream().count(); - double zsCount=(double)classStuList.stream().count(); - String accuracy2f =getNumberBfb2f(zbCount,zsCount); - optMap.put("zb",accuracy2f); - qAnalyzeStus.add(optMap); - } - return qAnalyzeStus; - } - -// private List multipleChoiceStatics(PunitQuestion pQuestion,List stuAnswerList,List classStuList) -// { -// List answers = JSONArray.parseArray(pQuestion.getAnswer(),Integer.class); -// -// } - private List blankFillingStatics(PunitQuestion pQuestion,List stuAnswerList,List classStuList){ - - List qAnalyzeStus=new ArrayList<>(); - //填空题 - //获取答案 - //List answers = JSONArray.parseArray(pQuestion.getAnswer(),String.class); - List> rightAnswerList = punitStuAnswerRService.tkRightAnswerList(pQuestion.getAnswer()); - if (!BschUtils.isNotEmpty(rightAnswerList)) return qAnalyzeStus; - - List optStuIds=new ArrayList<>(); - for (int i = 0; i < rightAnswerList.stream().count(); i++) { - List rightAnswers = rightAnswerList.get(i); - - Map optdcMap= new HashMap<>(); - List option=rightAnswerList.get(i); - optdcMap.put("option", StringUtils.join(option,",")); - for (PunitStuAnswer stuA:stuAnswerList) - { - //学生答案 - List stuAnswers = JSONArray.parseArray(stuA.getStuAnalysis(), String.class); - String answer = stuAnswers.get(i); - answer = punitStuAnswerRService.unescapeHtml(answer); - - boolean imgOrFomula = punitStuAnswerRService.containImgOrFomula(answer); - - if (imgOrFomula) { - // 语文题目的填空,并且学生是手写的答案,调用ocr接口识别手写的文字 - // 使用正则表达式匹配 src 属性的值 - String regex = "src=\"([^\"]+)\""; - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(answer); - // 如果匹配到了,则输出 src 属性的值 - if (matcher.find()) { - String imageSrc = matcher.group(1); - answer = aipOcrComponent.handwriting(imageSrc); - } - } - - if (rightAnswers.contains(answer.trim())){ - optStuIds.add(stuA.getStuId()); - } - - } - { - Map optMap= new HashMap<>(); - List optStus=classStuList.stream().filter(s->optStuIds.contains(s.get("id").toString())).collect(Collectors.toList()); - - optMap.put("stus",optStus); - optMap.put("count",optStus.stream().count()); - - double zbCount=(double)optStus.stream().count(); - double zsCount=(double)classStuList.stream().count(); - String accuracy2f =getNumberBfb2f(zbCount,zsCount); - optMap.put("zb",accuracy2f); - optdcMap.put("dui",optMap); - } - { - Map optMap= new HashMap<>(); - List optStus=classStuList.stream().filter(s->!optStuIds.contains(s.get("id").toString())).collect(Collectors.toList()); - - optMap.put("stus",optStus); - optMap.put("count",optStus.stream().count()); - - double zbCount=(double)optStus.stream().count(); - double zsCount=(double)classStuList.stream().count(); - String accuracy2f =getNumberBfb2f(zbCount,zsCount); - optMap.put("zb",accuracy2f); - optdcMap.put("cuo",optMap); - } - qAnalyzeStus.add(optdcMap); - } - return qAnalyzeStus; - } - - private List writtenQuestionStatics(PunitQuestion pQuestion,List stuAnswerList,List classStuList) - { - List qAnalyzeStus=new ArrayList<>(); - { - Map optMap=new HashMap(); - List optStuIds= stuAnswerList.stream().filter(s->pQuestion.getId().equals(s.getQuestionId())&& StringUtils.isNotEmpty(s.getStuAnalysis())).mapToInt(PunitStuAnswer::getStuId).boxed().collect(Collectors.toList()); - List optStus=classStuList.stream().filter(s->optStuIds.contains(s.get("id").toString())).collect(Collectors.toList()); - optMap.put("option","已作答"); - optMap.put("stus",optStus); - optMap.put("count",optStus.stream().count()); - double zbCount=(double)optStus.stream().count(); - double zsCount=(double)classStuList.stream().count(); - String accuracy2f =getNumberBfb2f(zbCount,zsCount); - optMap.put("zb",accuracy2f); - qAnalyzeStus.add(optMap); - } - { - Map optMap=new HashMap(); - List optStuIds= stuAnswerList.stream().filter(s->pQuestion.getId().equals(s.getQuestionId())&& StringUtils.isNotEmpty(s.getStuAnalysis())).mapToInt(PunitStuAnswer::getStuId).boxed().collect(Collectors.toList()); - List optStus=classStuList.stream().filter(s->!optStuIds.contains(s.get("id").toString())).collect(Collectors.toList()); - optMap.put("option","未作答"); - optMap.put("stus",optStus); - optMap.put("count",optStus.stream().count()); - double zbCount=(double)optStus.stream().count(); - double zsCount=(double)classStuList.stream().count(); - String accuracy2f =getNumberBfb2f(zbCount,zsCount); - optMap.put("zb",accuracy2f); - qAnalyzeStus.add(optMap); - } - return qAnalyzeStus; - } - - - private String getNumberBfb2f(double zbCount,double zsCount) - { - return String.format("%.2f",(zsCount==0||zbCount==0)?0:(zbCount*100*1.00/zsCount )); - } - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java deleted file mode 100644 index b3ce7ba..0000000 --- a/src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java +++ /dev/null @@ -1,513 +0,0 @@ -package com.bestsch.classicalchinese.utils; - -import cn.hutool.core.util.IdUtil; -import com.bestsch.classicalchinese.enums.FileType; -import com.bestsch.classicalchinese.model.FileMessage; -import com.bestsch.utils.DException; -import lombok.extern.slf4j.Slf4j; -import net.coobird.thumbnailator.Thumbnails; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.awt.image.BufferedImage; -import java.io.*; -import java.net.URL; -import java.net.URLEncoder; -import java.text.DecimalFormat; -import java.util.UUID; - -/** - * @author min - * @description File工具类,扩展 hutool 工具包 - * @date 2019-07-05 - */ -@Slf4j -public class FileUtil { - - /** - * 定义GB的计算常量 - */ - private static final int GB = 1024 * 1024 * 1024; - /** - * 定义MB的计算常量 - */ - private static final int MB = 1024 * 1024; - /** - * 定义KB的计算常量 - */ - private static final int KB = 1024; - - /** - * 格式化小数 - */ - private static final DecimalFormat DF = new DecimalFormat("0.00"); - - /** - * MultipartFile转File - * - * @param multipartFile - * @return - */ - public static File toFile(MultipartFile multipartFile) { - // 获取文件名 - String fileName = multipartFile.getOriginalFilename(); - // 获取文件后缀 - String prefix = "." + getExtensionName(fileName); - File file = null; - try { - // 用uuid作为文件名,防止生成的临时文件重复 - file = File.createTempFile(IdUtil.simpleUUID(), prefix); - // MultipartFile to File - multipartFile.transferTo(file); - } catch (IOException e) { - log.error(e.getMessage()); - } - return file; - } - - /** - * 删除 - * - * @param files - */ - public static void deleteFile(File... files) { - for (File file : files) { - if (file.exists()) { - file.delete(); - } - } - } - - /** - * 获取文件扩展名 - * - * @param filename - * @return - */ - public static String getExtensionName(String filename) { - if ((filename != null) && (filename.length() > 0)) { - int dot = filename.lastIndexOf('.'); - if ((dot > -1) && (dot < (filename.length() - 1))) { - return filename.substring(dot + 1); - } - } - return filename; - } - - /** - * Java文件操作 获取不带扩展名的文件名 - * - * @param filename - * @return - */ - public static String getFileNameNoEx2(String filename) { - if ((filename != null) && (filename.length() > 0)) { - int dot = filename.lastIndexOf('.'); - if ((dot > -1) && (dot < (filename.length()))) { - return filename.substring(0, dot); - } - } - return filename; - } - /** - * @author luona - * @createTime 2022/1/13 10:10 上午 - * @desc http链接截取后缀明 - */ - public static String getFileNameNoEx(String filename) { - if ((filename != null) && (filename.length() > 0)) { - int dot = filename.lastIndexOf('.'); - int dot2 = filename.lastIndexOf('/'); - if ((dot > -1) && (dot < (filename.length()))) { - return filename.substring(dot2, dot); - } - } - return filename; - } - - /** - * 文件大小转换 - * - * @param size - * @return - */ - public static String getSize(int size) { - String resultSize = ""; - if (size / GB >= 1) { - //如果当前Byte的值大于等于1GB - resultSize = DF.format(size / (float) GB) + "GB "; - } else if (size / MB >= 1) { - //如果当前Byte的值大于等于1MB - resultSize = DF.format(size / (float) MB) + "MB "; - } else if (size / KB >= 1) { - //如果当前Byte的值大于等于1KB - resultSize = DF.format(size / (float) KB) + "KB "; - } else { - resultSize = size + "B "; - } - return resultSize; - } - - public static String uploadImg(byte[] imgData, String pathName) { - String imgName = null; - String path = null; - File floorFile = null; - try { - //保存图片 - for (int i = 0; i < 100; i++) { - imgName = UUID.randomUUID().toString().substring(0, 8) + ".png"; - path = pathName + imgName; - floorFile = new File(path); - // 检测是否存在目录 - if (!floorFile.getParentFile().exists()) { - floorFile.getParentFile().mkdirs();// 新建文件夹 - } - if (floorFile.exists()) continue; - else break; - } - FileOutputStream fos = new FileOutputStream(floorFile); - fos.write(imgData); - fos.close(); - - } catch (IOException e) { - log.error(e.getMessage()); - } - return imgName; - } - - public static void save(byte[] bytes, String fileName) - { - try - { - InputStream inputStream = new ByteArrayInputStream(bytes); - save(inputStream, fileName); - inputStream.close(); - } - catch (Exception e) - { - throw new DException("保存文件失败"); - } - } - - public static void save(InputStream inputStream, String fileName) - { - try - { - FileOutputStream fileOutputStream = new FileOutputStream(fileName); - byte[] buf = new byte[102400]; - while (true) - { - int readed = inputStream.read(buf, 0, 4096); - if (readed == -1) - break; - - fileOutputStream.write(buf, 0, readed); - } - fileOutputStream.close(); - } - catch (IOException e) - { - throw new DException("保存文件失败"); - } - } - - public static String randName(String path, String ext) - { - for (int i = 0; i < 100; i++) - { - String name = UUID.randomUUID().toString().substring(0, 8) + ext; - String fullName = path + name; - File file = new File(fullName); - if (!file.exists()) return name; - } - throw new DException("文件已经存在"); - } - - public static String uploadImg(MultipartFile file, String pathName) { - String imgName = null; - String path = null; - File floorFile = null; - FileMessage fileMessage = new FileMessage(); - try { - - //保存图片 - byte[] imgData = file.getBytes(); - String fileName = file.getOriginalFilename(); - int index = fileName.lastIndexOf("."); - String ext = ""; - if (index > 0) { - ext = fileName.substring(index); - } - for (int i = 0; i < 100; i++) { - imgName = UUID.randomUUID().toString().substring(0, 8) + ext; - path = pathName + imgName; - floorFile = new File(path); - // 检测是否存在目录 - if (!floorFile.getParentFile().exists()) { - floorFile.getParentFile().mkdirs();// 新建文件夹 - } - if (floorFile.exists()) continue; - else break; - } - FileOutputStream fos = new FileOutputStream(floorFile); - fos.write(imgData); - fos.close(); - - /** - * 尺寸变为原来的一半,高质量输出 - * scale 比例 - * outputQuality 质量 - */ - /* Thumbnails.of(new FileInputStream(toFile(file))).scale(0.5f) - .outputQuality(1f).toFile(floorFile); - - fileMessage=getImgWidthHeight(floorFile); - fileMessage.setFileName(imgName);*/ - } catch (IOException e) { - log.error(e.getMessage()); - } - return imgName; - } - - /** - * 下载文件 - * - * @param response - * @param filePath 需要下载附件的路径 - * @param fileName 下载附件的文件名 --- 显示给用户看的文件名(文件的原文件名) - */ - public static void downloadFile(HttpServletResponse response, String filePath, String fileName) { - OutputStream outp = null; - try (FileInputStream in = new FileInputStream(filePath)) { - - response.reset(); - response.setContentType("application/x-download;charset=UTF-8"); - fileName = URLEncoder.encode(fileName, "UTF-8"); - //添加文件的头部 - response.addHeader("Content-Disposition", "attachment;filename=" + fileName); - outp = response.getOutputStream(); - //循环出流中的数据 - byte[] b = new byte[1024]; - while (in.read(b) != -1) { - outp.write(b); - } - outp.flush(); - } catch (Exception e) { - - } finally { - if (outp != null) { - try { - outp.close(); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - } - } - - - /** - * 获取图片宽 高度 - * - * @param file 图片文件 - */ - public static FileMessage getImgWidthHeight(File file) { - InputStream is = null; - BufferedImage src = null; - FileMessage fileMessage = new FileMessage(); - try { - is = new FileInputStream(file); - /*byte[] bytes=new byte[30]; - is.read(bytes); - if("WEBP".equals(new String(bytes,8,4,"utf-8"))){//先判断图片格式为webp - int width = (((int) bytes[27] & 0xff) << 8) | (int) bytes[26] & 0xff; - int height = (((int) bytes[29] & 0xff) << 8) | (int) bytes[28] & 0xff; - fileMessage.setImgHeight(height); - fileMessage.setImgWidth(width); - fileMessage.setFileName(file.getName()); - }*/ - src = javax.imageio.ImageIO.read(is); - int height = src.getHeight(null);// 得到源图高 - int width = src.getWidth(null);// 得到源图宽 - fileMessage.setImgHeight(height); - fileMessage.setImgWidth(width); - is.close(); - } catch (Exception e) { - log.error(e.getMessage()); - } - return fileMessage; - - } - public static Integer getFileType(MultipartFile file) { - String contentType = file.getContentType(); - //log.info(contentType);//audio/x-flac video/mp4 video/quicktime audio/mpeg image/jpeg - if (contentType.contains("video")) { - return FileType.VIDEO_TYPE.getId(); - } else if (contentType.contains("audio")) { - return FileType.AUDIO_TYPE.getId(); - }else if(contentType.contains("image")){ - return FileType.IMG_TYPE.getId(); - }else return FileType.OTHER_TYPE.getId(); - - } - - /** - - * 读取txt文件的内容 - - * @param file 想要读取的文件对象 - - * @return 返回文件内容 - - */ - - public static String txt2String(File file){ - StringBuilder result = new StringBuilder(); - - try{ - BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 - - String s = null; - - while((s = br.readLine())!=null){//使用readLine方法,一次读一行 - - result.append(System.lineSeparator()+s); - - } - - br.close(); - - }catch(Exception e){ - log.error(e.getMessage()); - - } - - return result.toString(); - - } - - - public static void main(String[] args) { - String path = "/Users/luona/Downloads/11575191533_.pic_hd.jpg"; - File file = new File("/Users/luona/Downloads/2.jpg"); - /** - * 尺寸变为原来的一半,高质量输出 - * scale 比例 - * outputQuality 质量 - */ - try { - Thumbnails.of(path).scale(0.5f) - .outputQuality(1f).toFile(file); - } catch (IOException e) { - log.error(e.getMessage()); - } - } - /** - * 下载文件到浏览器 - * @param request - * @param response - * @param filename 要下载的文件名 - * @param file 需要下载的文件对象 - * @throws IOException - */ - public static void downFile(HttpServletRequest request, HttpServletResponse response, String filename, File file) throws IOException { - // 文件存在才下载 - if (file.exists()) { - OutputStream out = null; - FileInputStream in = null; - try { - // 1.读取要下载的内容 - in = new FileInputStream(file); - - // 2. 告诉浏览器下载的方式以及一些设置 - // 解决文件名乱码问题,获取浏览器类型,转换对应文件名编码格式,IE要求文件名必须是utf-8, firefo要求是iso-8859-1编码 - String agent = request.getHeader("user-agent"); - if (agent.contains("FireFox")) { - filename = new String(filename.getBytes("UTF-8"), "iso-8859-1"); - } else { - filename = URLEncoder.encode(filename, "UTF-8"); - } - // 设置下载文件的mineType,告诉浏览器下载文件类型 - String mineType = request.getServletContext().getMimeType(filename); - response.setContentType(mineType); - // 设置一个响应头,无论是否被浏览器解析,都下载 - response.setHeader("Content-disposition", "attachment; filename=" + filename); - // 将要下载的文件内容通过输出流写到浏览器 - out = response.getOutputStream(); - int len = 0; - byte[] buffer = new byte[1024]; - while ((len = in.read(buffer)) > 0) { - out.write(buffer, 0, len); - } - } catch (IOException e) { - log.error(e.getMessage()); - } finally { - if (out != null) { - out.close(); - } - if (in != null) { - in.close(); - } - } - } - } - /** - * 递归删除目录下的所有文件及子目录下所有文件 - * - * @param filePath 将要删除的文件目录路径 - * @return boolean Returns "true" if all deletions were successful. - * If a deletion fails, the method stops attempting to - * delete and returns "false". - */ - public static boolean deleteDir(String filePath) { - File dir = new File(filePath); - if (dir.isDirectory()) { - String[] children = dir.list(); - //递归删除目录中的子目录下 - for (int i = 0; i < children.length; i++) { - boolean success = deleteDir(filePath + File.separator + children[i]); - if (!success) { - return false; - } - } - } - // 目录此时为空,可以删除 - return dir.delete(); - } - - - /** - * url文件转字节数组 - */ - public static byte[] getBytes(String imageUrl) { - byte[] imageBytes = new byte[0]; - InputStream inputStream = null; - ByteArrayOutputStream outputStream = null; - try { - URL url = new URL(imageUrl); - inputStream = url.openStream(); - outputStream = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - imageBytes = outputStream.toByteArray(); - } catch (IOException e) { - log.error("url文件转字节数组getBytes方法报错,读取网络文件失败:", e); - } finally { - try { - if (inputStream != null) { - inputStream.close(); - } - if (outputStream != null) { - outputStream.close(); - } - } catch (IOException e) { - log.error("关闭流失败:", e); - } - } - return imageBytes; - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java b/src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java deleted file mode 100644 index 71b4c4c..0000000 --- a/src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.bestsch.classicalchinese.utils; - -public class RedisConstants { - - public static final String CachePrefix = "bsch.punit."; - - public static final String ZY_Tree = CachePrefix + "ziyuan_tree"; - - //学年学期缓存 - public static final String ACADEMIC_YEAR_LIST = CachePrefix + "academic_year_list"; - - //学校 - public static final String SCHOOL_ALL= CachePrefix + "school_all"; - - //教师 - public static final String SCH_TEA = CachePrefix + "tea_sch_list"; - - //任教 - public static final String SCH_TEACHER = CachePrefix + "teacher_sch_list"; - - //年级班级 - public static final String SCH_GRADE_CLASS = CachePrefix + "sch_grade_class_list"; - - public static final String SCH_USER_CLASS = CachePrefix + "sch_user_class"; - - //学生 - public static final String STUDENT_ALL = CachePrefix + "student_sch_list"; - - //执行进度Progress - public static final String EXTERNAL_PROGRESS = CachePrefix + "external_progress"; - - //执行任务数据缓存 - public static final String EXTERNAL_PLAN_DATA = CachePrefix + "external_plan_data"; - - - - -} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java deleted file mode 100644 index a5dfe2a..0000000 --- a/src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.bestsch.classicalchinese.utils; - -import javax.validation.*; -import java.util.Set; - -public class ValidationUtil { - private static final Validator validator; - - static { - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - validator = factory.getValidator(); - } - - public static void validate(Object object) { - Set> violations = validator.validate(object); - if (!violations.isEmpty()) { - for (ConstraintViolation violation : violations) { - System.out.println(violation.getMessage()); // 输出错误信息 - } - throw new ConstraintViolationException(violations); // 可以根据需要抛出异常 - } - } -} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/VideoTransCodeUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/VideoTransCodeUtil.java deleted file mode 100644 index 8e993aa..0000000 --- a/src/main/java/com/bestsch/classicalchinese/utils/VideoTransCodeUtil.java +++ /dev/null @@ -1,313 +0,0 @@ -package com.bestsch.classicalchinese.utils; - -import com.bestsch.classicalchinese.model.FileMessage; -import com.bestsch.utils.DException; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.multipart.MultipartFile; -import ws.schild.jave.AudioInfo; -import ws.schild.jave.MultimediaInfo; -import ws.schild.jave.MultimediaObject; -import ws.schild.jave.*; - -import java.io.*; -import java.util.UUID; - -//import it.sauronsoftware.jave.*; -@Slf4j -public class VideoTransCodeUtil { - - public static File judgeFile(String videoPath, MultipartFile file) throws IOException { - File toFile = null; - if (file.equals("") || file.getSize() <= 0) { // 视频转属性 - throw new DException("缺少视频文件"); - } else { - InputStream ins = null; - ins = file.getInputStream(); - toFile = new File(videoPath + file.getOriginalFilename()); - inputStreamToFile(ins, toFile); - ins.close(); - } - return toFile; - } - - public static FileMessage VideoTransCode(String videoPath, MultipartFile file) throws Exception { - File filePath = new File(videoPath); - if (!filePath.exists()) { - filePath.mkdirs(); - } - - File toFile = judgeFile(videoPath, file); - FileMessage message = new FileMessage(); - int index = toFile.getName().lastIndexOf("."); - String name = ""; - if (index > 0) - name = toFile.getName().substring(0, index); - - String fileName = UUID.randomUUID().toString(); - - // 获取视屏长度 - MultimediaObject instance = new MultimediaObject(toFile); - MultimediaInfo result = instance.getInfo(); - long ls = result.getDuration() / 2000; - - float x = ls; - - /*FileInputStream fis = new FileInputStream(toFile); - - FileChannel fc = fis.getChannel(); - - BigDecimal fileSize = new BigDecimal(fc.size()); - //视频大小 - String size = fileSize.divide(new BigDecimal(1048576), 2, RoundingMode.HALF_UP) + "MB"; -*/ - - - - VideoInfo video = result.getVideo(); - AudioInfo audio = result.getAudio(); - String format = result.getFormat(); - - if (video != null&&!format.equals("mp3")) { - String decoder = video.getDecoder(); - try { - getVideoPicture(videoPath, fileName, toFile, x); - } catch (EncoderException e) { - try { - getVideoPicture(videoPath, fileName, toFile, 2);//第2s的时候截图 - } catch (EncoderException ex) { - //ex.printStackTrace(); - } - //log.error(e.getMessage()); - } - // 视频截图 - File picture = new File(videoPath + fileName + ".jpg"); - message.setPictureName(fileName + ".jpg"); - message = FileUtil.getImgWidthHeight(picture); - if (decoder.startsWith("h264")) { // 判断是不是h264格式 - changeName(toFile,videoPath + fileName + ".mp4"); - } else { - ChangeVideo changeVideo = new ChangeVideo(videoPath, fileName, toFile);// 转换视频格式 - changeVideo.start(); - } - // fileName = fileName + ".mp4"; - } else if (audio != null) {//音频转码 - String decoder = audio.getDecoder(); - - if (decoder.startsWith("mp3")) { - toFile.renameTo(new File(videoPath + fileName + ".mp3")); - } else { - ChangeAudio changeVideo = new ChangeAudio(videoPath, fileName, toFile);// 转换视频格式 - changeVideo.start(); - } - // fileName = fileName + ".mp3"; - } - - - - message.setFileName(fileName); - message.setVideoSize(ls * 2); - // message.setSize(size); - return message; - - } - - - public static void changeName(File file,String path){ - - boolean b = file.renameTo(new File(path)); - log.info(String.valueOf(b)); - log.info(file.getPath()); - log.info(path); - if(!b){ - changeName (file,path); - } - } - - // 转换视频格式 - public static void changeVideoType(String videoPath, String fileName, File toFile) throws EncoderException { - File target = new File(videoPath + fileName + ".mp4"); - // 视频转码 - if (target.exists()) { - target.delete(); - } - AudioAttributes audioAttr = new AudioAttributes(); - VideoAttributes videoAttr = new VideoAttributes(); - EncodingAttributes encodingAttr = new EncodingAttributes(); - - audioAttr.setChannels(2); - audioAttr.setCodec("aac"); - //或者 audioAttr.setCodec("libmp3lame"); 建议aac 此行的编码格式可能会造成意想不到的错误 - audioAttr.setBitRate(128000); - audioAttr.setSamplingRate(44100); - - videoAttr.setCodec("libx264"); - videoAttr.setBitRate(4000000); - - encodingAttr.setAudioAttributes(audioAttr); - encodingAttr.setVideoAttributes(videoAttr); - encodingAttr.setFormat("mp4"); - - Encoder encoder = new Encoder(); - encoder.encode(new MultimediaObject(toFile), target, encodingAttr); - } - - public static void getVideoPicture(String videoPath, String fileName, File toFile, float x) throws EncoderException { - File picture = new File(videoPath + fileName + ".jpg"); - VideoAttributes videoPicture = new VideoAttributes();// 视频属性 - videoPicture.setCodec("mjpeg");// 图片编码 -// videoPicture.setSize(new VideoSize(1200, 800));// 设置图片宽高 - EncodingAttributes attrPicture = new EncodingAttributes();// 转码属性 - attrPicture.setFormat("image2");// 转码格式 - attrPicture.setOffset(x);// 设置偏移位置,即开始转码位置(3秒) - attrPicture.setDuration(0.01f);// 设置转码持续时间(1秒) - attrPicture.setVideoAttributes(videoPicture); - - Encoder encoderPicture = new Encoder(); - encoderPicture.encode(new MultimediaObject(toFile), picture, attrPicture); - } - - public static void inputStreamToFile(InputStream ins, File file) { - try { - OutputStream os = new FileOutputStream(file); - int bytesRead = 0; - byte[] buffer = new byte[8192]; - while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { - os.write(buffer, 0, bytesRead); - } - os.close(); - ins.close(); - } catch (Exception e) { - log.error(e.getMessage()); - } - } - - public static void main(String[] args) { - File fileMp4=new File("/Users/luona/Desktop/zhd测试.mp4"); - File fileMp3=new File("/Users/luona/Desktop/mn1112.jpg"); - VideoAttributes videoPicture = new VideoAttributes();// 视频属性 - videoPicture.setCodec("mjpeg");// 图片编码 - - EncodingAttributes attrPicture = new EncodingAttributes();// 转码属性 - attrPicture.setFormat("image2");// 转码格式 - attrPicture.setOffset(3.0F);// 设置偏移位置,即开始转码位置(3秒) - attrPicture.setDuration(0.01f);// 设置转码持续时间(1秒) - attrPicture.setVideoAttributes(videoPicture); - Encoder encoder = new Encoder(); - - try { - encoder.encode(new MultimediaObject(fileMp4), fileMp3, attrPicture); - } catch (EncoderException e) { - log.error(e.getMessage()); - } - - - } - -} - -@Slf4j -class ChangeVideo extends Thread { - private Thread t; - private String videoPath; - private String fileName; - private File toFile; - - public ChangeVideo(String videoPath, String fileName, File toFile) { - this.videoPath = videoPath; - this.fileName = fileName; - this.toFile = toFile; - } - - public void start() { - if (t == null) { - t = new Thread(this); - t.start(); - } - } - - @Override - public void run() { - File target = new File(videoPath + fileName + ".mp4"); - // 视频转码 - if (target.exists()) { - target.delete(); - } - AudioAttributes audioAttr = new AudioAttributes(); - VideoAttributes videoAttr = new VideoAttributes(); - EncodingAttributes encodingAttr = new EncodingAttributes(); - - audioAttr.setChannels(2); - audioAttr.setCodec("aac"); - //或者 audioAttr.setCodec("libmp3lame"); 建议aac 此行的编码格式可能会造成意想不到的错误 - audioAttr.setBitRate(128000); - audioAttr.setSamplingRate(44100); - - videoAttr.setCodec("libx264"); - videoAttr.setBitRate(4000000); - - encodingAttr.setAudioAttributes(audioAttr); - encodingAttr.setVideoAttributes(videoAttr); - encodingAttr.setFormat("mp4"); - - Encoder encoder = new Encoder(); - try { - encoder.encode(new MultimediaObject(toFile), target, encodingAttr); - if (toFile.exists()) { - toFile.delete(); - } - } catch (EncoderException e) { - log.error(e.getMessage()); - } - } -} - -@Slf4j -class ChangeAudio extends Thread { - private Thread t; - private String videoPath; - private String fileName; - private File toFile; - - public ChangeAudio(String videoPath, String fileName, File toFile) { - this.videoPath = videoPath; - this.fileName = fileName; - this.toFile = toFile; - } - - public void start() { - if (t == null) { - t = new Thread(this); - t.start(); - } - } - - @Override - public void run() { - File target = new File(videoPath + fileName + ".mp3"); - // 音频转码 - if (target.exists()) { - target.delete(); - } - - AudioAttributes audio = new AudioAttributes(); - audio.setCodec("libmp3lame"); - audio.setBitRate(new Integer(128000)); - audio.setChannels(new Integer(2)); - audio.setSamplingRate(new Integer(44100)); - EncodingAttributes attrs = new EncodingAttributes(); - attrs.setFormat("mp3"); - attrs.setAudioAttributes(audio); - - - - Encoder encoder = new Encoder(); - try { - encoder.encode(new MultimediaObject(toFile), target, attrs); - if (toFile.exists()) { - toFile.delete(); - } - } catch (EncoderException e) { - log.error(e.getMessage()); - } - } -} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..2e6149d --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,14 @@ +server: + address: 0.0.0.0 + port: 8086 + +spring: + web: + cors: + enabled: false + +yh: + sso: + client-host-url: http://192.168.10.166:8086 + +FILE_WEB_PATH: http://localhost:8086/upload/ \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..8186d19 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,9 @@ +server: + address: 0.0.0.0 + port: 8087 + +yh: + sso: + client-host-url: http://192.168.10.166:8087 + +FILE_WEB_PATH: http://localhost:8087/upload/ \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6992ed5..2ce5258 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,3 @@ -server: - port: 8086 - spring: mvc: date-format: yyyy-MM-dd HH:mm:ss @@ -15,7 +12,7 @@ spring: host: 127.0.0.1 port: 6379 database: 0 - password: 123 + #password: 123 rabbitmq: host: 127.0.0.1 port: 5672 @@ -30,17 +27,17 @@ spring: redis: repositories: enabled: false -# http: -# encoding: -# force: true -# charset: utf-8 -# enabled: true + http: + encoding: + force: true + charset: utf-8 + enabled: true datasource: - url: jdbc:mysql://localhost:3306/classicalchinese?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai + url: jdbc:mysql://localhost:3306/dbschoolclass?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true username: root - password: 123 - driver-class-name: com.mysql.jdbc.Driver + password: 123123 + driver-class-name: com.mysql.cj.jdbc.Driver min-idle: 30 max-active: 30 hikari: @@ -65,41 +62,27 @@ spring: properties: hibernate: dialect: org.hibernate.dialect.MySQL5InnoDBDialect + format_sql: true # 格式化 SQL,方便阅读 open-in-view: true -bsch: +yh: sso: - # service-url-prefix: http://sso.bestsch.com - server-url-prefix: http://sso.bestsch.com - client-host-url: http://localhost:8086 + server-url-prefix: http://sso.yunhaixingtong.com/cas/ + client-host-url: http://192.168.10.166:8086 allow-headers: all allow-origins: all url-pattern: /api/* - ignore-pattern: /mobiapi/*|mobiapi2/*|/qywxapi/* mobi-api-pattern: /mobiapi/* + app-auth: + enabled: true + # 本应用自身身份(客户端签名用) + app-key: 100001 + app-secret: ec4e860206374c80938719fff8e14a86 open: - base-host: http://base.bestsch.com - photo_url: http://base.bestsch.com/ - app-key: 100614 - app-secret: f03fd6e4f5da4b108127cd74f05ee767 - schbase-host: http://base.bestsch.com/BschClass - zyk-host: http://base.bestsch.com/BschZyk - openai: - host: https://one2.app011.cn:8443/v1/completions - api-key: sk-PFVGDLriMVkt01Id4e094470060d41D281D42580C00f9380 - #host: https://api.deepseek.com/chat/completions - #api-key: sk-ce9491557e6247378727e0971359f75e - max-tokens: 5000 - temperature: 0.5 - oahost: https://oa2.schsoft.cn - - -baidu: - api: - app_id: 33374298 - app_key: UiZ4yP5jaUABm3QsjB824oqM - app_secret: j5lX1xEhzAqLCQuZ2obR3HMtQYL7144s + enabled: true + base-host: http://base.yunhaixingtong.com + user-center-url: http://base.yunhaixingtong.com/userbase FILE_PATH: D://工作区/JAVA/bsch/ diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..000a180 --- /dev/null +++ b/src/main/resources/bootstrap.yml @@ -0,0 +1,27 @@ +spring: + application: + name: bschclassmanage + profiles: + active: dev + cloud: + nacos: + config: + # Nacos 配置中心地址;生产也可通过环境变量 NACOS_ADDR 覆盖 + server-addr: ${NACOS_ADDR:nacos.yunhaixingtong.com:8848} + # public 命名空间 + namespace: "" + # 应用自身配置所在分组 + group: NOTICE + # 配置文件格式;最终主配置 dataId = ${spring.application.name}.${file-extension},即 notice.yaml + file-extension: yaml + encode: UTF-8 + # nacos 不可达时不强制退出,回退到本地 application.yml 兜底 + fail-fast: false + # 只读账号 + username: yh-reader + password: 123456 + # 共享公共配置:public 空间下的 common.properties + shared-configs: + - data-id: common.properties + group: DEFAULT_GROUP + refresh: false