From 9e06e21b9d3fb9d412fa9f1fa02cc206f56b04b9 Mon Sep 17 00:00:00 2001 From: wanghu Date: Sat, 28 Feb 2026 19:31:18 +0800 Subject: [PATCH] 1 --- .gitattributes | 2 + .gitignore | 33 + .mvn/wrapper/maven-wrapper.properties | 19 + mvnw | 259 ++++++ mvnw.cmd | 149 +++ pom.xml | 152 +++ .../ClassicalchineseApplication.java | 21 + .../Repository/BschKnowledgeRepository.java | 44 + .../BschLeadlearningRepository.java | 13 + .../Repository/BschQuestionRepository.java | 11 + .../Repository/BschTextbookRepository.java | 45 + .../BschVideoExplanationRepository.java | 44 + .../Repository/FeedBackRepository.java | 13 + .../Repository/OcrDataCacheRepository.java | 16 + .../PunitCommunicationRepository.java | 10 + .../PunitLeadlearningRepository.java | 42 + .../Repository/PunitQuestionRepository.java | 18 + .../Repository/PunitStuAnswerRepository.java | 17 + .../PunitZiYuanTreeTeaRepository.java | 10 + .../Repository/UploadFileRepository.java | 11 + .../VideoExplanationRepository.java | 47 + .../baidu/AipOcrComponent.java | 76 ++ .../classicalchinese/baidu/AipOcrConfig.java | 27 + .../baidu/BaiDuConfigProperties.java | 23 + .../classicalchinese/config/Config.java | 40 + .../config/DWebMvcConfig.java | 21 + .../classicalchinese/config/FileConfig.java | 24 + .../classicalchinese/config/RedisConfig.java | 87 ++ .../controller/BaseController.java | 37 + .../Handler/ValidationExceptionHandler.java | 27 + .../api/BschSettingsController.java | 374 ++++++++ .../controller/api/CommonController.java | 106 +++ .../controller/api/ExplanationController.java | 127 +++ .../controller/api/LoginUserController.java | 51 + .../controller/api/PunitNodeController.java | 288 ++++++ .../api/PunitSettingsController.java | 282 ++++++ .../controller/api/RelayController.java | 179 ++++ .../controller/api/StatisticsController.java | 55 ++ .../controller/api/UserController.java | 48 + .../mobiapi/MobiCommonController.java | 328 +++++++ .../mobiapi/MobiFileController.java | 231 +++++ .../mobiapi/MobiTeaAreaController.java | 250 +++++ .../controller/oapi/HyAIController.java | 78 ++ .../controller/oapi/OapiController.java | 133 +++ .../controller/oapi/UploadFileController.java | 32 + .../classicalchinese/entity/BaseEntity.java | 29 + .../entity/BschKnowledge.java | 57 ++ .../entity/BschLeadlearning.java | 47 + .../classicalchinese/entity/BschQuestion.java | 90 ++ .../classicalchinese/entity/BschTextbook.java | 88 ++ .../entity/BschVideoExplanation.java | 95 ++ .../classicalchinese/entity/FeedBack.java | 65 ++ .../entity/PunitCommunication.java | 63 ++ .../entity/PunitLeadlearning.java | 46 + .../entity/PunitQuestion.java | 39 + .../entity/PunitStuAnswer.java | 78 ++ .../entity/PunitZiYuanTreeTea.java | 28 + .../classicalchinese/entity/Question.java | 69 ++ .../classicalchinese/entity/UploadFile.java | 74 ++ .../entity/VideoExplanation.java | 114 +++ .../classicalchinese/enums/AnswerStatus.java | 36 + .../classicalchinese/enums/AppType.java | 33 + .../enums/DifficultLevel.java | 88 ++ .../classicalchinese/enums/FileType.java | 37 + .../classicalchinese/enums/GradeEnum.java | 127 +++ .../classicalchinese/enums/OcrDataCache.java | 29 + .../enums/QuestionDifficultyEnum.java | 23 + .../classicalchinese/enums/QuestionType.java | 82 ++ .../enums/QuestionTypeEnum.java | 22 + .../classicalchinese/enums/ReviewStatus.java | 33 + .../classicalchinese/enums/SchoolSection.java | 102 ++ .../enums/SchoolSection_.java | 100 ++ .../classicalchinese/enums/SourceEnum.java | 37 + .../classicalchinese/enums/Subject.java | 105 +++ .../classicalchinese/enums/TimeTypeEnum.java | 72 ++ .../classicalchinese/enums/UserRole.java | 52 ++ .../classicalchinese/model/AcademicYear.java | 24 + .../bestsch/classicalchinese/model/AiAsk.java | 21 + .../classicalchinese/model/BaseTree.java | 17 + .../classicalchinese/model/ClassInfo.java | 26 + .../classicalchinese/model/ClassModel.java | 13 + .../classicalchinese/model/DateModel.java | 13 + .../classicalchinese/model/DateTimeModel.java | 12 + .../classicalchinese/model/Example.java | 39 + .../model/ExcelBschLeadlearning.java | 20 + .../model/ExcelPunitTreeTea.java | 20 + .../classicalchinese/model/FileMessage.java | 15 + .../bestsch/classicalchinese/model/Grade.java | 26 + .../bestsch/classicalchinese/model/Page.java | 72 ++ .../classicalchinese/model/PageInfo.java | 26 + .../classicalchinese/model/SchClassModel.java | 12 + .../classicalchinese/model/SchSub.java | 9 + .../model/SchTeaSubGrade.java | 10 + .../classicalchinese/model/StartEndDate.java | 14 + .../classicalchinese/model/StudentInfo.java | 14 + .../model/SubGroupTeaIds.java | 17 + .../classicalchinese/model/SystemGrade.java | 31 + .../classicalchinese/model/TeaFirstClass.java | 15 + .../classicalchinese/model/TreeDept.java | 16 + .../classicalchinese/model/TreeUser.java | 17 + .../model/UserGradeClassSub.java | 15 + .../classicalchinese/model/YearSemester.java | 28 + .../classicalchinese/model/dto/PunitDto.java | 24 + .../model/vo/AiQuestionsVo.java | 25 + .../model/vo/BschFormQuestionVo.java | 27 + .../model/vo/PunitFilesVo.java | 26 + .../model/vo/PunitFormVo.java | 39 + .../model/vo/PunitNodeStuQuestion.java | 50 + .../model/vo/SubmitStuQuestionVo.java | 23 + .../service/IBschExplanationService.java | 25 + .../service/IBschKnowledgeService.java | 237 +++++ .../service/IBschLeadlearningService.java | 20 + .../service/IBschQuestionService.java | 25 + .../service/IBschTextbookService.java | 107 +++ .../service/ICommonService.java | 23 + .../service/IExplanationService.java | 28 + .../service/IFeedBackService.java | 8 + .../service/IOcrDataCacheService.java | 16 + .../service/IPunitCommunicationService.java | 27 + .../service/IPunitLeadlearningService.java | 32 + .../service/IPunitQuestionService.java | 23 + .../service/IPunitStuAnswerService.java | 43 + .../service/IPunitZiYuanTreeTeaService.java | 19 + .../service/IStatisticsService.java | 17 + .../service/com/BaseComService.java | 163 ++++ .../service/com/ClassService.java | 813 ++++++++++++++++ .../service/com/CommonService.java | 347 +++++++ .../service/com/DeepSeekApiService.java | 84 ++ .../service/com/DeptSchService.java | 230 +++++ .../service/com/HyAIService.java | 314 +++++++ .../service/com/TeaSchService.java | 81 ++ .../service/com/UploadFileService.java | 195 ++++ .../service/com/UserGradeClassSubService.java | 172 ++++ .../service/com/ZiyuankuService.java | 275 ++++++ .../service/impl/BschExplanationService.java | 284 ++++++ .../service/impl/BschKnowledgeService.java | 875 ++++++++++++++++++ .../service/impl/BschLeadlearningService.java | 73 ++ .../service/impl/BschQuestionService.java | 93 ++ .../service/impl/BschTextbookService.java | 268 ++++++ .../service/impl/ExplanationService.java | 301 ++++++ .../service/impl/FeedBackService.java | 22 + .../service/impl/OcrDataCacheServiceImpl.java | 49 + .../impl/PunitCommunicationService.java | 143 +++ .../impl/PunitLeadlearningService.java | 186 ++++ .../service/impl/PunitQuestionService.java | 134 +++ .../service/impl/PunitStuAnswerService.java | 699 ++++++++++++++ .../impl/PunitZiYuanTreeTeaService.java | 83 ++ .../service/impl/StatisticsService.java | 363 ++++++++ .../classicalchinese/utils/CalendarUtils.java | 40 + .../classicalchinese/utils/ChinaDate.java | 322 +++++++ .../classicalchinese/utils/ConstantUtil.java | 19 + .../classicalchinese/utils/DateRangeUtil.java | 47 + .../classicalchinese/utils/DicUtil.java | 374 ++++++++ .../utils/DownloadFileUtil.java | 56 ++ .../classicalchinese/utils/EasyPoiUtils.java | 82 ++ .../classicalchinese/utils/EnumUtil.java | 151 +++ .../classicalchinese/utils/FileUtil.java | 513 ++++++++++ .../classicalchinese/utils/HttpUtils.java | 143 +++ .../classicalchinese/utils/JavaBeanUtil.java | 73 ++ .../utils/ListMapSortUtil.java | 47 + .../utils/ModelMapperUtil.java | 201 ++++ .../classicalchinese/utils/OkHttpUtil.java | 181 ++++ .../classicalchinese/utils/OrgJsonUtil.java | 21 + .../classicalchinese/utils/OtherUtil.java | 277 ++++++ .../classicalchinese/utils/PageUtil.java | 49 + .../utils/RedisConstants.java | 38 + .../classicalchinese/utils/RedisUtil.java | 868 +++++++++++++++++ .../classicalchinese/utils/Signature.java | 121 +++ .../classicalchinese/utils/TimeUtils.java | 242 +++++ .../classicalchinese/utils/UUIDUtils.java | 16 + .../utils/ValidationUtil.java | 23 + .../utils/VideoTransCodeUtil.java | 313 +++++++ src/main/resources/application.yml | 109 +++ 173 files changed, 17839 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml create mode 100644 src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/BschLeadlearningRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/BschQuestionRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/BschTextbookRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/BschVideoExplanationRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/FeedBackRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/OcrDataCacheRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/PunitCommunicationRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/PunitLeadlearningRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/PunitQuestionRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/PunitStuAnswerRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/PunitZiYuanTreeTeaRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/UploadFileRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/Repository/VideoExplanationRepository.java create mode 100644 src/main/java/com/bestsch/classicalchinese/baidu/AipOcrComponent.java create mode 100644 src/main/java/com/bestsch/classicalchinese/baidu/AipOcrConfig.java create mode 100644 src/main/java/com/bestsch/classicalchinese/baidu/BaiDuConfigProperties.java create mode 100644 src/main/java/com/bestsch/classicalchinese/config/Config.java create mode 100644 src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java create mode 100644 src/main/java/com/bestsch/classicalchinese/config/FileConfig.java create mode 100644 src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/BaseController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/Handler/ValidationExceptionHandler.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/BschSettingsController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/CommonController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/ExplanationController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/LoginUserController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/PunitSettingsController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/RelayController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/StatisticsController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/api/UserController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiFileController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiTeaAreaController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/oapi/HyAIController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/oapi/OapiController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/controller/oapi/UploadFileController.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/BaseEntity.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/BschKnowledge.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/BschLeadlearning.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/BschQuestion.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/BschTextbook.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/BschVideoExplanation.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/FeedBack.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/PunitCommunication.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/PunitLeadlearning.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/PunitQuestion.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/PunitStuAnswer.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/PunitZiYuanTreeTea.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/Question.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/UploadFile.java create mode 100644 src/main/java/com/bestsch/classicalchinese/entity/VideoExplanation.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/AnswerStatus.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/AppType.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/DifficultLevel.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/FileType.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/GradeEnum.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/OcrDataCache.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/QuestionDifficultyEnum.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/QuestionType.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/ReviewStatus.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/SchoolSection.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/SchoolSection_.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/SourceEnum.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/Subject.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/TimeTypeEnum.java create mode 100644 src/main/java/com/bestsch/classicalchinese/enums/UserRole.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/AiAsk.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/BaseTree.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/ClassInfo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/ClassModel.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/DateModel.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/DateTimeModel.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/Example.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/ExcelBschLeadlearning.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/ExcelPunitTreeTea.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/FileMessage.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/Grade.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/Page.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/PageInfo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/SchSub.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/SchTeaSubGrade.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/StartEndDate.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/StudentInfo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/SubGroupTeaIds.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/SystemGrade.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/TeaFirstClass.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/TreeDept.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/TreeUser.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/UserGradeClassSub.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/YearSemester.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/dto/PunitDto.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/vo/AiQuestionsVo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/vo/BschFormQuestionVo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/vo/PunitFilesVo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/vo/PunitFormVo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/vo/PunitNodeStuQuestion.java create mode 100644 src/main/java/com/bestsch/classicalchinese/model/vo/SubmitStuQuestionVo.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IBschExplanationService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IBschKnowledgeService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IBschLeadlearningService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IBschQuestionService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IBschTextbookService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/ICommonService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IExplanationService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IFeedBackService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IOcrDataCacheService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IPunitCommunicationService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IPunitLeadlearningService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IPunitQuestionService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IPunitStuAnswerService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IPunitZiYuanTreeTeaService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/IStatisticsService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/BaseComService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/ClassService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/CommonService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/DeepSeekApiService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/DeptSchService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/HyAIService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/TeaSchService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/UploadFileService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/UserGradeClassSubService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/com/ZiyuankuService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/BschExplanationService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/BschKnowledgeService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/BschLeadlearningService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/BschQuestionService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/BschTextbookService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/ExplanationService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/FeedBackService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/OcrDataCacheServiceImpl.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/PunitCommunicationService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/PunitLeadlearningService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/PunitQuestionService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/PunitStuAnswerService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/PunitZiYuanTreeTeaService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/service/impl/StatisticsService.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/CalendarUtils.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/HttpUtils.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/RedisUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/Signature.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java create mode 100644 src/main/java/com/bestsch/classicalchinese/utils/VideoTransCodeUtil.java create mode 100644 src/main/resources/application.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..d58dfb7 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# 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/mvnw b/mvnw new file mode 100644 index 0000000..19529dd --- /dev/null +++ b/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..249bdf3 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c8d1b31 --- /dev/null +++ b/pom.xml @@ -0,0 +1,152 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.4.RELEASE + + + com.bestsch.previewUnit + previewunit + 0.0.1-SNAPSHOT + previewunit + Demo project for Spring Boot + + 1.8 + 9.0.63 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + true + + + + mysql + mysql-connector-java + runtime + + + + + com.bestsch + bsch-spring-boot-starter + 1.2.5-SNAPSHOT + + + + cn.hutool + hutool-all + 5.0.4 + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.hibernate.validator + hibernate-validator + 6.2.0.Final + + + org.glassfish + jakarta.el + 3.0.3 + + + + org.modelmapper + modelmapper + 3.2.0 + + + + com.alibaba + fastjson + 1.2.80 + + + net.coobird + thumbnailator + 0.4.20 + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + + org.commonmark + commonmark + 0.21.0 + + + + com.google.guava + guava + 16.0.1 + + + + org.json + json + 20210307 + + + + + com.baidu.aip + java-sdk + 4.16.19 + + + + + ws.schild + jave-core + 2.4.6 + + + + com.squareup.okhttp3 + okhttp + 4.10.0 + + + + + + cn.afterturn + easypoi-base + 4.1.0 + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java b/src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java new file mode 100644 index 0000000..f9e902d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/ClassicalchineseApplication.java @@ -0,0 +1,21 @@ +package com.bestsch.classicalchinese; + +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.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableTransactionManagement +@EnableAsync +@EnableBschSso //用户中心接口 +@EnableBschApiStd +public class ClassicalchineseApplication { + + public static void main(String[] args) { + SpringApplication.run(ClassicalchineseApplication.class, args); + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java b/src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java new file mode 100644 index 0000000..9c698ec --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/BschKnowledgeRepository.java @@ -0,0 +1,44 @@ +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 new file mode 100644 index 0000000..8506a75 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/BschLeadlearningRepository.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 0000000..58837f8 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/BschQuestionRepository.java @@ -0,0 +1,11 @@ +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 new file mode 100644 index 0000000..271d266 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/BschTextbookRepository.java @@ -0,0 +1,45 @@ +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 new file mode 100644 index 0000000..858cd9f --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/BschVideoExplanationRepository.java @@ -0,0 +1,44 @@ +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 new file mode 100644 index 0000000..a927678 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/FeedBackRepository.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 0000000..abd3ad6 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/OcrDataCacheRepository.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..7ee9fbc --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/PunitCommunicationRepository.java @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..3e2eaa6 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/PunitLeadlearningRepository.java @@ -0,0 +1,42 @@ +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 new file mode 100644 index 0000000..a522f3a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/PunitQuestionRepository.java @@ -0,0 +1,18 @@ +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 new file mode 100644 index 0000000..d3476c3 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/PunitStuAnswerRepository.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..267d3ba --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/PunitZiYuanTreeTeaRepository.java @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..d456f62 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/UploadFileRepository.java @@ -0,0 +1,11 @@ +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 new file mode 100644 index 0000000..b3ab537 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/Repository/VideoExplanationRepository.java @@ -0,0 +1,47 @@ +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 new file mode 100644 index 0000000..2f2098d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrComponent.java @@ -0,0 +1,76 @@ +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 new file mode 100644 index 0000000..cebd0b0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/baidu/AipOcrConfig.java @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..83f73e4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/baidu/BaiDuConfigProperties.java @@ -0,0 +1,23 @@ +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/Config.java b/src/main/java/com/bestsch/classicalchinese/config/Config.java new file mode 100644 index 0000000..a06ade1 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/config/Config.java @@ -0,0 +1,40 @@ +package com.bestsch.classicalchinese.config; + + + + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Value; + +import java.util.ResourceBundle; + +public enum Config { + + Inst; + + 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; + + @Value("${FILE_PATH}") + public String FILE_PATH; + + + + public String getString(String key) + { + ResourceBundle resource = ResourceBundle.getBundle("config"); + return resource.getString(key); + } + + public int getInt(String key) + { + String value = getString(key); + return Integer.parseInt(value); + } + + +} diff --git a/src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java b/src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java new file mode 100644 index 0000000..cd50cba --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/config/DWebMvcConfig.java @@ -0,0 +1,21 @@ +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/config/FileConfig.java b/src/main/java/com/bestsch/classicalchinese/config/FileConfig.java new file mode 100644 index 0000000..9e0bd02 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/config/FileConfig.java @@ -0,0 +1,24 @@ +package com.bestsch.classicalchinese.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +/** + * @author luona + * @date 2021-02-22 10:31 + **/ +@Configuration +@Getter +@Setter +public class FileConfig { + + + @Value("${FILE_PATH}") + private String path; + + @Value("${FILE_WEB_PATH}") + private String webPath; + +} diff --git a/src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java b/src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java new file mode 100644 index 0000000..754389b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/config/RedisConfig.java @@ -0,0 +1,87 @@ +package com.bestsch.classicalchinese.config; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; + +/** + * @author min + * @description + * @date 2019-07-06 + */ +@Slf4j +@Configuration +@EnableCaching +// 自动配置 +@ConditionalOnClass(RedisOperations.class) +@EnableConfigurationProperties(RedisProperties.class) +public class RedisConfig extends CachingConfigurerSupport { + + /** + * 设置 redis 数据默认过期时间,默认1天 + * 设置@cacheable 序列化方式 + * @return + */ + @Bean + public RedisCacheConfiguration redisCacheConfiguration(){ + FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); + RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); + configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofDays(1)); + return configuration; + } + + @Bean(name = "redisTemplate") + @ConditionalOnMissingBean(name = "redisTemplate") + public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + + template.setValueSerializer(jackson2JsonRedisSerializer); + template.setHashValueSerializer(jackson2JsonRedisSerializer); + ParserConfig.getGlobalInstance().addAccept("com.bestsch.modules.system.service.dto"); + // key的序列化采用StringRedisSerializer + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setConnectionFactory(redisConnectionFactory); + return template; + } + + /** + * 自定义缓存key生成策略 + * 使用方法 @Cacheable(keyGenerator="keyGenerator") + * @return + */ + @Bean + @Override + public KeyGenerator keyGenerator() { + return (target, method, params) -> { + StringBuilder sb = new StringBuilder(); + sb.append(target.getClass().getName()); + sb.append(method.getName()); + for (Object obj : params) { + sb.append(JSON.toJSONString(obj).hashCode()); + } + return sb.toString(); + }; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/BaseController.java b/src/main/java/com/bestsch/classicalchinese/controller/BaseController.java new file mode 100644 index 0000000..e579575 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/BaseController.java @@ -0,0 +1,37 @@ +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 new file mode 100644 index 0000000..1b17bd8 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/Handler/ValidationExceptionHandler.java @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..4daddfe --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/BschSettingsController.java @@ -0,0 +1,374 @@ +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 new file mode 100644 index 0000000..164dd3c --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/CommonController.java @@ -0,0 +1,106 @@ +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 new file mode 100644 index 0000000..4ff36d1 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/ExplanationController.java @@ -0,0 +1,127 @@ +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/LoginUserController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/LoginUserController.java new file mode 100644 index 0000000..3140621 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/LoginUserController.java @@ -0,0 +1,51 @@ +package com.bestsch.classicalchinese.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 org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.Enumeration; +import java.util.List; + + +@RestController +@RequestMapping(Config.API_PATH) +@CrossOrigin(origins = {"*", "*"}, 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()); + } + + @GetMapping("GetUserInfo") + public BoaUser getUserInfo(BoaUser authUserWithDept) { + return authUserWithDept; + } + + + @GetMapping("Logout") + protected void logout(HttpServletRequest request) { + HttpSession session = request.getSession(); + Enumeration names = session.getAttributeNames(); + while (names.hasMoreElements()) { + System.out.print(names.nextElement() + ","); + } + session.invalidate(); + System.out.println("logout over"); + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java new file mode 100644 index 0000000..504d50e --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/PunitNodeController.java @@ -0,0 +1,288 @@ +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 new file mode 100644 index 0000000..b95f8e3 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/PunitSettingsController.java @@ -0,0 +1,282 @@ +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 new file mode 100644 index 0000000..410d513 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/RelayController.java @@ -0,0 +1,179 @@ +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 new file mode 100644 index 0000000..b225dbd --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/StatisticsController.java @@ -0,0 +1,55 @@ +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/api/UserController.java b/src/main/java/com/bestsch/classicalchinese/controller/api/UserController.java new file mode 100644 index 0000000..7e1471c --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/api/UserController.java @@ -0,0 +1,48 @@ +package com.bestsch.classicalchinese.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 org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.Enumeration; +import java.util.List; + +@RestController +@RequestMapping(Config.API_PATH +"/base/") +@CrossOrigin(origins = {"*", "*"}, allowCredentials = "true") +public class UserController { + + @Autowired + private BschBaseOpenApi bschBaseOpenApi; + + @GetMapping("getUserMod") + public List getUserMod(BoaUser authUserWithDept) { + return bschBaseOpenApi.getUserModule(authUserWithDept.getId()); + } + + @GetMapping("getUserInfo") + public BoaUser getUserInfo(BoaUser authUserWithDept) { + return authUserWithDept; + } + + + @GetMapping("logout") + protected void logout(HttpServletRequest request) { + HttpSession session = request.getSession(); + Enumeration names = session.getAttributeNames(); + while (names.hasMoreElements()) { + System.out.print(names.nextElement() + ","); + } + session.invalidate(); + System.out.println("logout over"); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java new file mode 100644 index 0000000..bb3280f --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiCommonController.java @@ -0,0 +1,328 @@ +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 new file mode 100644 index 0000000..f848149 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiFileController.java @@ -0,0 +1,231 @@ +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 new file mode 100644 index 0000000..b20c516 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/mobiapi/MobiTeaAreaController.java @@ -0,0 +1,250 @@ +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 new file mode 100644 index 0000000..5c1cede --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/oapi/HyAIController.java @@ -0,0 +1,78 @@ +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 new file mode 100644 index 0000000..08ee984 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/oapi/OapiController.java @@ -0,0 +1,133 @@ +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 new file mode 100644 index 0000000..3d49904 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/controller/oapi/UploadFileController.java @@ -0,0 +1,32 @@ +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 new file mode 100644 index 0000000..8fee058 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/BaseEntity.java @@ -0,0 +1,29 @@ +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 new file mode 100644 index 0000000..8663023 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/BschKnowledge.java @@ -0,0 +1,57 @@ +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 new file mode 100644 index 0000000..3e0cb46 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/BschLeadlearning.java @@ -0,0 +1,47 @@ +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 new file mode 100644 index 0000000..8a03b9b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/BschQuestion.java @@ -0,0 +1,90 @@ +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 new file mode 100644 index 0000000..94f5bc0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/BschTextbook.java @@ -0,0 +1,88 @@ +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 new file mode 100644 index 0000000..e6bfc44 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/BschVideoExplanation.java @@ -0,0 +1,95 @@ +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 new file mode 100644 index 0000000..f686592 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/FeedBack.java @@ -0,0 +1,65 @@ +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 new file mode 100644 index 0000000..35d2638 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/PunitCommunication.java @@ -0,0 +1,63 @@ +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 new file mode 100644 index 0000000..471e57b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/PunitLeadlearning.java @@ -0,0 +1,46 @@ +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 new file mode 100644 index 0000000..c2e7db4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/PunitQuestion.java @@ -0,0 +1,39 @@ +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 new file mode 100644 index 0000000..42852c6 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/PunitStuAnswer.java @@ -0,0 +1,78 @@ +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 new file mode 100644 index 0000000..35e6c30 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/PunitZiYuanTreeTea.java @@ -0,0 +1,28 @@ +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 new file mode 100644 index 0000000..e91313d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/Question.java @@ -0,0 +1,69 @@ +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 new file mode 100644 index 0000000..0d77c2b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/UploadFile.java @@ -0,0 +1,74 @@ +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 new file mode 100644 index 0000000..d332c5b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/entity/VideoExplanation.java @@ -0,0 +1,114 @@ +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 new file mode 100644 index 0000000..ce5b3b3 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/AnswerStatus.java @@ -0,0 +1,36 @@ +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 new file mode 100644 index 0000000..cd013d0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/AppType.java @@ -0,0 +1,33 @@ +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/DifficultLevel.java b/src/main/java/com/bestsch/classicalchinese/enums/DifficultLevel.java new file mode 100644 index 0000000..6b9d524 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/DifficultLevel.java @@ -0,0 +1,88 @@ +package com.bestsch.classicalchinese.enums; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public enum DifficultLevel +{ + I(1, "容易"), + II(2, "中等"), + III(3, "困难"), + IV(4, "不限制难度"), + ; + + private int id; + private String name; + + DifficultLevel(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 String nameById(int id) { + for (DifficultLevel type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + + public static Integer getIdByName(String name) { + for (DifficultLevel 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 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) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/FileType.java b/src/main/java/com/bestsch/classicalchinese/enums/FileType.java new file mode 100644 index 0000000..d32075a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/FileType.java @@ -0,0 +1,37 @@ +package com.bestsch.classicalchinese.enums; + +public enum FileType { + + + IMG_TYPE(1,"图片"), + VIDEO_TYPE(2,"视频"), + AUDIO_TYPE(3,"音频"), + OTHER_TYPE(4,"其他"); + + + + + private int id; + private String name; + + FileType(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 new file mode 100644 index 0000000..c704861 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/GradeEnum.java @@ -0,0 +1,127 @@ +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 new file mode 100644 index 0000000..ed7bc6d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/OcrDataCache.java @@ -0,0 +1,29 @@ +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 new file mode 100644 index 0000000..a9964c8 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/QuestionDifficultyEnum.java @@ -0,0 +1,23 @@ +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/QuestionType.java b/src/main/java/com/bestsch/classicalchinese/enums/QuestionType.java new file mode 100644 index 0000000..cf370b6 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/QuestionType.java @@ -0,0 +1,82 @@ +package com.bestsch.classicalchinese.enums; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public enum QuestionType +{ + I(1, "单选题"), + II(2, "多选题"), + III(3, "判断题"), + IV(4, "解答题"), + V(6, "组合题"), + VI(5, "填空题"), + VII(7, "英语题"); + + private int id; + private String name; + + QuestionType(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(QuestionType.class)); + } + + public static Map map() + { + return list().stream().collect(Collectors.toMap(QuestionType::getId, QuestionType->QuestionType)); + } + + public static String nameById(int id) { + for (QuestionType type : list()) { + if (type.getId() == id) return type.getName(); + } + return null; + } + public static Integer getIdByName(String name) { + for (QuestionType type : list()) { + if (type.getName().equals(name)) return type.getId(); + } + return null; + } + public static QuestionType getById(int id) + { + for (QuestionType na : list()) + { + if (na.getId() == id) + { + return na; + } + } + + return null; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java b/src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java new file mode 100644 index 0000000..d686f63 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/QuestionTypeEnum.java @@ -0,0 +1,22 @@ +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 new file mode 100644 index 0000000..deae235 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/ReviewStatus.java @@ -0,0 +1,33 @@ +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 new file mode 100644 index 0000000..8202816 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection.java @@ -0,0 +1,102 @@ +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 new file mode 100644 index 0000000..4d8ab2a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/SchoolSection_.java @@ -0,0 +1,100 @@ +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 new file mode 100644 index 0000000..707311d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/SourceEnum.java @@ -0,0 +1,37 @@ +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 new file mode 100644 index 0000000..4a25586 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/Subject.java @@ -0,0 +1,105 @@ +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 new file mode 100644 index 0000000..db7710b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/TimeTypeEnum.java @@ -0,0 +1,72 @@ +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/enums/UserRole.java b/src/main/java/com/bestsch/classicalchinese/enums/UserRole.java new file mode 100644 index 0000000..33c2a03 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/enums/UserRole.java @@ -0,0 +1,52 @@ +package com.bestsch.classicalchinese.enums; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum UserRole { + + GENERAL_USER(0,"一般用户"), + TEACHER_USER(1,"教师"), + SCH_LEADER_USER(2,"校领导"), + STU_USER(3,"学生"), + PATRIARCH_USER(4,"家长"), + BUREAU_LEADER_USER(5,"局领导"), + BUSINESS(6,"工作号"), + ADMIN(7,"管理员"), + ; + + private Integer value; + private String name; + + UserRole () { + } + + UserRole ( Integer value, String name) { + this.value = value; + this.name = name; + } + + public Integer getValue() { + return value; + } + + public String getName() { + return name; + } + + public static List> getAll(){ + UserRole[] users = UserRole.values(); + List> list = new ArrayList<>(); + for(UserRole user : users){ + Map map = new HashMap<>(); + map.put("name",user.getName()); + map.put("value",user.getValue()); + list.add(map); + } + return list; + } + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java b/src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java new file mode 100644 index 0000000..7aacd1f --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/AcademicYear.java @@ -0,0 +1,24 @@ +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 new file mode 100644 index 0000000..6150b40 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/AiAsk.java @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..dd56bfa --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/BaseTree.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..a936886 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/ClassInfo.java @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..4808cff --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/ClassModel.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 0000000..bcf64b4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/DateModel.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 0000000..4ee4294 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/DateTimeModel.java @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..3b71326 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/Example.java @@ -0,0 +1,39 @@ +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 new file mode 100644 index 0000000..63c1377 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/ExcelBschLeadlearning.java @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..03caa11 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/ExcelPunitTreeTea.java @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..2fae6c4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/FileMessage.java @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..a174de2 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/Grade.java @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..f305fc2 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/Page.java @@ -0,0 +1,72 @@ +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/PageInfo.java b/src/main/java/com/bestsch/classicalchinese/model/PageInfo.java new file mode 100644 index 0000000..0ac66a6 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/PageInfo.java @@ -0,0 +1,26 @@ +package com.bestsch.classicalchinese.model; + +/** + * @Author wanghu + * @Date 2025-11-10 14:47 (可以根据需要修改) + * @Description: + */ +public class PageInfo { + private int pageNum; + private int pageSize; + private int total; + private int totalPages; + private boolean hasNext; + private boolean hasPrev; + + // 构造方法、getter、setter... + public PageInfo(int pageNum, int pageSize, int total, int totalPages, + boolean hasNext, boolean hasPrev) { + this.pageNum = pageNum; + this.pageSize = pageSize; + this.total = total; + this.totalPages = totalPages; + this.hasNext = hasNext; + this.hasPrev = hasPrev; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java b/src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java new file mode 100644 index 0000000..a4f7ba8 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/SchClassModel.java @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..95c8545 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/SchSub.java @@ -0,0 +1,9 @@ +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 new file mode 100644 index 0000000..c6868fc --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/SchTeaSubGrade.java @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..d0cecb9 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/StartEndDate.java @@ -0,0 +1,14 @@ +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 new file mode 100644 index 0000000..a80396a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/StudentInfo.java @@ -0,0 +1,14 @@ +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 new file mode 100644 index 0000000..595fb24 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/SubGroupTeaIds.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..b6c010d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/SystemGrade.java @@ -0,0 +1,31 @@ +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 new file mode 100644 index 0000000..e80106a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/TeaFirstClass.java @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..6086534 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/TreeDept.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..1bec5f3 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/TreeUser.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..e83736e --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/UserGradeClassSub.java @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..81010a9 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/YearSemester.java @@ -0,0 +1,28 @@ +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 new file mode 100644 index 0000000..9f6ddab --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/dto/PunitDto.java @@ -0,0 +1,24 @@ +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 new file mode 100644 index 0000000..fcf0dd3 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/vo/AiQuestionsVo.java @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..3f67761 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/vo/BschFormQuestionVo.java @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..baf0946 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFilesVo.java @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..f2f2514 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/vo/PunitFormVo.java @@ -0,0 +1,39 @@ +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 new file mode 100644 index 0000000..2645919 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/vo/PunitNodeStuQuestion.java @@ -0,0 +1,50 @@ +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 new file mode 100644 index 0000000..959d253 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/model/vo/SubmitStuQuestionVo.java @@ -0,0 +1,23 @@ +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 new file mode 100644 index 0000000..e4775b4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IBschExplanationService.java @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..3682be4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IBschKnowledgeService.java @@ -0,0 +1,237 @@ +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 new file mode 100644 index 0000000..21ccf5c --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IBschLeadlearningService.java @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..4aed9a3 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IBschQuestionService.java @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..6318fd1 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IBschTextbookService.java @@ -0,0 +1,107 @@ +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 new file mode 100644 index 0000000..2a8cff0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/ICommonService.java @@ -0,0 +1,23 @@ +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 new file mode 100644 index 0000000..8a1ed54 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IExplanationService.java @@ -0,0 +1,28 @@ +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 new file mode 100644 index 0000000..7f83aff --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IFeedBackService.java @@ -0,0 +1,8 @@ +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 new file mode 100644 index 0000000..db8fcc0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IOcrDataCacheService.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..542e596 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IPunitCommunicationService.java @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..967373a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IPunitLeadlearningService.java @@ -0,0 +1,32 @@ +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 new file mode 100644 index 0000000..31b51f9 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IPunitQuestionService.java @@ -0,0 +1,23 @@ +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 new file mode 100644 index 0000000..b930fb8 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IPunitStuAnswerService.java @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000..2c7dd1c --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IPunitZiYuanTreeTeaService.java @@ -0,0 +1,19 @@ +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 new file mode 100644 index 0000000..d93294f --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/IStatisticsService.java @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..4042ed4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/BaseComService.java @@ -0,0 +1,163 @@ +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 new file mode 100644 index 0000000..c2fc59b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/ClassService.java @@ -0,0 +1,813 @@ +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 new file mode 100644 index 0000000..cddd809 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/CommonService.java @@ -0,0 +1,347 @@ +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 new file mode 100644 index 0000000..882811b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/DeepSeekApiService.java @@ -0,0 +1,84 @@ +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 new file mode 100644 index 0000000..6aa53ec --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/DeptSchService.java @@ -0,0 +1,230 @@ +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 new file mode 100644 index 0000000..fd28962 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/HyAIService.java @@ -0,0 +1,314 @@ +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 new file mode 100644 index 0000000..fa12765 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/TeaSchService.java @@ -0,0 +1,81 @@ +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 new file mode 100644 index 0000000..7f55def --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/UploadFileService.java @@ -0,0 +1,195 @@ +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 new file mode 100644 index 0000000..a64b598 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/UserGradeClassSubService.java @@ -0,0 +1,172 @@ +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 new file mode 100644 index 0000000..c45ed7e --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/com/ZiyuankuService.java @@ -0,0 +1,275 @@ +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 new file mode 100644 index 0000000..fae191f --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/BschExplanationService.java @@ -0,0 +1,284 @@ +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 new file mode 100644 index 0000000..a9f4a82 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/BschKnowledgeService.java @@ -0,0 +1,875 @@ +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 new file mode 100644 index 0000000..a001d5a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/BschLeadlearningService.java @@ -0,0 +1,73 @@ +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 new file mode 100644 index 0000000..cbf16bc --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/BschQuestionService.java @@ -0,0 +1,93 @@ +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 new file mode 100644 index 0000000..d8f311d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/BschTextbookService.java @@ -0,0 +1,268 @@ +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 new file mode 100644 index 0000000..46270ee --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/ExplanationService.java @@ -0,0 +1,301 @@ +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 new file mode 100644 index 0000000..a79ec25 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/FeedBackService.java @@ -0,0 +1,22 @@ +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 new file mode 100644 index 0000000..8a2f9e9 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/OcrDataCacheServiceImpl.java @@ -0,0 +1,49 @@ +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 new file mode 100644 index 0000000..cb65e26 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitCommunicationService.java @@ -0,0 +1,143 @@ +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 new file mode 100644 index 0000000..75310e7 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitLeadlearningService.java @@ -0,0 +1,186 @@ +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 new file mode 100644 index 0000000..dcd9483 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitQuestionService.java @@ -0,0 +1,134 @@ +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 new file mode 100644 index 0000000..0af43f4 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitStuAnswerService.java @@ -0,0 +1,699 @@ +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 new file mode 100644 index 0000000..6cd19e2 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/PunitZiYuanTreeTeaService.java @@ -0,0 +1,83 @@ +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 new file mode 100644 index 0000000..6c15eef --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/service/impl/StatisticsService.java @@ -0,0 +1,363 @@ +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/CalendarUtils.java b/src/main/java/com/bestsch/classicalchinese/utils/CalendarUtils.java new file mode 100644 index 0000000..9e5eef5 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/CalendarUtils.java @@ -0,0 +1,40 @@ +package com.bestsch.classicalchinese.utils; + +import java.util.Calendar; + +public class CalendarUtils { + + private static Calendar c = Calendar.getInstance(); + + public static int getYear(){ + return c.get(Calendar.YEAR); + } + + public static int getMonth(){ + return c.get(Calendar.MONTH)+1; //获取月份 + } + + public static int getDay(){ + return c.get(Calendar.DATE); + } + + public static int get12Hour(){ + return c.get(Calendar.HOUR); + } + + public static int get24Hour(){ + return c.get(Calendar.HOUR_OF_DAY); + } + + public static int getMinute(){ + return c.get(Calendar.MINUTE); + } + + public static int getSecond(){ + return c.get(Calendar.SECOND); + } + + public static int getDayOfWeek(){ + return c.get(Calendar.DAY_OF_WEEK); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java b/src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java new file mode 100644 index 0000000..05531ef --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/ChinaDate.java @@ -0,0 +1,322 @@ +package com.bestsch.classicalchinese.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class ChinaDate { + + // private static final Logger logger = LoggerFactory.getLogger(CalendarUtil.class); + // 计算阴历日期参照1900年到2049年 + private final static int[] LUNAR_INFO = { + 0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2, + 0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977, + 0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970, + 0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950, + 0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557, + 0x06ca0,0x0b550,0x15355,0x04da0,0x0a5d0,0x14573,0x052d0,0x0a9a8,0x0e950,0x06aa0, + 0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0, + 0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b5a0,0x195a6, + 0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570, + 0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0, + 0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5, + 0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930, + 0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530, + 0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45, + 0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0 + }; + + // 允许输入的最小年份 + private final static int MIN_YEAR = 1900; + // 允许输入的最大年份 + private final static int MAX_YEAR = 2049; + // 当年是否有闰月 + private static boolean isLeapYear; + // 阳历日期计算起点 + private final static String START_DATE = "1900-01-30"; + + + /** + * 计算阴历 {@code year}年闰哪个月 1-12 , 没闰传回 0 + * @param year 阴历年 + * @return (int)月份 + */ + private static int getLeapMonth(int year) { + return (int) (LUNAR_INFO[year - 1900] & 0xf); + } + + /** + * 计算阴历{@code year}年闰月多少天 + * @param year 阴历年 + * @return (int)天数 + */ + private static int getLeapMonthDays(int year) { + if(getLeapMonth(year)!=0){ + if((LUNAR_INFO[year - 1900] & 0xf0000)==0){ + return 29; + }else { + return 30; + } + }else{ + return 0; + } + } + + /** + * 计算阴历{@code lunarYeay}年{@code month}月的天数 + * @param lunarYeay 阴历年 + * @param month 阴历月 + * @return (int)该月天数 + * @throws Exception + */ + private static int getMonthDays(int lunarYeay, int month) throws Exception { + if ((month > 31) || (month < 0)) { + throw(new Exception("月份有错!")); + } + // 0X0FFFF[0000 {1111 1111 1111} 1111]中间12位代表12个月,1为大月,0为小月 + int bit = 1 << (16-month); + if(((LUNAR_INFO[lunarYeay - 1900] & 0x0FFFF)&bit)==0){ + return 29; + }else { + return 30; + } + } + + /** + * 计算阴历{@code year}年的总天数 + * @param year 阴历年 + * @return (int)总天数 + */ + private static int getYearDays(int year) { + int sum = 29*12; + for(int i=0x8000;i>=0x8;i>>=1){ + if((LUNAR_INFO[year-1900]&0xfff0&i)!=0){ + sum++; + } + } + return sum+getLeapMonthDays(year); + } + + /** + * 计算两个阳历日期相差的天数。计算不准确,已经废弃 + * @param startDate 开始时间 + * @param endDate 截至时间 + * @return (int)天数 + */ + @Deprecated + private static int daysBetween2(Date startDate, Date endDate) { + long between_days=(endDate.getTime()-startDate.getTime())/(1000*3600*24); + + return Integer.parseInt(String.valueOf(between_days)); + } + + /** + * 计算两个阳历日期相差的天数。 + * @param startDate 开始时间 + * @param endDate 截至时间 + * @return (int)天数 + */ + private static int daysBetween(Date startDate, Date endDate) { + int days = 0; + //将转换的两个时间对象转换成Calendar对象 + Calendar can1 = Calendar.getInstance(); + can1.setTime(startDate); + Calendar can2 = Calendar.getInstance(); + can2.setTime(endDate); + //拿出两个年份 + int year1 = can1.get(Calendar.YEAR); + int year2 = can2.get(Calendar.YEAR); + //天数 + + Calendar can = null; + //如果can1 < can2 + //减去小的时间在这一年已经过了的天数 + //加上大的时间已过的天数 + if(can1.before(can2)){ + days -= can1.get(Calendar.DAY_OF_YEAR); + days += can2.get(Calendar.DAY_OF_YEAR); + can = can1; + }else{ + days -= can2.get(Calendar.DAY_OF_YEAR); + days += can1.get(Calendar.DAY_OF_YEAR); + can = can2; + } + for (int i = 0; i < Math.abs(year2-year1); i++) { + //获取小的时间当前年的总天数 + days += can.getActualMaximum(Calendar.DAY_OF_YEAR); + //再计算下一年。 + can.add(Calendar.YEAR, 1); + } + return days; + } + + /** + * 检查阴历日期是否合法 + * @param lunarYear 阴历年 + * @param lunarMonth 阴历月 + * @param lunarDay 阴历日 + * @param leapMonthFlag 闰月标志 + * @throws Exception + */ + private static void checkLunarDate(int lunarYear, int lunarMonth, int lunarDay, boolean leapMonthFlag) throws Exception { + if ((lunarYear < MIN_YEAR) || (lunarYear > MAX_YEAR)) { + throw(new Exception("非法农历年份!")); + } + if ((lunarMonth < 1) || (lunarMonth > 12)) { + throw(new Exception("非法农历月份!")); + } + if ((lunarDay < 1) || (lunarDay > 30)) { // 中国的月最多30天 + throw(new Exception("非法农历天数!")); + } + + int leap = getLeapMonth(lunarYear);// 计算该年应该闰哪个月 + if ((leapMonthFlag == true) && (lunarMonth != leap)) { + throw(new Exception("非法闰月!")); + } + } + + /** + * 阴历转换为阳历 + * @param lunarDate 阴历日期,格式YYYYMMDD + * @param leapMonthFlag 是否为闰月 + * @return 阳历日期,格式:YYYYMMDD + * @throws Exception + */ + public static String lunarToSolar(String lunarDate, boolean leapMonthFlag) throws Exception{ + int lunarYear = Integer.parseInt(lunarDate.substring(0, 4)); + int lunarMonth = Integer.parseInt(lunarDate.substring(4, 6)); + int lunarDay = Integer.parseInt(lunarDate.substring(6, 8)); + + checkLunarDate(lunarYear, lunarMonth, lunarDay, leapMonthFlag); + + int offset = 0; + + for (int i = MIN_YEAR; i < lunarYear; i++) { + int yearDaysCount = getYearDays(i); // 求阴历某年天数 + offset += yearDaysCount; + } + //计算该年闰几月 + int leapMonth = getLeapMonth(lunarYear); + + if(leapMonthFlag & leapMonth != lunarMonth){ + throw(new Exception("您输入的闰月标志有误!")); + } + + //当年没有闰月或月份早于闰月或和闰月同名的月份 + if(leapMonth==0|| (lunarMonth < leapMonth) || (lunarMonth==leapMonth && !leapMonthFlag)){ + for (int i = 1; i < lunarMonth; i++) { + int tempMonthDaysCount = getMonthDays(lunarYear, i); + offset += tempMonthDaysCount; + } + + // 检查日期是否大于最大天 + if (lunarDay > getMonthDays(lunarYear, lunarMonth)) { + throw(new Exception("不合法的农历日期!")); + } + offset += lunarDay; // 加上当月的天数 + }else{//当年有闰月,且月份晚于或等于闰月 + for (int i = 1; i < lunarMonth; i++) { + int tempMonthDaysCount = getMonthDays(lunarYear, i); + offset += tempMonthDaysCount; + } + if (lunarMonth>leapMonth) { + int temp = getLeapMonthDays(lunarYear); // 计算闰月天数 + offset += temp; // 加上闰月天数 + + if (lunarDay > getMonthDays(lunarYear, lunarMonth)) { + throw(new Exception("不合法的农历日期!")); + } + offset += lunarDay; + }else { // 如果需要计算的是闰月,则应首先加上与闰月对应的普通月的天数 + // 计算月为闰月 + int temp = getMonthDays(lunarYear, lunarMonth); // 计算非闰月天数 + offset += temp; + + if (lunarDay > getLeapMonthDays(lunarYear)) { + throw(new Exception("不合法的农历日期!")); + } + offset += lunarDay; + } + } + + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + Date myDate = null; + myDate = formatter.parse(START_DATE); + Calendar c = Calendar.getInstance(); + c.setTime(myDate); + c.add(Calendar.DATE, offset); + myDate = c.getTime(); + + return formatter.format(myDate); + } + + /** + * 阳历日期转换为阴历日期 + * @param solarDate 阳历日期,格式YYYYMMDD + * @return 阴历日期 + * @throws Exception + */ + public static String solarToLunar(String solarDate, Boolean isFormat) throws Exception{ + int i; + int temp = 0; + int lunarYear; + int lunarMonth; //农历月份 + int lunarDay; //农历当月第几天 + boolean leapMonthFlag =false; + + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + Date myDate = null; + Date startDate = null; + try { + myDate = formatter.parse(solarDate); + startDate = formatter.parse(START_DATE); + } catch (ParseException e) { +// e.printStackTrace(); + } + + int offset = daysBetween(startDate,myDate); + + for (i = MIN_YEAR; i <= MAX_YEAR; i++){ + temp = getYearDays(i); //求当年农历年天数 + if (offset - temp < 1){ + break; + }else{ + offset -= temp; + } + } + lunarYear = i; + + int leapMonth = getLeapMonth(lunarYear);//计算该年闰哪个月 + //设定当年是否有闰月 + if (leapMonth > 0){ + isLeapYear = true; + }else{ + isLeapYear = false; + } + + for (i = 1; i<=12; i++) { + if(i==leapMonth+1 && isLeapYear){ + temp = getLeapMonthDays(lunarYear); + isLeapYear = false; + leapMonthFlag = true; + i--; + }else{ + temp = getMonthDays(lunarYear, i); + } + offset -= temp; + if(offset<=0){ + break; + } + } + + offset += temp; + lunarMonth = i; + lunarDay = offset; + + if(isFormat) + return "阴历:"+lunarYear+"年"+(leapMonthFlag&(lunarMonth==leapMonth)?"闰":"")+lunarMonth+"月"+lunarDay+"日"; + return "" + lunarYear + lunarMonth + lunarDay; + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java new file mode 100644 index 0000000..339bdc8 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/ConstantUtil.java @@ -0,0 +1,19 @@ +package com.bestsch.classicalchinese.utils; + +public class ConstantUtil { + + /** + * redis过期时间 + */ + public static final long EXPIRE_TIME=60*60*8; + + /** + * redis前缀 + */ + public static final String PREFIX_KEY="bsch.evaluate.";//redis前缀 + + /** + * 个人常用应用 + */ + public static final String USEDAPP_KEY=PREFIX_KEY+"usedapp"; +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java new file mode 100644 index 0000000..b674d5a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/DateRangeUtil.java @@ -0,0 +1,47 @@ +package com.bestsch.classicalchinese.utils; + +import org.apache.http.client.utils.DateUtils; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; + +public class DateRangeUtil { + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + /** + * 根据类型获取日期范围 + * @param type 1:今日 2:本周 3:本月 + * @return Map containing "startDate" and "endDate" in yyyy-MM-dd format + */ + public static Map getDateRange(int type) { + Map result = new HashMap<>(); + LocalDate today = LocalDate.now(); + + switch (type) { + case 1: // 今日 + result.put("startDate", DateUtils.parseDate(today.format(FORMATTER)+" 00:00:00")); + result.put("endDate", DateUtils.parseDate(today.format(FORMATTER)+" 23:59:00")); + break; + + case 2: // 本周 + LocalDate monday = today.with(DayOfWeek.MONDAY); + LocalDate sunday = today.with(DayOfWeek.SUNDAY); + result.put("startDate", DateUtils.parseDate(monday.format(FORMATTER)+" 00:00:00")); + result.put("endDate",DateUtils.parseDate( sunday.format(FORMATTER)+" 23:59:00")); + break; + + case 3: // 本月 + LocalDate firstDay = today.withDayOfMonth(1); + LocalDate lastDay = today.withDayOfMonth(today.lengthOfMonth()); + result.put("startDate", DateUtils.parseDate(firstDay.format(FORMATTER)+" 00:00:00")); + result.put("endDate", DateUtils.parseDate(lastDay.format(FORMATTER)+" 23:59:00")); + break; + + default: + throw new IllegalArgumentException("不支持的type类型: " + type); + } + + return result; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java new file mode 100644 index 0000000..2765022 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/DicUtil.java @@ -0,0 +1,374 @@ +package com.bestsch.classicalchinese.utils; + + +/** + * @ Description : 存储魔法值 + * @ Author : cls + * @ CreateDate : 2020/2/1 9:24 + * @ Company : bestsch + */ +public class DicUtil { + + /** + * 超管id + */ + public static final Integer SUPER_ADMIN_ID = 100000; + + public static final String UNKNOWN = "未知"; + + /** + * 一般hashMap初始化大小 + */ + public static final int initialCapacity = 6; + + /** + * 缓存时间,单位毫秒 + */ + public static final long ONE_DAY = 1000 * 60 * 60 * 24; + public static final long TEN_MINUTES = 1000 * 60 * 10; + public static final long FIVE_MINUTES = 1000 * 60 * 5; + public static final long ONE_MINUTE = 1000 * 60; + public static final long HALF_MINUTE = 1000 * 30; + public static final long THREE_SECONDS = 1000 * 3; + + /** + * 默认的学科类型 6 代表其他 + */ + public static final String DEFAULT_RESOURCE_TYPE = "6"; + + /** + * 数据状态 1 有效 + */ + public static final Integer STATUS_VALID = 1; + + /** + * 数据状态 0 无效 + */ + public static final Integer STATUS_INVALID = 0; + + /** + * 审核状态 0 待审 + */ + public static final Integer REVIEW_STATUS_TODO = 0; + + /** + * 审核状态 1 通过 + */ + public static final Integer REVIEW_STATUS_PASS = 1; + + /** + * 审核状态 2 未通过 + */ + public static final Integer REVIEW_STATUS_NOPASS = 2; + + /** + * 用户类别 用户中心数据,2 组管理员 + */ +// public static final Integer USER_TYPE_GROUP_MANAGER = 2; + + /** + * 用户类别 用户中心数据,1 超级管理员 + */ + public static final Integer USER_TYPE_SUPER_MANAGER = 1; + + /** + * 目录所属来源 “我的文件”模块 + */ + public static final Integer SOURCE_MY_FILES = 0; + + /** + * 目录所属来源 “我的收藏”模块 + */ + public static final Integer SOURCE_MY_COLLECTION = 1; + + /** + * 目录所属来源 “教研组共享”模块 + */ + public static final Integer SOURCE_GROUP = 2; + + /** + * 目录所属来源 “草稿箱模块[学校]” + */ + public static final Integer SOURCE_DRAFTS_SYSTEM= 3; + + /** + * 目录所属来源 “草稿箱模块[个人]” + */ + public static final Integer SOURCE_DRAFTS_USER= 4; + + /** + * 根目录默认名称 + */ + public static final String ROOT_FOLDER_NAME = "根目录"; + + /** + * 文印系统资源默认保存文件夹名称 + */ + public static final String SEAL_FOLDER_NAME = "文印文档"; + + /** + * 外部系统资源默认保存文件夹名称 + */ + public static final String DEFAULT_OUTER_FOLDER = "外部系统文档"; + + /** + * 默认头像 + */ + public static final String DEFAULT_PIC = "http://base.bestsch.com/img/defprofilepic.png"; + + /** + * 排序 降序 0 + */ + public static final Integer ORDER_DESC = 0; + + /** + * 排序 升序 1 + */ + public static final Integer ORDER_ASC = 1; + + /** + * 垃圾来源,0文件夹-资源 + */ + public static final Integer RUBBISH_SOURCE_FOLDER_TO_RESOURCE = 0; + + /** + * 垃圾来源,1知识章节-资源 + */ + public static final Integer RUBBISH_SOURCE_KNOWLEDGE_TO_RESOURCE = 1; + + /** + * 垃圾来源,2文件夹 + */ + public static final Integer RUBBISH_SOURCE_FOLDER = 2; + + /** + * 垃圾来源,3 专题资源 + */ + public static final Integer RUBBISH_SOURCE_SPECIAL = 3; + + /** + * 文件类型 资源 + */ + public static final Integer FILE_TYPE_RESOURCE = 0; + + /** + * 文件类型 文件夹 + */ + public static final Integer FILE_TYPE_FOLDER = 1; + + /** + * memCached全局标签 + */ + public static final String MEMCACHED_GLOBAL_TAG = "_ziyuanku_"; + + /** + * 区间参数 不包括 + */ + public static final int SECTION_NO_INCLUDE = 0; + + /** + * 区间参数 包括 + */ + public static final int SECTION_INCLUDE = 1; + + /** + * 51铃铛关键词 + */ + public static final String LINGDANG_KEY = "51lingdang"; + + /** + * 学习中心路径头部 + */ + public static final String LEARN_CENTER_HEADER = "http:///learn.bestsch.com"; + + /** + * 分享去向 folder + */ + public static final String WHEREABOUTS_FOLDER = "folder"; + + /** + * 分享去向 knowledge + */ + public static final String WHEREABOUTS_KNOWLEDGE = "knowledge"; + + /** + * 分享去向 special + */ + public static final String WHEREABOUTS_SPECIAL = "special"; + + /** + * 分享去向 node + */ + public static final String WHEREABOUTS_NODE = "node"; + + /** + * 错误消息,数据不存在 + */ + public static final String ERROR_MSG_NOT_FOUND = "数据不存在,可能已被删除"; + + /** + * 错误消息,无操作权限 + */ + public static final String ERROR_MSG_NO_POWER = "您无操作权限"; + + /** + * 错误信息,上传文件失败 + */ + public static final String ERROR_MSG_IMPORT_WRONG = "上传失败,请稍后再试"; + + /** + * 错误信息,对应关系已存在 + */ + public static final String ERROR_MSG_RELATION_EXISTED = "您选择的节点下已存在此文件"; + + /** + * 错误信息,无法对收藏来的文件夹进行操作 + */ + public static final String ERROR_MSG_IS_OTHERS_FOLDER = "无法对收藏来的文件夹进行操作"; + + /** + * 错误消息,重复收藏 + */ + public static final String ERROR_MSG_COLLECT_EXISTED = "此文件已在您的收藏夹里"; + + /** + * 错误消息,目标文件夹不是收藏模块里的文件夹 + */ + public static final String ERROR_MSG_COLLECT_NOT_YOUR = "此文件夹不属于‘我的收藏’模块"; + + /** + * 错误消息,资源大小超出限制 + */ + public static final String ERROR_MSG_TOO_BIG = "文件大小超出限制"; + + /** + * 错误消息,网盘空间超出限制 + */ + public static final String ERROR_MSG_ZONE_BREAK = "网盘空间不足"; + + /** + * 错误消息,文件类型不符合要求 + */ + public static final String ERROR_MSG_NO_EXT = "文件类型不符合要求"; + + /** + * 错误消息,名称冲突 + */ + public static final String ERROR_NAME_EXISTED = "此位置已经包含同名文件"; + + /** + * 错误消息,不能跨层级移动 + */ + public static final String ERROR_NO_LEVEL = "不支持跨层级移动"; + + /** + * 错误消息,资源不属于51 + */ + public static final String ERROR_NOT_51LINGDANG = "此资源不属于51铃铛平台,请调用正确的接口"; + + /** + * 错误消息,资源属于51 + */ + public static final String ERROR_ONLY_ON_OUTER = "此资源属于外部平台,请调用正确的接口"; + + /** + * 错误消息,文件不存在 + */ + public static final String ERROR_FILE_NOT_FOUND = "文件不存在,可能已被删除"; + + /** + * 错误消息,角色已存在 + */ + public static final String ERROR_ROLE_IS_EXISTED = "当前用户已拥有此角色"; + + /** + * 错误消息,身份未指定 + */ + public static final String NO_CHOICE_ID = "请先指定您的身份"; + + /** + * 错误消息,身份中没有相关联的学校 + */ + public static final String NO_SCHOOL_IN_ID = "您的身份不存在关联的学校信息"; + + /** + * 错误消息,超过层级上限 + */ + //public static final String OVER_MAX_LEVEL = "层级超过上限,最多支持" + (MAX_LEVEL + 1) + "层"; + + /** + * 错误消息,没有资源录入权限,也就没有查看/编辑/移动资源的权限 + */ + //public static final String NO_ZYLR_OF_NODE = "您缺少此节点的【" + ZYLR.getCnKey() + "】权限"; + + /** + * 错误消息,没有节点编辑权限 + */ + //public static final String NO_JDBJ_OF_NODE = "您缺少此节点的【" + JDBJ.getCnKey() + "】权限"; + + /** + * 错误消息,没有根节点编辑权限 + */ + //public static final String NO_JDBJ_OF_ROOT_NODE = "您缺少根节点的【" + JDBJ.getCnKey() + "】权限"; + + /** + * 错误消息,无权删除资源 + */ + public static final String NO_POWER_TO_DEL_RESOURCE = "您无法删除此文件"; + + /** + * 错误消息,无权编辑资源 + */ + public static final String NO_POWER_TO_MODIFY_RESOURCE = "您无法编辑/移动此文件"; + + /** + * 错误消息,无权移动到新节点 + */ + //public static final String NO_POWER_TO_MOVE_RESOURCE = "您无法把文件移至新节点,因为" + NO_ZYLR_OF_NODE; + + /** + * 错误消息,无权移动到根节点 + */ + public static final String NO_MOVE_TO_ROOT = "您无法把文件移至根节点"; + + /** + * 错误消息,无法删除此节点 + */ + public static final String NOT_DEL_NODE = "无法删除,请先移动或删除此节点下的文件"; + + /** + * 错误消息,没有可查看的节点 + */ + public static final String NO_NODE_BY_WATCH = "您暂无可查看的节点"; + + /** + * 错误消息,未知的教材来源 + */ + public static final String UNKNOWN_TEXTBOOK_SOURCE = "未知的教材来源"; + + /** + * 错误消息,无法对根节点进行操作 + */ + public static final String CANT_OPERATE_FOR_ROOT = "无法对根节点进行操作"; + + /** + * 错误消息,未知的权限类型 + */ + public static final String UNKNOWN_AUTHORITY_TYPE = "未知的权限类型"; + + /** + * 错误消息,无权编辑资源 + */ + public static final String NO_STUDENT = "不是学生身份无法查看"; + + /** + * 错误消息,节点不存在 + */ + public static final String NO_NODE = "节点不存在"; + + /** + * 错误消息,无权删除已分享的资源 + */ + public static final String NO_TO_DEL_RESOURCE_OF_SHARE = "该文件已被分享,无法删除。若需删除,请先取消分享"; + +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java new file mode 100644 index 0000000..2233129 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/DownloadFileUtil.java @@ -0,0 +1,56 @@ +package com.bestsch.classicalchinese.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import java.io.*; + +@Slf4j +public class DownloadFileUtil { + + public static final String separator = File.separator; + + /** + * 下载样表 + * @param filePath 文件上级目录 + * @param fileName 文件名 + * @param newName 下载的展示文件名 + * @return 响应 + */ + public static ResponseEntity download(String filePath, String fileName, String newName) { +// String route = "static" + separator + "templates" + separator; +// String path = null; + ResponseEntity response = null; + try { +// path = route + filePath + separator + fileName; + + File file = new File(filePath); + + System.out.println(file.exists()); + + +// ClassPathResource classPathResource = new ClassPathResource(filePath); + InputStream inputStream = new FileInputStream(file); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); + headers.add("Content-Disposition", + "attachment; filename=" + + new String(newName.getBytes("gbk"), "iso8859-1")); + headers.add("Pragma", "no-cache"); + headers.add("Expires", "0"); + response = ResponseEntity.ok().headers(headers) + .contentType(MediaType.parseMediaType("application/octet-stream")) + .body(new InputStreamResource(inputStream)); + } catch (FileNotFoundException e1) { + log.error("找不到指定的文件", e1); + } catch (IOException e) { + log.error("获取不到文件流", e); + } + return response; + } +} + diff --git a/src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java b/src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java new file mode 100644 index 0000000..b4f56f0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/EasyPoiUtils.java @@ -0,0 +1,82 @@ +package com.bestsch.classicalchinese.utils; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.word.WordExportUtil; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xwpf.usermodel.XWPFDocument; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; + +public final class EasyPoiUtils { + + private EasyPoiUtils() {} + + /** + * 只能xls + * @param fileName + * @param response + * @param workbook + */ + public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) { + try { + response.setCharacterEncoding("UTF-8"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + workbook.write(response.getOutputStream()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void defaultExport(List dataList, Class clz, String fileName, HttpServletResponse response, ExportParams exportParams) { + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, clz, dataList); + if (workbook != null) { + downLoadExcel(fileName, response, workbook); + } + } + + public static void exportExcel(List dataList, String title, String sheetName, Class clz, String fileName, boolean isCreateHeader, HttpServletResponse response) { + ExportParams exportParams = new ExportParams(title, sheetName); + exportParams.setCreateHeadRows(isCreateHeader); + defaultExport(dataList, clz, fileName, response, exportParams); + } + + public static void exportExcel(List dataList, String title, String sheetName, Class clz, String fileName, HttpServletResponse response) { + defaultExport(dataList, clz, fileName, response, new ExportParams(title, sheetName)); + } + /** + * 导出word + */ + public static void exportWord(String fileName, Map map, HttpServletRequest request, HttpServletResponse response) { + + try { + String userAgent = request.getHeader("user-agent").toLowerCase(); + if (userAgent.contains("msie") || userAgent.contains("like gecko")) { + fileName = URLEncoder.encode(fileName, "UTF-8"); + } else { + fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1"); + } + XWPFDocument doc = WordExportUtil.exportWord07( + "/Users/luona/Downloads/模版.docx", map); + // 设置强制下载不打开 + response.setContentType("application/force-download"); + // 设置文件名 + response.addHeader("Content-Disposition", "attachment;fileName=" + fileName); + OutputStream out = response.getOutputStream(); + doc.write(out); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java new file mode 100644 index 0000000..bc21311 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/EnumUtil.java @@ -0,0 +1,151 @@ +package com.bestsch.classicalchinese.utils; + +import org.apache.commons.lang.StringUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @program: ResearchLearn + * @description: 枚举工具类 + * @author: chenx + * @create: 2023-05-26 14:05 + **/ + +public final class EnumUtil { + /** + * 枚举转List格式 + * + * @param targetEnumClazz 目标枚举Clazz + */ + public static List> toMapList(Class targetEnumClazz) { + //获取方法 + Method[] methods = targetEnumClazz.getMethods(); + Field[] fields = targetEnumClazz.getDeclaredFields(); + List fieldList = new ArrayList(); + for (Method method : methods) { + for (Field field : fields) { + if (method.getName().endsWith(StringUtils.capitalize(field.getName()))) { + fieldList.add(field); + } + } + } + List> resultList = new ArrayList(); + //获取值 + Enum[] enums = (Enum[]) targetEnumClazz.getEnumConstants(); + Object value = null; + + try { + for (Enum e : enums) { + Map eMap = new HashMap(); + String enumNameValue = e.name(); + for (Field field : fieldList) { + // 对于private的属性,如果不解锁,那么将无法访问,会报错 + field.setAccessible(true); + // 通过反射的字段获取实体中的值 + value = field.get(e); + eMap.put(field.getName(), value); + } + eMap.put("enum",e); + resultList.add(eMap); + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return resultList; + } + + /** + * 通过枚举key获取对应的枚举值 + * + * @param targetEnumClazz 目标枚举Clazz + * @param key 对应的枚举值 + */ + public static String getValue(Class targetEnumClazz, String key) { + List> list = toMapList(targetEnumClazz); + for (Map map : list) { + if (map.get("key").toString().equals(key)) { + return map.get("value").toString(); + } + } + return ""; + } + + /** + * 通过枚举值获取对应的枚举key + * + * @param targetEnumClazz 目标枚举Clazz + * @param value 对应的枚举值 + */ + public static String getKey(Class targetEnumClazz, String value) { + List> list = toMapList(targetEnumClazz); + for (Map map : list) { + if (map.get("value").toString().equals(value)) { + return map.get("key").toString(); + } + } + return ""; + } + + /** + * 通过枚举key获取对应的枚举 + * + * @param targetEnumClazz 目标枚举Clazz + * @param key 对应的枚举值 + */ + public static Object getEnumByKey(Class targetEnumClazz, String key) { + List> list = toMapList(targetEnumClazz); + for (Map map : list) { + if (map.get("key").toString().equals(key)) { + return map.get("enum"); + } + } + return null; + } + + /** + * 是否存在此key + * + * @param targetEnumClazz 目标枚举Clazz + * @param key 对应的枚举值 + */ + public static boolean isExistKey(Class targetEnumClazz,String key){ + List> list = toMapList(targetEnumClazz); + return list.stream().filter(x->x.get("key").equals(key)).count()>0; + } + + /** + * 是否存在此value + * + * @param targetEnumClazz 目标枚举Clazz + * @param value 对应的枚举值 + */ + public static boolean isExistValue(Class targetEnumClazz,String value){ + List> list = toMapList(targetEnumClazz); + return list.stream().filter(x->x.get("value").equals(value)).count()>0; + } + + + /** + * 是否存在此value + * + * @param keyName 自定义key + * @param valueName 自定义value + */ + public static List> toMapList(Class targetEnumClazz,String keyName,String valueName) { + List> list = toMapList(targetEnumClazz); + List result = new ArrayList(); + for (Map map : list) { + Map newMap = new HashMap(); + newMap.put(keyName, map.get("key")); + newMap.put(valueName, map.get("value")); + result.add(newMap); + } + return result; + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java new file mode 100644 index 0000000..b3ce7ba --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/FileUtil.java @@ -0,0 +1,513 @@ +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/HttpUtils.java b/src/main/java/com/bestsch/classicalchinese/utils/HttpUtils.java new file mode 100644 index 0000000..412192d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/HttpUtils.java @@ -0,0 +1,143 @@ +package com.bestsch.classicalchinese.utils; + +import com.bestsch.utils.DException; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.ByteBuffer; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; + +public class HttpUtils { + static { + try { + trustAllHttpsCertificates(); + HttpsURLConnection.setDefaultHostnameVerifier + ( + (urlHostName, session) -> true + ); + } catch (Exception e) { + } + } + /** + * 跳过ssl证书 + * + * @throws NoSuchAlgorithmException + * @throws KeyManagementException + */ + private static void trustAllHttpsCertificates() + throws NoSuchAlgorithmException, KeyManagementException { + TrustManager[] trustAllCerts = new TrustManager[1]; + trustAllCerts[0] = (TrustManager) new TrustAllManager(); + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, null); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } + + private static class TrustAllManager implements X509TrustManager { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + } + + public static String get(String aUrl,Integer timeout){ + int respCode = 0; + HttpURLConnection conn = null; + String var3; + try { + conn = getHttpURLConnection(aUrl, "GET",timeout); + conn.setDoInput(true); + respCode = conn.getResponseCode(); + if (respCode != 301) { + InputStream is = conn.getInputStream(); + int contentLen = conn.getContentLength(); + byte[] resultData = read(is, contentLen); + is.close(); + String var6 = new String(resultData, "utf-8"); + return var6; + } + var3 = get(conn.getHeaderField("Location"),timeout); + } catch (Exception var10) { + throw new DException("网络连接失败"); + } finally { + close(conn); + } + return var3; + } + + + private static HttpURLConnection getHttpURLConnection(String uri, String method,int timeout) throws IOException { + URL url = new URL(uri); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + conn.setRequestMethod(method); + conn.setConnectTimeout(timeout); + conn.setReadTimeout(timeout); + return conn; + } + + private static byte[] read(InputStream is, int contentLen) throws IOException { + if (contentLen <= 0) { + int BUF_SIZE = 102400; + byte[] buf = new byte[102400]; + ByteBuffer byteBuffer = ByteBuffer.allocate(102400); + + int readed; + do { + if (byteBuffer.position() + 102400 > byteBuffer.capacity()) { + byteBuffer = reallocByteBuffer(byteBuffer, byteBuffer.capacity() + 102400); + } + + readed = is.read(buf, 0, 102400); + if (readed > 0) { + byteBuffer.put(buf, 0, readed); + } + } while(readed != -1); + + byte[] data = new byte[byteBuffer.position()]; + System.arraycopy(byteBuffer.array(), 0, data, 0, byteBuffer.position()); + return data; + } else { + byte[] data = new byte[contentLen]; + + int readed; + for(int remain = contentLen; remain > 0; remain -= readed) { + readed = is.read(data, contentLen - remain, remain); + if (readed == -1) { + break; + } + } + + return data; + } + } + private static ByteBuffer reallocByteBuffer(ByteBuffer buffer, int size) { + ByteBuffer newBuf = ByteBuffer.allocate(size); + newBuf.put(buffer.array(), 0, buffer.position()); + return newBuf; + } + private static void close(HttpURLConnection conn) { + try { + if (conn == null) { + return; + } + + conn.disconnect(); + } catch (Exception var2) { + var2.printStackTrace(); + } + + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java new file mode 100644 index 0000000..cb52fe0 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/JavaBeanUtil.java @@ -0,0 +1,73 @@ +package com.bestsch.classicalchinese.utils; + +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.http.client.utils.DateUtils; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * @ Description : javaBean工具类 + * @ Author : cls + * @ CreateDate : 2020/2/3 20:21 + * @ Company : bestsch + */ +public class JavaBeanUtil { + + /** + * bean转map + * @param obj + * @return + */ + public static Map beanToMap(Object obj) { + if (obj == null) { + return new HashMap<>(); + } + Map map = new HashMap(); + try { + BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor property : propertyDescriptors) { + String key = property.getName(); + // 过滤class属性 + if (!key.equals("class")) { + //若属性被jsonignore注解修饰,则跳过转换 + JsonIgnoreProperties jsonIgnore = property.getPropertyType().getAnnotation(JsonIgnoreProperties.class); + if(jsonIgnore != null){ + continue; + } + // 得到property对应的getter方法 + Method getter = property.getReadMethod(); + Object value = getter.invoke(obj); + if(value != null && value.getClass().equals(Timestamp.class)){ + JsonFormat jsonFormat = property.getPropertyType().getAnnotation(JsonFormat.class); + if(jsonFormat != null){ + value = DateUtils.formatDate((Date)value,jsonFormat.pattern()); + }else{ + value = DateUtils.formatDate((Date)value); + } + } + if(null == value){ + map.put(key,null); + }else{ + map.put(key,value); + } + } + } + } catch (Exception e) { + } + return map; + } + + public static Map beanToJsonMap(Object object){ + return (Map) JSONObject.toJSON(object); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java new file mode 100644 index 0000000..cd63a6a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/ListMapSortUtil.java @@ -0,0 +1,47 @@ +package com.bestsch.classicalchinese.utils; + + +import java.util.List; +import java.util.Map; +import java.util.Comparator; + +public class ListMapSortUtil { + + // 针对Integer类型的排序 + public static void sortByIntegerKey(List list, String key) { + list.sort(Comparator.comparing(map -> (Integer) map.get(key))); + } + + // 针对Double类型的排序 + public static void sortByDoubleKey(List list, String key) { + list.sort(Comparator.comparing(map -> (Double) map.get(key))); + } + + // 更通用的方法,使用Number并转换为Double进行比较(适用于整数和浮点数) + public static void sortByNumberKey(List list, String key) { + list.sort(Comparator.comparing(map -> ((Number) map.get(key)).doubleValue())); + } + + // 支持升序降序 + public static void sortByIntegerKey(List list, String key, boolean ascending) { + Comparator comparator = Comparator.comparing(map -> (Integer) map.get(key)); + if (!ascending) { + comparator = comparator.reversed(); + } + list.sort(comparator); + } + + // 支持null值处理,将null视为最小值 + public static void sortByIntegerKeyWithNullsFirst(List list, String key) { + list.sort(Comparator.comparing( + map -> (Integer) map.get(key), + Comparator.nullsFirst(Comparator.naturalOrder()) + )); + } + + // 更通用的方法,支持任意Comparable类型,包括String、Integer等 + @SuppressWarnings("unchecked") + public static > void sortByKey(List list, String key) { + list.sort(Comparator.comparing(map -> (T) map.get(key))); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java new file mode 100644 index 0000000..ea03e8d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/ModelMapperUtil.java @@ -0,0 +1,201 @@ +package com.bestsch.classicalchinese.utils; + +import org.modelmapper.ModelMapper; +import org.modelmapper.convention.MatchingStrategies; + +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.function.BiConsumer; +import java.util.function.Consumer; + +/** + * 对象映射转换工具类,转换逻辑属性名完全匹配进行转换 + * + * @Description: + * @Time: 2019-11-28 20:18 + * @Author: + */ +public final class ModelMapperUtil { + + public static final ModelMapper MODEL_MAPPER; + + static { + + MODEL_MAPPER = new ModelMapper(); + // 完全类型匹配 + //MODEL_MAPPER.getConfiguration().setFullTypeMatchingRequired(true); + // 设置属性匹配规则,设置为最严格匹配,必须属性名相同 + MODEL_MAPPER.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); + } + + /** + * 禁止实列化该类 + * @throws InstantiationException 不能实列化 + */ + private ModelMapperUtil() throws InstantiationException { + throw new InstantiationException("Tool Class Cannot Be Created Instantiation !"); + } + + /** + * 将对象转换为指定class类型对象。 + * @param source 源对象 + * @param targetClass 转换目标类型 + * @return 转换后对象 + * @param 目标类型 + */ + public static Target map(Object source, Class targetClass) { + return source == null ? null : MODEL_MAPPER.map(source, targetClass); + } + + + /** + * 将源对象中的属性转换到目标对象中,源对象与目标对象属性名相同的则转换 + * @param source 源对象 + * @param target 目标对象 + */ + public static void map(Object source, Object target) { + if (source == null || target == null) { + return; + } else { + MODEL_MAPPER.map(source, target); + } + } + + /** + * 将对象转换为指定class类型对象,并对转换后对象进行处理 + * @param source 源对象 + * @param targetClass 转换目标类型 + * @param consumer 对转换后对象进行消费处理 + * @return 转换后对象 + * @param 目标类型 + */ + public static Target map(Object source, Class targetClass, Consumer consumer) { + Target target = source == null ? null : MODEL_MAPPER.map(source, targetClass); + if (consumer != null) { + consumer.accept(target); + } + return target; + } + + + + /** + * 将对象转换为指定class类型对象,并对转换后对象进行处理 + * @param source 源对象 + * @param targetClass 转换目标类型 + * @param consumer 对转换后对象进行消费处理 + * @return 转换后对象 + * @param 源对象类型 + * @param 目标类型 + */ + public static Target map(Source source, Class targetClass, BiConsumer consumer) { + Target target = source == null ? null : MODEL_MAPPER.map(source, targetClass); + if (consumer != null) { + consumer.accept(source, target); + } + return target; + } + + /** + * 将集合中的元素抓换为指定类型 + * @param sourceList 源集合 + * @param targetClass 转换目标类型 + * @return 转换后的目标类型集合 + * @param 源类型 + * @param 目标类型 + */ + public static List mapList(Collection sourceList, Class targetClass) { + + if (sourceList == null) { + return new ArrayList(); + } + + ArrayList targets = new ArrayList<>(sourceList.size()); + + sourceList.forEach(p -> { + Target item = map(p, targetClass); + }); + + return targets; + } + + /** + * 将集合中的元素抓换为指定类型,并对转换后的元素处理 + * @param sourceList 源集合 + * @param targetClass 转换目标类型 + * @param consumer 对转换后元素处理 + * @return 转换后的集合 + * @param 源类型 + * @param 目标类型 + */ + public static List mapList(Collection sourceList, Class targetClass, Consumer consumer) { + + if (sourceList == null) { + return new ArrayList(); + } + + ArrayList targets = new ArrayList<>(sourceList.size()); + + sourceList.forEach(p -> { + Target item = map(p, targetClass); + + if (consumer != null) { + consumer.accept(item); + } + targets.add(item); + }); + + return targets; + } + + /** + * 将集合中的元素抓换为指定类型,并对转换后的元素处理 + * @param sourceList 源集合 + * @param targetClass 转换目标类型 + * @param consumer 对转换后元素处理 + * @return 转换后的集合 + * @param 源类型 + * @param 目标类型 + */ + public static List mapList(Collection sourceList, Class targetClass, BiConsumer consumer) { + + if (sourceList == null) { + return new ArrayList(); + } + + ArrayList targets = new ArrayList<>(sourceList.size()); + + sourceList.forEach(p -> { + Target map = ModelMapperUtil.map(p, targetClass); + if (consumer != null) { + consumer.accept(p, map); + } + targets.add(map); + }); + return targets; + } + + + public static T deepCopy(T obj) { + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + return (T) ois.readObject(); + } catch (Exception e) { + throw new RuntimeException("Deep copy failed", e); + } + } + +} + + diff --git a/src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java new file mode 100644 index 0000000..74d9999 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/OkHttpUtil.java @@ -0,0 +1,181 @@ +package com.bestsch.classicalchinese.utils; + +import okhttp3.*; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Component +public class OkHttpUtil { + + private static OkHttpClient DEFAULT_CLIENT = new OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .build(); + + private OkHttpClient client; + + public OkHttpUtil() { + this.client = DEFAULT_CLIENT; + } + + public OkHttpUtil(OkHttpClient client) { + this.client = client; + } + + public String get(String url) throws IOException { + Request request = new Request.Builder() + .url(url) + .build(); + + try (Response response = client.newCall(request).execute()) { + return response.body().string(); + } + } + +// public String post(String url, String json) throws IOException { +// MediaType JSON = MediaType.get("application/json; charset=utf-8"); +// RequestBody body = RequestBody.create(json, JSON); +// Request request = new Request.Builder() +// .url(url) +// .post(body) +// .build(); +// +// try (Response response = client.newCall(request).execute()) { +// return response.body().string(); +// } +// } + + public String post(String aUrl, Map param, + Map formData, Map header)throws IOException + { + return post(aUrl,param,formData,header,null); + } + + + public String post(String aUrl, Map param, + Map formData, Map header, + MediaType type) throws IOException { + + // 构建URL(添加查询参数) + HttpUrl.Builder urlBuilder = HttpUrl.parse(aUrl).newBuilder(); + if (param != null) { + for (Map.Entry entry : param.entrySet()) { + urlBuilder.addQueryParameter(entry.getKey(), String.valueOf(entry.getValue())); + } + } + String finalUrl = urlBuilder.build().toString(); + + + // 构建请求体 + RequestBody requestBody = null; + if (formData != null && !formData.isEmpty()) { + if (type == null) { + type = MediaType.parse("application/x-www-form-urlencoded"); + } + if ("application/x-www-form-urlencoded".equals(type.toString())) { + FormBody.Builder formBuilder = new FormBody.Builder(); + for (Map.Entry entry : formData.entrySet()) { + formBuilder.add(entry.getKey(), String.valueOf(entry.getValue())); + } + requestBody = formBuilder.build(); + } else if ("multipart/form-data".equals(type.toString())) { + MultipartBody.Builder bodyBuilder =new MultipartBody.Builder().setType(type); + for (Map.Entry entry : formData.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof File) { + // 处理文件类型参数 + File file = (File) value; + MediaType mediaType = MediaType.parse(getMimeType(file.getName())); + RequestBody fileBody = RequestBody.create(mediaType, file); + bodyBuilder.addFormDataPart(key, file.getName(), fileBody); + } else if (value instanceof byte[]) { + // 处理字节数组(文件流) + byte[] bytes = (byte[]) value; + MediaType mediaType = MediaType.parse("application/octet-stream"); + bodyBuilder.addFormDataPart(key, "file", + RequestBody.create(mediaType, bytes)); + } else { + // 处理普通字符串参数 + bodyBuilder.addFormDataPart(key, value.toString()); + } + } + requestBody = bodyBuilder.build(); + }else { + // 对于JSON或其他格式 + StringBuilder content = new StringBuilder(); + if ("application/json".equals(type.toString())) { + content.append("{"); + int i = 0; + for (Map.Entry entry : formData.entrySet()) { + if (i > 0) content.append(","); + content.append("\"").append(entry.getKey()).append("\":"); + if (entry.getValue() instanceof String) { + content.append("\"").append(entry.getValue()).append("\""); + } else { + content.append(entry.getValue()); + } + i++; + } + content.append("}"); + + } else + { + // 其他格式简单处理为键值对 + for (Map.Entry entry : formData.entrySet()) { + if (content.length() > 0) content.append("&"); + content.append(entry.getKey()).append("=").append(entry.getValue()); + } + } + requestBody = RequestBody.create(type, content.toString()); + } + } + + + + // 构建请求 + Request.Builder requestBuilder = new Request.Builder() + .url(finalUrl) + .post(requestBody != null ? requestBody : RequestBody.create(null, new byte[0])); + + // 添加请求头 + if (header != null) { + for (Map.Entry entry : header.entrySet()) { + requestBuilder.addHeader(entry.getKey(), entry.getValue()); + } + } + + // 执行请求 + Request request = requestBuilder.build(); + try (Response response = client.newCall(request).execute()) { + ResponseBody responseBody = response.body(); + if (responseBody != null) { + return responseBody.string(); + } else { + return null; // 或者根据实际情况返回 null 或空字符串 + } + } + } + private String getMimeType(String fileName) { + if (fileName.endsWith(".png")) { + return "image/png"; + } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) { + return "image/jpeg"; + } else if (fileName.endsWith(".pdf")) { + return "application/pdf"; + } else if (fileName.endsWith(".txt")) { + return "text/plain"; + } + // 默认类型 + return "application/octet-stream"; + } + + + +} \ No newline at end of file diff --git a/src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java new file mode 100644 index 0000000..829a67d --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/OrgJsonUtil.java @@ -0,0 +1,21 @@ +package com.bestsch.classicalchinese.utils; + +import org.json.JSONArray; +import org.springframework.stereotype.Service; + +@Service +public class OrgJsonUtil { + + public static String[][] getJsonStrig(String answer){ + JSONArray jsonArray = new JSONArray(answer); + String[][] result = new String[jsonArray.length()][]; + for (int i = 0; i < jsonArray.length(); i++) { + JSONArray innerArray = jsonArray.getJSONArray(i); + result[i] = new String[innerArray.length()]; + for (int j = 0; j < innerArray.length(); j++) { + result[i][j] = innerArray.getString(j); + } + } + return result; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java new file mode 100644 index 0000000..d2a7abb --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/OtherUtil.java @@ -0,0 +1,277 @@ +package com.bestsch.classicalchinese.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.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.commonmark.node.Node; +import org.commonmark.parser.Parser; +import org.commonmark.renderer.html.HtmlRenderer; +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 javax.websocket.DecodeException; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.*; +import java.util.stream.Collectors; + +/* +* 杂项公用方法集合 +* */ +public class OtherUtil { + + /** + * @Description: 判断字符串能否序列化 + * @Author: chenx + * @Date: 2023/4/20 + */ + public final static boolean isJSONValid(String str) { + try { + JSONObject.parse(str); + } catch (JSONException ex) { + return false; + } + return true; + } + + /** + * @Description: 判断字符串能否序列化为json数组 + * @Author: chenx + * @Date: 2023/4/20 + */ + public final static boolean isJsonArray(String str) { + if (!isJSONValid(str)) return false; + try { + Object object = JSON.parse(str); + return object instanceof JSONArray; + } catch (JSONException ex) { + return false; + } + } + + /** + * @Description: 数组深拷贝 + * @Author: chenx + * @Date: 2023/4/20 + */ + public final static List deepCopy(List src, Class clazz) { + String jsonStr=JSON.toJSONString(src); + if (!isJsonArray(jsonStr)) return src; + return JSONArray.parseArray(jsonStr,clazz); + } + + + + /** + * double类型的加法运算(不需要舍入) + * @param m1 + * @param m2 + * @return 不加doubleValue()则, 返回BigDecimal对象 + */ + public static double additionDouble(double m1, double m2) { + BigDecimal p1 = new BigDecimal(Double.toString(m1)); + BigDecimal p2 = new BigDecimal(Double.toString(m2)); + return p1.add(p2).doubleValue(); + } + + /** + * double类型的除法运算(直接删除多余位数) + * @param m1 + * @param m2 + * @return 不加doubleValue()则, 返回BigDecimal对象 + */ + public static double divideDouble(double m1, double m2) { + if (m1 == 0 || m2 == 0) return 0; + BigDecimal p1 = new BigDecimal(Double.toString(m1)); + BigDecimal p2 = new BigDecimal(Double.toString(m2)); + BigDecimal p3 = p1.divide(p2,4, BigDecimal.ROUND_DOWN ); + return p3.doubleValue(); + } + + /** + * double类型转化为字符串,统一位数 + * @param num + * @return 保留2位小数-直接舍弃2位之后的数据 + */ + public static String formatDouble(double num) { + DecimalFormat df = new DecimalFormat("0.##"); + df.setRoundingMode(RoundingMode.DOWN); + return df.format(num); + } + + /** + * 字符串值 类型转化为double,统一位数 + * @param numStr + * @return 保Str留2位小数-直接舍弃2位之后的数据 + */ + public static Double formatDouble(String numStr) { + try { + double num = Double.parseDouble(numStr); + DecimalFormat df = new DecimalFormat("0.##"); + df.setRoundingMode(RoundingMode.DOWN); + numStr = df.format(num); + return Double.parseDouble(numStr); + + } catch (NumberFormatException e) { + return null; + } + } + + public static void setBaseEntityValue(UserSysRole curRole, T entity, Integer id) + { + if(id==null||id==0) + entity.setCDate(new Date()); + else + entity.setId(id); + + entity.setSchId(curRole.getSchId()); + entity.setCUserId(curRole.getUserId()); + } + + public static Map convertJsonToMap(String json) { + ObjectMapper objectMapper = new ObjectMapper(); + try { + return objectMapper.readValue(json, Map.class); + } catch (Exception e) { + System.out.println("convertJsonToMap json to Map 失败!json="+json); + e.printStackTrace(); + return null; + } + } + + public static List> convertJsonToMapList(String json) { + ObjectMapper objectMapper = new ObjectMapper(); + List> list=new ArrayList<>(); + + try { + list = objectMapper.readValue(json, new TypeReference>>() {}); + } catch (Exception e) { + try{ + list = objectMapper.readValue("["+json+"]", new TypeReference>>() {}); + }catch (Exception e2) { + } + 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); + + for (JsonNode node : rootNode) { + result.add(jsonNodeToMap(node)); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } + + private static Map jsonNodeToMap(JsonNode node) { + Map retMap = new HashMap<>(); + node.fields().forEachRemaining(entry -> { + if (entry.getValue().isObject()) { + retMap.put(entry.getKey(), jsonNodeToMap(entry.getValue())); + } else if (entry.getValue().isArray()) { + List list = new ArrayList<>(); + for (JsonNode element : entry.getValue()) { + list.add(jsonNodeToMap(element)); + } + retMap.put(entry.getKey(), list); + } else { + retMap.put(entry.getKey(), entry.getValue().asText()); + } + }); + return retMap; + } + + public static String convertMarkdownToHtml(String markdown) { + Parser parser = Parser.builder().build(); + Node document = parser.parse(markdown); + HtmlRenderer renderer = HtmlRenderer.builder().build(); + return renderer.render(document); + } + + public static Target mapToClass(Map map, Class targetClass) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(map,targetClass); + } + + public static List mapToList(List> sourceList, Class targetClass) { + + if (sourceList == null) { + return new ArrayList(); + } + + ArrayList targets = new ArrayList<>(sourceList.size()); + sourceList.forEach(p -> { + Target item = mapToClass(p, targetClass); + targets.add(item); + }); + + return targets; + } + + 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()); + } + + public static HttpServletRequest getRequest() { + ServletRequestAttributes attributes = (ServletRequestAttributes) + RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + throw new IllegalStateException("当前线程中不存在Request上下文"); + } + return attributes.getRequest(); + } + +// public static String getHeader(String headerName) { +// HttpServletRequest request = getRequest(); +// return request.getHeader(headerName); +// } + + public static String getHeader(String headerName) { + String value = getHeader(headerName); + if(StringUtils.hasText(value)) + return value; + else + 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 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"); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java new file mode 100644 index 0000000..a2145dd --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/PageUtil.java @@ -0,0 +1,49 @@ +package com.bestsch.classicalchinese.utils; + +import com.bestsch.classicalchinese.model.PageInfo; +import org.springframework.data.domain.Pageable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @Author wanghu + * @Date 2025-11-10 14:47 (可以根据需要修改) + * @Description: + */ +public class PageUtil { + + public static List paginate(List list,Pageable pageable) { + if (list == null || list.isEmpty()) { + return new ArrayList<>(); + } + + int total = list.size(); + int fromIndex = pageable.getPageNumber() * pageable.getPageSize(); + + // 检查页码是否有效 + if (fromIndex >= total) { + return new ArrayList<>(); + } + + int toIndex = Math.min(fromIndex + pageable.getPageSize(), total); + return list.subList(fromIndex, toIndex); + } + + /** + * 获取分页信息 + * @param list 原始数据列表 + * @param pageNum 页码 + * @param pageSize 每页大小 + * @return 分页信息对象 + */ + public static PageInfo getPageInfo(List list,int pageNum, int pageSize) { + int total = list.size(); + int totalPages = (int) Math.ceil((double) total / pageSize); + boolean hasNext = pageNum < totalPages; + boolean hasPrev = pageNum > 0; + return new PageInfo(pageNum, pageSize, total, totalPages, hasNext, hasPrev); + } +} + diff --git a/src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java b/src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java new file mode 100644 index 0000000..71b4c4c --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/RedisConstants.java @@ -0,0 +1,38 @@ +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/RedisUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/RedisUtil.java new file mode 100644 index 0000000..7f3368b --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/RedisUtil.java @@ -0,0 +1,868 @@ +package com.bestsch.classicalchinese.utils; + + +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.concurrent.TimeUnit; + + +/** + * Redis工具类 + */ + +@Component +public final class RedisUtil { + + + @Autowired + private RedisTemplate redisTemplate; + + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + + public boolean expire(String key, long time) { + + try { + + if (time > 0) { + + redisTemplate.expire(key, time, TimeUnit.SECONDS); + + } + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + + public long getExpire(String key) { + + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + + } + + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + + public boolean hasKey(String key) { + + try { + + return redisTemplate.hasKey(key); + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + + @SuppressWarnings("unchecked") + + public void del(String... key) { + + if (key != null && key.length > 0) { + + if (key.length == 1) { + + redisTemplate.delete(key[0]); + + } else { + + redisTemplate.delete(CollectionUtils.arrayToList(key)); + + } + + } + + } + + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + + public Object get(String key) { + + return key == null ? null : redisTemplate.opsForValue().get(key); + + } + + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + + public boolean set(String key, Object value) { + + try { + + redisTemplate.opsForValue().set(key, value); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + + } + + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + + public boolean set(String key, Object value, long time) { + + try { + + if (time > 0) { + + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + + } else { + + set(key, value); + + } + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 递增 + * + * @param key 键 + * @param delta 要增加几(大于0) + * @return + */ + + public long incr(String key, long delta) { + + if (delta < 0) { + + throw new RuntimeException("递增因子必须大于"); + + } + + return redisTemplate.opsForValue().increment(key, delta); + + } + + + /** + * 递减 + * + * @param key 键 + * @param delta 要减少几(小于0) + * @return + */ + + public long decr(String key, long delta) { + + if (delta < 0) { + + throw new RuntimeException("递减因子必须大于"); + + } + + return redisTemplate.opsForValue().increment(key, -delta); + + } + + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + + public Object hget(String key, String item) { + + return redisTemplate.opsForHash().get(key, item); + + } + + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + + public Map hmget(String key) { + + return redisTemplate.opsForHash().entries(key); + + } + + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + + public boolean hmset(String key, Map map) { + + try { + + redisTemplate.opsForHash().putAll(key, map); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + + public boolean hmset(String key, Map map, long time) { + + try { + + redisTemplate.opsForHash().putAll(key, map); + + if (time > 0) { + + expire(key, time); + + } + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + + public boolean hset(String key, String item, Object value) { + + try { + + redisTemplate.opsForHash().put(key, item, value); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + + public boolean hset(String key, String item, Object value, long time) { + + try { + + redisTemplate.opsForHash().put(key, item, value); + + if (time > 0) { + + expire(key, time); + + } + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + + public void hdel(String key, Object... item) { + + redisTemplate.opsForHash().delete(key, item); + + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + + public boolean hHasKey(String key, String item) { + + return redisTemplate.opsForHash().hasKey(key, item); + + } + + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于) + * @return + */ + + public double hincr(String key, String item, double by) { + + return redisTemplate.opsForHash().increment(key, item, by); + + } + + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于) + * @return + */ + + public double hdecr(String key, String item, double by) { + + return redisTemplate.opsForHash().increment(key, item, -by); + + } + + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + + public Set sGet(String key) { + + try { + + return redisTemplate.opsForSet().members(key); + + } catch (Exception e) { + + e.printStackTrace(); + + return null; + + } + + } + + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + + public boolean sHasKey(String key, Object value) { + + try { + + return redisTemplate.opsForSet().isMember(key, value); + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + + public long sSet(String key, Object... values) { + + try { + + return redisTemplate.opsForSet().add(key, values); + + } catch (Exception e) { + + e.printStackTrace(); + + return 0; + + } + + } + + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + + public long sSetAndTime(String key, long time, Object... values) { + + try { + + Long count = redisTemplate.opsForSet().add(key, values); + + if (time > 0) + + expire(key, time); + + return count; + + } catch (Exception e) { + + e.printStackTrace(); + + return 0; + + } + + } + + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + + public long sGetSetSize(String key) { + + try { + + return redisTemplate.opsForSet().size(key); + + } catch (Exception e) { + + e.printStackTrace(); + + return 0; + + } + + } + + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + + public long setRemove(String key, Object... values) { + + try { + + Long count = redisTemplate.opsForSet().remove(key, values); + + return count; + + } catch (Exception e) { + + e.printStackTrace(); + + return 0; + + } + + } + + // ===============================list================================= + + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + + public List lGet(String key, long start, long end) { + + try { + + return redisTemplate.opsForList().range(key, start, end); + + } catch (Exception e) { + + e.printStackTrace(); + + return null; + + } + + } + + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + + public long lGetListSize(String key) { + + try { + + return redisTemplate.opsForList().size(key); + + } catch (Exception e) { + + e.printStackTrace(); + + return 0; + + } + + } + + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * * @return + */ + + public Object lGetIndex(String key, long index) { + + try { + + return redisTemplate.opsForList().index(key, index); + + } catch (Exception e) { + + e.printStackTrace(); + + return null; + + } + + } + + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + + public boolean lSet(String key, Object value) { + + try { + + redisTemplate.opsForList().rightPush(key, value); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + + public boolean lSet(String key, Object value, long time) { + + try { + + redisTemplate.opsForList().rightPush(key, value); + + if (time > 0) + + expire(key, time); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + + public boolean lSet(String key, List value) { + + try { + + redisTemplate.opsForList().rightPushAll(key, value); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + + public boolean lSet(String key, List value, long time) { + + try { + + redisTemplate.opsForList().rightPushAll(key, value); + + if (time > 0) + + expire(key, time); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + + public boolean lUpdateIndex(String key, long index, Object value) { + + try { + + redisTemplate.opsForList().set(key, index, value); + + return true; + + } catch (Exception e) { + + e.printStackTrace(); + + return false; + + } + + } + + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + + public long lRemove(String key, long count, Object value) { + + try { + + Long remove = redisTemplate.opsForList().remove(key, count, value); + + return remove; + + } catch (Exception e) { + + e.printStackTrace(); + + return 0; + + } + + } + +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/Signature.java b/src/main/java/com/bestsch/classicalchinese/utils/Signature.java new file mode 100644 index 0000000..c3a08fe --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/Signature.java @@ -0,0 +1,121 @@ +package com.bestsch.classicalchinese.utils; + +import com.bestsch.utils.DException; +import org.apache.commons.lang.StringUtils; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class Signature { + + public static String getSign(String data, String timeStamp, String secret) { + return getHmacSHA256(data + timeStamp, secret); + } + + public static int getTimestamp(Date time) + { + Calendar cal = Calendar.getInstance(); + Calendar newDate; + if (time != null) + { + cal.setTime(time); + newDate = cal; + } + else + newDate = cal; + + return newDate.get(Calendar.HOUR_OF_DAY) * 3600 + newDate.get(Calendar.MINUTE) * 60 + newDate.get(Calendar.SECOND); + } + + public static Map getHeaderMap(String data,String app_key,String app_secret) + { + int timeLong=getTimestamp(new Date()); + Map headerMap=new HashMap(); + headerMap.put("t",timeLong); + headerMap.put("sign",Signature.getSign(data,String.valueOf(timeLong),app_secret)); + headerMap.put("appkey",app_key); + return headerMap; + } + + + public static String getHmacSHA256(String data,String secret) + { + try + { // 创建密钥规范 + SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); + // 获取Mac实例并初始化 + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(secretKeySpec); + + byte[] hmacSHA256Bytes = mac.doFinal(data.getBytes(StandardCharsets.UTF_8)); + // 将哈希值转换为十六进制字符串表示 + StringBuilder hexString = new StringBuilder(2 * hmacSHA256Bytes.length); + for (byte b : hmacSHA256Bytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + // 输出结果 + return hexString.toString(); + } + catch(Exception ex) + { + return ""; + } + } + + public static String getRequestBody(HttpServletRequest request,HttpServletResponse response){ + try { + StringBuilder buffer = new StringBuilder(); + String line; + try (BufferedReader reader = request.getReader()) { + while ((line = reader.readLine()) != null) { + buffer.append(line); + } + } + String requestBody = buffer.toString(); + return requestBody; + } catch (IOException ex) { + throw new DException("body is null"); + } + } + + public static void verifySign(HttpServletRequest request,String data,String app_key,String app_secret) + { + String appkey = request.getHeader("appkey"); + if(StringUtils.isEmpty(appkey)) throw new DException("appkey is null"); + if(!app_key.equals(appkey))throw new DException("appkey value error"); + + String sign = request.getHeader("sign"); + if(StringUtils.isEmpty(sign)) throw new DException("sign is null"); + String t = request.getHeader("t"); + if(StringUtils.isEmpty(t)) throw new DException("t is null"); + long currentTimeMillis = System.currentTimeMillis(); + long pastTimeMillis = Long.parseLong(t); + long timeDifference = currentTimeMillis - pastTimeMillis ; + long timeDifferenceInSeconds = timeDifference / 1000; + if(timeDifferenceInSeconds>300) throw new DException("request expire"); + String sign2= getSign(data,t,app_secret); + + if(!sign.equals(sign2)){ + //签名验不过,表示这个API返回的数据有可能已经被篡改了 + throw new DException("sign verify fail"); + } + } + + + +} + + diff --git a/src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java b/src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java new file mode 100644 index 0000000..017de05 --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/TimeUtils.java @@ -0,0 +1,242 @@ +package com.bestsch.classicalchinese.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.*; + +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; + } + + + + /** + * 日期转星期 + */ + public static String dateToWeek(String datetime) { + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd"); + String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; + Calendar cal = Calendar.getInstance(); // 获得一个日历 + Date date = null; + try { + date = f.parse(datetime); + cal.setTime(date); + } catch (Exception e) { + } + int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。 + if (w < 0) + w = 0; + return weekDays[w]; + } + + public static String getTodayDate() { + String date = sdf.format(new Date()); + return date; + } + + + + 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("-"); + if (split.length > 1) + { + return timestamp; + } + 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; + } + /** + * 获取这个月的第一天 + */ + public static String getFirstDayOfCurrentMonth() { + Calendar cal = Calendar.getInstance(); + // 获取某月最大天数 + int lastDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH); + // 设置日历中月份的最大天数 + cal.set(Calendar.DAY_OF_MONTH, lastDay); + // 格式化日期 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String firstDayOfMonth = sdf.format(cal.getTime()); + return firstDayOfMonth; + } + + /** + * 获取这个月的最后一天 + */ + public static String getLastDayOfCurrentMonth() { + Calendar cal = Calendar.getInstance(); + // 获取某月最大天数 + int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH); + // 设置日历中月份的最大天数 + cal.set(Calendar.DAY_OF_MONTH, lastDay); + // 格式化日期 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String lastDayOfMonth = sdf.format(cal.getTime()); + return lastDayOfMonth; + } + + /** + * 每周的第一天 + */ + public static String getFirstOfWeek(){ + Calendar cal = Calendar.getInstance(); + Date current = new Date(); + cal.setTime(current); + int d = 0; + if (cal.get(Calendar.DAY_OF_WEEK) == 1) { + d = 0; + } else { + d = 1 - cal.get(Calendar.DAY_OF_WEEK); + } + cal.add(Calendar.DAY_OF_WEEK, d+1); + // 所在周开始日期 + String data1 = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime()); + return data1; + + } + + /** + * 每周的最后一天 + */ + public static String getLastOfWeek(){ + Calendar cal = Calendar.getInstance(); + Date current = new Date(); + cal.setTime(current); + int d = 0; + if (cal.get(Calendar.DAY_OF_WEEK) == 1) { + d = 6; + } else { + d = 7 - cal.get(Calendar.DAY_OF_WEEK); + } + cal.add(Calendar.DAY_OF_WEEK, d+1); + // 所在周结束日期 + String data2 = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime()); + return data2; + + } + + + // 获取两个时间之间的月份 + public static List getMonthBetweenDate(Date startDate,Date endDate){ + ArrayList result = new ArrayList(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");//格式化,调整为自己需要的格式 + Calendar min = Calendar.getInstance(); + Calendar max = Calendar.getInstance(); +// 给calendar设置开始时间 + min.setTime(startDate); +// set方法设置年月日 年为开始时间的年份 后面同理 + min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1); +// 给calendar设置结束时间 + max.setTime(endDate); +// set方法设置年月日 年为结束时间的年份 后面同理,最后面的1和2不要改 + max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2); +// 创建一个临时的变量,代表当前的时间 + Calendar curr = min; +// 如果当前的时间在结束时间之前,循环知道超过结束时间就结束,返回结果集合 + while (curr.before(max)) { +// 将这个当前的时间格式化之后保存到result集合 + result.add(sdf.format(curr.getTime())); +// 将当前的时间加上1个月 + curr.add(Calendar.MONTH, 1); + } + return result; + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java b/src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java new file mode 100644 index 0000000..3a8d1de --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/UUIDUtils.java @@ -0,0 +1,16 @@ +package com.bestsch.classicalchinese.utils; + +import java.util.UUID; + +/** + * @ Description : java类作用描述 + * @ Author : cls + * @ CreateDate : 2020/2/15 17:15 + * @ Company : bestsch + */ +public class UUIDUtils { + + public static String getUUID(){ + return UUID.randomUUID().toString().replace("-",""); + } +} diff --git a/src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java b/src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java new file mode 100644 index 0000000..a5dfe2a --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/ValidationUtil.java @@ -0,0 +1,23 @@ +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 new file mode 100644 index 0000000..8e993aa --- /dev/null +++ b/src/main/java/com/bestsch/classicalchinese/utils/VideoTransCodeUtil.java @@ -0,0 +1,313 @@ +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.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..6992ed5 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,109 @@ +server: + port: 8086 + +spring: + mvc: + date-format: yyyy-MM-dd HH:mm:ss + servlet: + multipart: + max-file-size: 50MB # 单个文件大小 + max-request-size: 50MB + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + redis: + host: 127.0.0.1 + port: 6379 + database: 0 + password: 123 + rabbitmq: + host: 127.0.0.1 + port: 5672 + username: guest + password: guest + +# publisher-confirms: true + publisher-returns: true + template: + mandatory: true + data: + redis: + repositories: + enabled: false +# http: +# encoding: +# force: true +# charset: utf-8 +# enabled: true + + datasource: + url: jdbc:mysql://localhost:3306/classicalchinese?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai + username: root + password: 123 + driver-class-name: com.mysql.jdbc.Driver + min-idle: 30 + max-active: 30 + hikari: + minimum-idle: 20 #最小连接数 + maximum-pool-size: 500 #池中最大连接数 + connection-timeout: 600000 #连接超时时间 + idle-timeout: 120000 # 空闲等待时间 ms + leakDetectionThreshold: 300000 #用来设置连接被占用的超时时间,单位为毫秒,默认为0,表示禁用连接泄露检测。 + auto-commit: true # + max-lifetime: 1800000 # 30000--30分钟 + validation-timeout: 3000 + connection-test-query: SELECT 1 FROM DUAL + connection-init-sql: SET NAMES utf8mb4 + #jpa + jpa: + database: MySQL + show-sql: true + hibernate: + # 生产环境设置成 none,避免程序运行时自动更新数据库结构 + ddl-auto: update + database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + open-in-view: true + + +bsch: + sso: + # service-url-prefix: http://sso.bestsch.com + server-url-prefix: http://sso.bestsch.com + client-host-url: http://localhost:8086 + allow-headers: all + allow-origins: all + url-pattern: /api/* + ignore-pattern: /mobiapi/*|mobiapi2/*|/qywxapi/* + mobi-api-pattern: /mobiapi/* + 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 + +FILE_PATH: D://工作区/JAVA/bsch/ + +FILE_WEB_PATH: http://localhost:8086/upload/ + + +