已重命名40个文件
已修改129个文件
已添加36个文件
| | |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-maven-plugin</artifactId> |
| | | <version>2.5.15</version> |
| | | <configuration> |
| | | <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> |
| | | </configuration> |
| | | <executions> |
| | | <execution> |
| | | <goals> |
| | | <goal>repackage</goal> |
| | | </goals> |
| | | </execution> |
| | | </executions> |
| | | </plugin> |
| | | <plugin> |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-war-plugin</artifactId> |
| | | <version>3.1.0</version> |
| | | <configuration> |
| | | <failOnMissingWebXml>false</failOnMissingWebXml> |
| | | <warName>${project.artifactId}</warName> |
| | | </configuration> |
| | | </plugin> |
| | | </plugins> |
| | | <finalName>${project.artifactId}</finalName> |
| | | </build> |
| | | |
| | | |
| | | </project> |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppCarouselController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | @Autowired |
| | | private SysCarouselService carouselService; |
| | | |
| | | // @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "轮播列表(分页)") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"), |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppCourseController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | |
| | | @Autowired |
| | | private ExCourseService courseService; |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "根据id获取课程信息") |
| | | @GetMapping(value = { "/{courseId}" }) |
| | | public CommonResult getCompanyInfo(@PathVariable(value = "courseId", required = true) Long courseId) |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppExerciseAnswerController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | * @author kzy |
| | | * @since 2024-06-20 09:42:25 |
| | | */ |
| | | @Api(tags = "学员刷题前端控制器") |
| | | @Api(tags = "APP学员刷题前端控制器") |
| | | @RestController |
| | | @RequestMapping("/app/exercise-answer") |
| | | public class AppExerciseAnswerController { |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppLoginController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | @ApiOperation(value = "用户退出") |
| | | @PostMapping("/logout") |
| | | public CommonResult logout(){ |
| | | |
| | | sysLoginService.logout(); |
| | | return CommonResult.success(); |
| | | } |
| | | |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppPaperStudentController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "结束考试") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "body", name = "paperId", dataType = "long", required = true, value = "试卷id"), |
| | | @ApiImplicitParam(paramType = "body", name = "studentId", dataType = "long", required = true, value = "学员id") |
| | | @ApiImplicitParam(paramType = "body", name = "id", dataType = "long", required = true, value = "学员与试卷关系id") |
| | | }) |
| | | @PostMapping(value = { "/endExam" }) |
| | | public CommonResult endExam(ExPaperStudent paperStudent) |
| | | public CommonResult endExam(@RequestBody ExPaperStudent paperStudent) |
| | | { |
| | | paperStudentService.endExam(paperStudent); |
| | | return CommonResult.success(); |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppPhaseStudentController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppQuestionBankController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppQuestionController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | private ExQuestionService questionService; |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "刷题获取题目ID列表") |
| | | @ApiOperation(value = "刷题根据题库id获取题目ID列表") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "long", required = false, value = "题库id"), |
| | | @ApiImplicitParam(paramType = "query", name = "exercistType", dataType = "int", required = false, value = "练习方式:1随机,2顺序") |
| | | @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "long", required = false, value = "题库id") |
| | | }) |
| | | @GetMapping(value = { "/getExerciseQuestionList" }) |
| | | public CommonResult getExerciseQuestionList(@RequestParam(required = true) Long bankId, @RequestParam(required = true)Integer exerciseType) |
| | | public CommonResult getExerciseQuestionList(@RequestParam(required = true) Long bankId) |
| | | { |
| | | return CommonResult.success(questionService.getExerciseQuestionList(bankId,exerciseType)); |
| | | return CommonResult.success(questionService.getExerciseQuestionList(bankId)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | |
| | | |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "刷题获取错题题目ID列表") |
| | | @ApiOperation(value = "刷题根据题库id获取错题题目ID列表") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "long", required = false, value = "题库id") |
| | | }) |
| | |
| | | |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "考试获取题目ID列表(考试完成返回错对,未完成则不返回)") |
| | | @ApiOperation(value = "考试获取题目ID列表(考试完成返回错对,未完成则返回是否答题状态)") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "long", required = false, value = "考卷id"), |
| | | @ApiImplicitParam(paramType = "query", name = "viewType", dataType = "int", required = false, value = "查看方式:1考试,2查看") |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppResourceController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppStudentAnswerController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
对比新文件 |
| | |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | | import com.gkhy.exam.system.domain.ExStudent; |
| | | import com.gkhy.exam.system.service.ExStudentService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | /** |
| | | * <p> |
| | | * 学员前端控制器 |
| | | * </p> |
| | | * |
| | | * @author kzy |
| | | * @since 2024-06-06 13:53:17 |
| | | */ |
| | | @Api(tags = "APP学员前端控制器") |
| | | @RestController |
| | | @RequestMapping("/app/student") |
| | | public class AppStudentController { |
| | | @Autowired |
| | | private ExStudentService studentService; |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "根据id获取学员信息") |
| | | @GetMapping(value = { "/{studentId}" }) |
| | | public CommonResult getStudentInfo(@PathVariable(value = "studentId", required = true) Long studentId) |
| | | { |
| | | return CommonResult.success(studentService.selectStudentById(studentId)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "重置密码") |
| | | @PutMapping(value = "/resetPwd") |
| | | public CommonResult restPwd(@RequestBody ExStudent student){ |
| | | studentService.resetUserPwd(student); |
| | | return CommonResult.success(); |
| | | } |
| | | } |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/app/AppStudentStudyController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.app; |
| | | package com.gkhy.exam.admin.controller.app; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | | import com.gkhy.exam.system.domain.ExStudentStudy; |
| | | import com.gkhy.exam.system.service.ExStudentStudyService; |
| | |
| | | @Autowired |
| | | private ExStudentStudyService studentStudyService; |
| | | |
| | | @RepeatSubmit |
| | | @PreAuthorize("hasAnyAuthority('train:exam:student')") |
| | | @ApiOperation(value = "新增学习记录") |
| | | @PostMapping |
| | |
| | | }) |
| | | @PostMapping("/progress") |
| | | public CommonResult progress(@RequestBody ExStudentStudy studentStudy){ |
| | | System.out.println("progress info:"+studentStudy.getId()+","+studentStudy.getPhaseId()+","+studentStudy.getPeriodId()+","+studentStudy.getStudentId()); |
| | | studentStudyService.progress(studentStudy); |
| | | return CommonResult.success(); |
| | | } |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/monitor/SysLogininforController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.monitor; |
| | | package com.gkhy.exam.admin.controller.monitor; |
| | | |
| | | /** |
| | | * 系统访问记录 |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/monitor/SysOperLogController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.monitor; |
| | | package com.gkhy.exam.admin.controller.monitor; |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | | import com.gkhy.exam.common.api.CommonResult; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/CaptchaController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import cn.hutool.core.codec.Base64; |
| | | import cn.hutool.core.lang.UUID; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysCarouselController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | return CommonResult.success(carouselService.selectCarouselById(carouselId)); |
| | | } |
| | | |
| | | |
| | | @RepeatSubmit |
| | | @PreAuthorize("hasAnyAuthority('train:exam:system')") |
| | | @Log(title = "轮播图管理", businessType = BusinessType.INSERT) |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysCategoryController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysCommonController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | @GetMapping("/importExcel") |
| | | public CommonResult importExcel() throws Exception { |
| | | commonService.importStudent(); |
| | | return CommonResult.success(); |
| | | } |
| | | } |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysCompanyController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysConfigController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | //@Api(tags = "系统配置前端控制器") |
| | | //@RestController |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysDictDataController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysDictTypeController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysLoginController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | @ApiOperation(value = "用户退出") |
| | | @PostMapping("/logout") |
| | | public CommonResult logout(){ |
| | | |
| | | sysLoginService.logout(); |
| | | return CommonResult.success(); |
| | | } |
| | | |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysNoticeController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysProfileController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import cn.hutool.core.codec.Base64; |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/system/SysUserController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.system; |
| | | package com.gkhy.exam.admin.controller.system; |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | | import com.gkhy.exam.common.annotation.RepeatSubmit; |
| | |
| | | |
| | | // @PreAuthorize("hasAuthority('train:exam:company')") |
| | | // @PreAuthorize("hasAnyAuthority('train:exam:system','train:exam:company')") |
| | | @PreAuthorize("hasAnyAuthority('train:exam:system','train:exam:company','train:exam:depart','train:exam:workshop','train:exam:other')") |
| | | @PreAuthorize("hasAnyAuthority('train:exam:system','train:exam:company','train:exam:depart','train:exam:workshop','train:exam:other')") |
| | | @ApiOperation(value = "用户列表(分页)") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"), |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExCompanyPeriodController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExCourseChapterController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExCourseChapterPeriodController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExCourseController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExCoursePhaseController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | } |
| | | |
| | | @RepeatSubmit |
| | | @Log(title = "批次管理", businessType = BusinessType.UPDATE) |
| | | @Log(title = "批次管理", businessType = BusinessType.DELETE) |
| | | @ApiOperation(value = "删除批次") |
| | | @DeleteMapping(value = { "/{phaseId}" }) |
| | | public CommonResult delete(@PathVariable(value = "phaseId", required = true) Long phaseId){ |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExExamPaperController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | |
| | | } |
| | | |
| | | @RepeatSubmit |
| | | @PreAuthorize("hasAnyAuthority('train:exam:company','train:exam:depart','train:exam:workshop','train:exam:other')") |
| | | @Log(title = "试卷管理", businessType = BusinessType.INSERT) |
| | | @ApiOperation(value = "新增试卷") |
| | | @PostMapping |
| | |
| | | } |
| | | |
| | | @RepeatSubmit |
| | | @PreAuthorize("hasAnyAuthority('train:exam:company','train:exam:depart','train:exam:workshop','train:exam:other')") |
| | | @Log(title = "试卷管理", businessType = BusinessType.UPDATE) |
| | | @ApiOperation(value = "编辑试卷") |
| | | @PutMapping |
| | |
| | | } |
| | | |
| | | @RepeatSubmit |
| | | @Log(title = "试卷管理", businessType = BusinessType.UPDATE) |
| | | @PreAuthorize("hasAnyAuthority('train:exam:company','train:exam:depart','train:exam:workshop','train:exam:other')") |
| | | @Log(title = "试卷管理", businessType = BusinessType.DELETE) |
| | | @ApiOperation(value = "删除试卷") |
| | | @DeleteMapping(value = { "/{paperId}" }) |
| | | public CommonResult delete(@PathVariable(value = "paperId", required = true) Long paperId){ |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExExamRecordController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExPaperStudentController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | | import com.gkhy.exam.common.enums.BusinessType; |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.domain.vo.BatchPaperStudentVO; |
| | | import com.gkhy.exam.system.domain.vo.ExPaperStudentVO; |
| | | import com.gkhy.exam.system.service.ExPaperStudentService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | return CommonResult.success(paperStudentService.selectPaperStudentList(paperStudent)); |
| | | } |
| | | |
| | | @ApiOperation(value = "根据id查询学员试卷信息") |
| | | @GetMapping(value = { "/getPaperStudentById" }) |
| | | public CommonResult getPaperStudentById(@RequestParam(value = "paperStudentId", required = true) Long paperStudentId) |
| | | { |
| | | return CommonResult.success(paperStudentService.selectPaperStudentById(paperStudentId)); |
| | | } |
| | | |
| | | @RepeatSubmit |
| | | @Log(title = "试卷与学员关系管理", businessType = BusinessType.INSERT) |
| | | @ApiOperation(value = "新增学员") |
| | |
| | | |
| | | @RepeatSubmit |
| | | @Log(title = "试卷与学员关系管理", businessType = BusinessType.INSERT) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "body", name = "phaseIds", dataType = "array", required = false, value = "批次id列表"), |
| | | @ApiImplicitParam(paramType = "query", name = "studentIds", dataType = "array", required = false, value = "学员id列表(批次id和学员id列表只能传一个)"), |
| | | @ApiImplicitParam(paramType = "query", name = "paperId", dataType = "long", required = true, value = "考卷id") |
| | | }) |
| | | @ApiOperation(value = "批量新增学员") |
| | | @PostMapping("/batchAdd") |
| | | public CommonResult batchAdd(@RequestBody Map<String,Object> paperStudentMap){ |
| | | return CommonResult.success(paperStudentService.batchAddPaperStudent(paperStudentMap)); |
| | | public CommonResult batchAdd(@Validated @RequestBody BatchPaperStudentVO batchPaperStudent){ |
| | | return CommonResult.success(paperStudentService.batchAddPaperStudent(batchPaperStudent)); |
| | | } |
| | | |
| | | @RepeatSubmit |
| | |
| | | @Log(title = "试卷与学员关系管理", businessType = BusinessType.DELETE) |
| | | @ApiOperation(value = "批量删除学员") |
| | | @DeleteMapping(value = { "/batchDelete" }) |
| | | public CommonResult batchDelete( List<Long> paperStudentIds){ |
| | | public CommonResult batchDelete(@RequestBody List<Long> paperStudentIds){ |
| | | paperStudentService.batchDeletePaperStudent(paperStudentIds); |
| | | return CommonResult.success(); |
| | | } |
| | |
| | | paperStudentService.checkStudentUnique(Collections.singletonList(paperStudent)); |
| | | return CommonResult.success(); |
| | | } |
| | | |
| | | |
| | | @ApiOperation(value = "提交批改试卷") |
| | | @PostMapping("/doReview") |
| | | public CommonResult doReview(@RequestBody ExPaperStudentVO paperStudentVO) |
| | | { |
| | | paperStudentService.doReview(paperStudentVO); |
| | | return CommonResult.success(); |
| | | } |
| | | } |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExPhaseStudentController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | } |
| | | |
| | | @RepeatSubmit |
| | | @Log(title = "批次与学员关系管理", businessType = BusinessType.UPDATE) |
| | | @Log(title = "批次与学员关系管理", businessType = BusinessType.DELETE) |
| | | @ApiOperation(value = "批量删除学员") |
| | | @DeleteMapping(value = { "/batchDelete" }) |
| | | public CommonResult batchDelete( List<Long> phaseStudentIds){ |
| | | public CommonResult batchDelete(@RequestBody List<Long> phaseStudentIds){ |
| | | phaseStudentService.batchDeletePhaseStudent(phaseStudentIds); |
| | | return CommonResult.success(); |
| | | } |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExQuestionBankController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExQuestionController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"), |
| | | @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10"), |
| | | @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "long", required = true, value = "题库id") |
| | | @ApiImplicitParam(paramType = "query", name = "bankId", dataType = "long", required = false, value = "题库id") |
| | | }) |
| | | @GetMapping("/list") |
| | | public CommonResult list(ExQuestion question){ |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExResourceController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExStatisticController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | |
| | | @ApiImplicitParam(paramType = "query", name = "type", dataType = "int", required = true, value = "1线上教育 2线下教育,默认1") |
| | | }) |
| | | @GetMapping("/companyStatistic") |
| | | public CommonResult companyStatistic(@RequestParam(required = false) Date startTime, @RequestParam(required = false) Date endTime, @RequestParam(required = false) Long companyId, @RequestParam(required = true,value = "1") Integer type) { |
| | | public CommonResult companyStatistic(@RequestParam(required = true,defaultValue = "1") Integer type, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime, @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date endTime, @RequestParam(required = false) Long companyId) { |
| | | return CommonResult.success(statisticService.companyStatic(companyId, startTime, endTime,type)); |
| | | } |
| | | |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExStudentController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @ApiOperation(value = "校验身份证是否为一") |
| | | @PostMapping(value = "/checkIdNoUnique") |
| | | public CommonResult checkIdNoUnique(@RequestBody ExStudent student){ |
| | | return CommonResult.success(studentService.checkIdNoUnique(student)); |
| | | return CommonResult.success(studentService.checkIdNoUnique(student.getIdNo())); |
| | | } |
| | | |
| | | |
| | | @ApiOperation(value = "学员企业归属变更") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(paramType = "body", name = "studentId", dataType = "long", required = true, value = "学员id"), |
| | | @ApiImplicitParam(paramType = "body", name = "companyId", dataType = "long", required = true, value = "公司id") |
| | | }) |
| | | @PreAuthorize("hasAnyAuthority('train:exam:system','train:exam:company')") |
| | | @PostMapping(value = "/changeStudentCompany") |
| | | public CommonResult changeStudentCompany(@RequestBody Map<String,Long> bodyMap){ |
| | | studentService.changeStudentCompany(bodyMap); |
| | | return CommonResult.success(); |
| | | } |
| | | |
| | | |
| | | @ApiOperation(value = "学员培训记录") |
| | | @GetMapping(value = "/trainRecord") |
| | | public CommonResult trainRecord(Long studentId){ |
| | | return CommonResult.success(studentService.trainRecord(studentId)); |
| | | } |
| | | |
| | | } |
文件名从 exam-admin/src/main/java/com/gkhy/exam/admin/web/ExStudentStudyController.java 修改 |
| | |
| | | package com.gkhy.exam.admin.web; |
| | | package com.gkhy.exam.admin.controller.web; |
| | | |
| | | |
| | | import com.gkhy.exam.common.annotation.Log; |
| | |
| | | password: |
| | | initialSize: 5 #连接池初始化大小 |
| | | minIdle: 10 #最小空闲连接数 |
| | | maxActive: 20 #最大连接数 |
| | | maxActive: 50 #最大连接数 |
| | | # 配置获取连接等待超时的时间 |
| | | maxWait: 60000 |
| | | # 配置连接超时时间 |
| | |
| | | level: |
| | | root: INFO |
| | | org: |
| | | com.nms.swspkmas_standalone: DEBUG |
| | | file: |
| | | name: logs/nms-kaoshi.log |
| | | com.gkhy.exam: DEBUG |
| | | |
| | | swagger: |
| | | enabled: true |
| | |
| | | endpoint: http://192.168.2.16:9000/ #Minio服务所在地址 |
| | | bucketName: trainexam #存储桶名称 |
| | | accessKey: JuHGtYXvgJdeaPHcu5AI #访问的key |
| | | secretKey: mQhUsIYnD696ZFI2sJ6eQ77tmmoe9TTUavFg9Ien #访问的秘钥 |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | version: '3.9' |
| | | services: |
| | | kele_mysql: |
| | | restart: always |
| | | image: mysql:5.6 |
| | | volumes: |
| | | - ./data/mysql:/var/lib/mysql |
| | | - ./conf/mysql/:/etc/mysql/conf.d |
| | | ports: |
| | | - "3306:3306" |
| | | environment: |
| | | - MYSQL_DATABASE=imooc |
| | | - MYSQL_ROOT_PASSWORD=root |
| | | |
| | | kele_nginx: |
| | | restart: always |
| | | image: nginx |
| | | ports: |
| | | - "8001:80" |
| | | volumes: |
| | | - ./conf/nginx/mx_nginx.conf:/etc/nginx/conf.d/mx_nginx.conf |
| | | volumes_from: |
| | | - kele_imooc |
| | | links: |
| | | - kele_imooc:web |
| | | |
| | | kele_imooc: |
| | | restart: always |
| | | build: . |
| | | ports: |
| | | - "8000:8000" |
| | | volumes: |
| | | - .:/imooc |
| | | links: |
| | | - kele_mysql:mysql |
| | | command: uwsgi -s :8000 -w imooc.wsgi -p 3 |
| | | |
| | | secretKey: mQhUsIYnD696ZFI2sJ6eQ77tmmoe9TTUavFg9Ien #访问的秘钥 |
对比新文件 |
| | |
| | | spring: |
| | | datasource: |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | druid: |
| | | # 主库数据源 |
| | | master: |
| | | url: jdbc:mysql://127.0.0.1:6361/train_exam?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true |
| | | username: root |
| | | password: HZjCbHGxiXy7cek4 |
| | | # 从库数据源 |
| | | slave: |
| | | enabled: false |
| | | url: |
| | | username: |
| | | password: |
| | | initialSize: 5 #连接池初始化大小 |
| | | minIdle: 10 #最小空闲连接数 |
| | | maxActive: 50 #最大连接数 |
| | | # 配置获取连接等待超时的时间 |
| | | maxWait: 60000 |
| | | # 配置连接超时时间 |
| | | connectTimeout: 30000 |
| | | # 配置网络超时时间 |
| | | socketTimeout: 60000 |
| | | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 |
| | | timeBetweenEvictionRunsMillis: 60000 |
| | | # 配置一个连接在池中最小生存的时间,单位是毫秒 |
| | | minEvictableIdleTimeMillis: 300000 |
| | | # 配置一个连接在池中最大生存的时间,单位是毫秒 |
| | | maxEvictableIdleTimeMillis: 900000 |
| | | # 配置检测连接是否有效 |
| | | validationQuery: SELECT 1 FROM DUAL |
| | | testWhileIdle: true |
| | | testOnBorrow: false |
| | | testOnReturn: false |
| | | web-stat-filter: |
| | | exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据 |
| | | stat-view-servlet: #访问监控网页的登录用户名和密码 |
| | | login-username: druid |
| | | login-password: druid |
| | | #redis 配置 |
| | | redis: |
| | | database: 4 |
| | | host: 127.0.0.1 |
| | | port: 6379 |
| | | password: akj78avauba789a |
| | | |
| | | |
| | | # mybatis-plus相关配置 |
| | | mybatis-plus: |
| | | # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置) |
| | | mapper-locations: classpath*:mapper/**/*Mapper.xml |
| | | # 以下配置均有默认值,可以不设置 |
| | | global-config: |
| | | db-config: |
| | | #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; |
| | | id-type: auto |
| | | #字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断" |
| | | field-strategy: NOT_EMPTY |
| | | #数据库类型 |
| | | db-type: MYSQL |
| | | configuration: |
| | | # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射 |
| | | map-underscore-to-camel-case: true |
| | | # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段 |
| | | call-setters-on-nulls: true |
| | | # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 |
| | | #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
| | | |
| | | |
| | | logging: |
| | | level: |
| | | root: INFO |
| | | org: |
| | | com.gkhy.exam: INFO |
| | | |
| | | |
| | | swagger: |
| | | enabled: false |
| | | |
| | | minio: |
| | | endpoint: http://106.15.95.149:9001/ #Minio服务所在地址 |
| | | bucketName: trainexam #存储桶名称 |
| | | accessKey: U9JW4xOeeUQOSR4f #访问的key |
| | | secretKey: iaqQV6twR9yDZiFAf2UYr5xZfESanZs3 #访问的秘钥 |
对比新文件 |
| | |
| | | spring: |
| | | datasource: |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | driverClassName: com.mysql.cj.jdbc.Driver |
| | | druid: |
| | | # 主库数据源 |
| | | master: |
| | | url: jdbc:mysql://127.0.0.1:23306/train_exam?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Beijing&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true |
| | | username: root |
| | | password: 2farwL3yPXfbH2AP |
| | | # 从库数据源 |
| | | slave: |
| | | enabled: false |
| | | url: |
| | | username: |
| | | password: |
| | | initialSize: 5 #连接池初始化大小 |
| | | minIdle: 10 #最小空闲连接数 |
| | | maxActive: 50 #最大连接数 |
| | | # 配置获取连接等待超时的时间 |
| | | maxWait: 60000 |
| | | # 配置连接超时时间 |
| | | connectTimeout: 30000 |
| | | # 配置网络超时时间 |
| | | socketTimeout: 60000 |
| | | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 |
| | | timeBetweenEvictionRunsMillis: 60000 |
| | | # 配置一个连接在池中最小生存的时间,单位是毫秒 |
| | | minEvictableIdleTimeMillis: 300000 |
| | | # 配置一个连接在池中最大生存的时间,单位是毫秒 |
| | | maxEvictableIdleTimeMillis: 900000 |
| | | # 配置检测连接是否有效 |
| | | validationQuery: SELECT 1 FROM DUAL |
| | | testWhileIdle: true |
| | | testOnBorrow: false |
| | | testOnReturn: false |
| | | web-stat-filter: |
| | | exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据 |
| | | stat-view-servlet: #访问监控网页的登录用户名和密码 |
| | | login-username: druid |
| | | login-password: druid |
| | | #redis 配置 |
| | | redis: |
| | | database: 0 |
| | | host: 127.0.0.1 |
| | | port: 6379 |
| | | password: |
| | | |
| | | |
| | | # mybatis-plus相关配置 |
| | | mybatis-plus: |
| | | # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置) |
| | | mapper-locations: classpath*:mapper/**/*Mapper.xml |
| | | # 以下配置均有默认值,可以不设置 |
| | | global-config: |
| | | db-config: |
| | | #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; |
| | | id-type: auto |
| | | #字段策略 IGNORED:"忽略判断" NOT_NULL:"非 NULL 判断") NOT_EMPTY:"非空判断" |
| | | field-strategy: NOT_EMPTY |
| | | #数据库类型 |
| | | db-type: MYSQL |
| | | configuration: |
| | | # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射 |
| | | map-underscore-to-camel-case: true |
| | | # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段 |
| | | call-setters-on-nulls: true |
| | | # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 |
| | | #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
| | | |
| | | |
| | | logging: |
| | | level: |
| | | root: INFO |
| | | org: |
| | | com.gkhy.exam: INFO |
| | | |
| | | |
| | | swagger: |
| | | enabled: false |
| | | |
| | | minio: |
| | | endpoint: http://127.0.0.1:9000/ #Minio服务所在地址 |
| | | bucketName: trainexam #存储桶名称 |
| | | accessKey: nblxqRZXDvQ59HBH49rF #访问的key |
| | | secretKey: TR0IFphXPo0IObQCYgcJ0JOik21s40ey2MIMU8Rh #访问的秘钥 |
| | |
| | | application: |
| | | name: train_exam |
| | | profiles: |
| | | active: dev |
| | | active: guotai |
| | | servlet: |
| | | multipart: |
| | | enabled: true |
| | |
| | | port: 8082 |
| | | servlet: |
| | | context-path: /api |
| | | tomcat: |
| | | threads: |
| | | min-spare: 10 |
| | | max: 200 |
| | | |
| | | |
| | | # 用户配置 |
| | |
| | | #获取ip地址开关 |
| | | addressEnabled: false |
| | | |
| | | |
| | | # 防止XSS攻击 |
| | | xss: |
| | | # 过滤开关 |
| | | enabled: true |
| | | # 排除链接(多个用逗号分隔) |
| | | excludes: |
| | | # 匹配链接 |
| | | urlPatterns: /system/*,/manage/* |
| | | |
| | |
| | | -- ---------------------------- |
| | | -- 系统管理用户表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_user`; |
| | | CREATE TABLE `train_exam`.`sys_user` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
| | | `username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录账号', |
| | |
| | | `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '手机号码', |
| | | `sex` tinyint NULL DEFAULT 2 COMMENT '用户性别(0男,1女,2未知,默认2)', |
| | | `company_id` bigint(20) NULL DEFAULT NULL COMMENT '公司id', |
| | | `parent_id` bigint(20) NULL DEFAULT NULL COMMENT '父级账号id', |
| | | `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父级账号id', |
| | | `password` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码', |
| | | `status` tinyint NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)', |
| | | `del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标志(0代表存在,2代表删除,默认0)', |
| | |
| | | UNIQUE INDEX `index_username`(`username`) USING BTREE |
| | | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统管理用户表' ROW_FORMAT = Dynamic; |
| | | |
| | | insert into sys_user values(1, 'admin', '国科鸿宇', 0, '15888888888', 0, null, '$2a$10$CrsAZufp851DxTmUBep7TOuUAESWdqlkrReAIR.4SHBIahl9exO6y', 0, 0, '127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', sysdate(), '管理员',0); |
| | | insert into sys_user values(1, 'admin', '国科鸿宇', 0, '15888888888', 0, null,0, '$2a$10$CrsAZufp851DxTmUBep7TOuUAESWdqlkrReAIR.4SHBIahl9exO6y', 0, 0, '127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', sysdate(), '管理员',0); |
| | |
| | | -- ---------------------------- |
| | | -- 字典类型表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_dict_type`; |
| | | CREATE TABLE `train_exam`.`sys_dict_type` ( |
| | | `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT, |
| | | `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典名称', |
| | |
| | | -- ---------------------------- |
| | | -- 字典数据表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_dict_data`; |
| | | CREATE TABLE `train_exam`.`sys_dict_data` ( |
| | | `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT, |
| | | `sort` int NOT NULL DEFAULT 0 COMMENT '字典排序', |
| | |
| | | -- ---------------------------- |
| | | -- 系统配置表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_config`; |
| | | CREATE TABLE `train_exam`.`sys_config` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT, |
| | | `name` varchar(100) NOT NULL COMMENT '参数名称', |
| | |
| | | -- ---------------------------- |
| | | -- 系统通知表 |
| | | -- ---------------------------- |
| | | drop table if exists sys_notice; |
| | | create table sys_notice ( |
| | | id bigint NOT NULL AUTO_INCREMENT, |
| | | title varchar(50) not null comment '公告标题', |
| | |
| | | -- ---------------------------- |
| | | -- 操作日志表 |
| | | -- ---------------------------- |
| | | drop table if exists sys_oper_log; |
| | | create table sys_oper_log ( |
| | | id bigint(20) not null auto_increment comment '日志主键', |
| | | title varchar(50) default '' comment '模块标题', |
| | |
| | | -- ---------------------------- |
| | | -- 系统访问记录 |
| | | -- ---------------------------- |
| | | drop table if exists sys_logininfor; |
| | | create table sys_logininfor ( |
| | | id bigint(20) not null auto_increment comment '日志主键', |
| | | user_name varchar(50) default '' comment '用户账号', |
| | |
| | | -- ---------------------------- |
| | | -- 学员表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_student`; |
| | | CREATE TABLE `train_exam`.`ex_student` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
| | | `company_id` bigint(20) NOT NULL COMMENT '企业id', |
| | |
| | | -- ---------------------------- |
| | | -- 企业表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_company`; |
| | | CREATE TABLE `train_exam`.`sys_company` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, |
| | | `name` varchar(80) NOT NULL COMMENT '企业名称', |
| | | `credit_code` varchar(30) NOT NULL COMMENT '企业信用代码', |
| | | `major` varchar(30) NOT NULL COMMENT '负责人', |
| | | `phone` varchar(11) NOT NULL COMMENT '联系电话', |
| | | `remain_period` int NOT NULL DEFAULT 0 COMMENT '剩余课时(分)', |
| | | `spend_period` int NOT NULL DEFAULT 0 COMMENT '已用课时(分)', |
| | | `total_period` int NOT NULL DEFAULT 0 COMMENT '总课时(分)', |
| | | `remain_period` bigint(20) NOT NULL DEFAULT 0 COMMENT '剩余课时(秒)', |
| | | `total_period` bigint(20) NOT NULL DEFAULT 0 COMMENT '总课时(秒)', |
| | | `del_flag` tinyint NOT NULL DEFAULT 0 COMMENT '删除标志(0为删除,1删除,默认0)', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | | `create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人', |
| | |
| | | -- ---------------------------- |
| | | -- 轮播图表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_carousel`; |
| | | CREATE TABLE `train_exam`.`sys_carousel` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)', |
| | |
| | | -- ---------------------------- |
| | | -- 课程分类表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`sys_category`; |
| | | CREATE TABLE `train_exam`.`sys_category` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `parent_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '父分类id', |
| | | `name` varchar(30) NOT NULL COMMENT '分类名称', |
| | | `category_type` tinyint NOT NULL DEFAULT 1 COMMENT '类型(1课程,2资源)', |
| | | `del_flag` tinyint NOT NULL DEFAULT 0 COMMENT '删除标志(0为删除,1删除,默认0)', |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)', |
| | | `sort` int UNSIGNED NOT NULL DEFAULT 1 COMMENT '排序', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | |
| | | -- ---------------------------- |
| | | -- 课程表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_course`; |
| | | CREATE TABLE `train_exam`.`ex_course` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT '课程状态(0正常,1停用,默认0)', |
| | |
| | | `name` varchar(50) NOT NULL COMMENT '课程名称', |
| | | `logo` varchar(255) NOT NULL DEFAULT '' COMMENT '课程封面', |
| | | `introduce` text NULL COMMENT '课程简介', |
| | | `state` tinyint NULL DEFAULT 1 COMMENT '审批状态(0创建,1待审核,2审批通过,3审批不通过 默认0)', |
| | | `state` tinyint NULL DEFAULT 0 COMMENT '审批状态(0创建,1待审核,2审批通过,3审批不通过 默认0)', |
| | | `message` varchar(50) NULL COMMENT '审批意见', |
| | | `company_id` bigint(20) NULL COMMENT '提交公司id', |
| | | `privatize` tinyint NOT NULL DEFAULT 0 COMMENT '课程公开私有属性(0私有,1公开 默认0)', |
| | | `period` bigint(20) NOT NULL DEFAULT 0 COMMENT '课时(单位秒)', |
| | | `del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标志(0代表存在,2代表删除,默认0)', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | | `create_by` varchar(50) NULL DEFAULT NULL COMMENT '创建人', |
| | |
| | | -- ---------------------------- |
| | | -- 课程章节表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_course_chapter`; |
| | | CREATE TABLE `train_exam`.`ex_course_chapter` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)', |
| | |
| | | -- ---------------------------- |
| | | -- 课时信息表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_course_chapter_period`; |
| | | CREATE TABLE `train_exam`.`ex_course_chapter_period` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)', |
| | |
| | | -- ---------------------------- |
| | | -- 课程资源表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_resource`; |
| | | CREATE TABLE `train_exam`.`ex_resource` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)', |
| | |
| | | `company_id` bigint(20) NULL COMMENT '提交公司id', |
| | | `resource_type` tinyint NOT NULL DEFAULT 1 COMMENT '资源种类(1:视频2:音频;3:文档,默认1)', |
| | | `media_type` varchar(100) NULL COMMENT '资源类型', |
| | | `resource_size` bigint(20) NOT NULL COMMENT '资源大小', |
| | | `resource_size` bigint(20) NOT NULL DEFAULT 0 COMMENT '资源大小', |
| | | `resource_uri` varchar(200) NULL DEFAULT NULL COMMENT '资源地址(存放第三方地址)', |
| | | `resource_length` bigint(20) NULL DEFAULT NULL COMMENT '资源时长(秒)', |
| | | `resource_length` bigint(20) NULL DEFAULT 0 COMMENT '资源时长(秒)', |
| | | `resource_path` varchar(120) NULL DEFAULT NULL COMMENT '资源路径', |
| | | `md5` varchar(50) NOT NULL COMMENT '文件md5', |
| | | `doc_page` int NULL DEFAULT 0 COMMENT '资源页数,单位页', |
| | |
| | | -- ---------------------------- |
| | | -- 课时批次表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_course_phase`; |
| | | CREATE TABLE `train_exam`.`ex_course_phase` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `code` varchar(12) NOT NULL COMMENT '批次编号', |
| | |
| | | -- ---------------------------- |
| | | -- 课程学习学习日志表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_student_study`; |
| | | CREATE TABLE `train_exam`.`ex_student_study` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `phase_id` bigint(20) NOT NULL COMMENT '课时批次id', |
| | |
| | | `current_duration` bigint(20) NOT NULL DEFAULT 0 COMMENT '当前学习时长,单位秒', |
| | | `current_page` int NOT NULL DEFAULT 0 COMMENT '当前学习页数,单位页', |
| | | `progress` decimal(5, 2) NOT NULL DEFAULT 0 COMMENT '进度(百分比)', |
| | | `resource_type` varchar(10) NOT NULL COMMENT '资源类型(PPT,MP4,PDF)', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | | `create_by` varchar(50) NULL DEFAULT NULL COMMENT '创建人', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| | |
| | | -- ---------------------------- |
| | | -- 课时批次与学员关系表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_phase_student`; |
| | | CREATE TABLE `train_exam`.`ex_phase_student` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `phase_id` bigint(20) NOT NULL COMMENT '课时批次id', |
| | |
| | | -- ---------------------------- |
| | | -- 公司课时变更记录表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_company_period`; |
| | | CREATE TABLE `train_exam`.`ex_company_period` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `company_id` bigint NOT NULL COMMENT '公司id', |
| | | `phase_id` bigint NULL COMMENT '批次id', |
| | | `origin` varchar(50) NOT NULL COMMENT '变动来源', |
| | | `modify_period` int NOT NULL COMMENT '变动情况(增减课时)', |
| | | `remain_period` int NOT NULL COMMENT '变动后剩余(分)', |
| | | `modify_period` bigint(20) NOT NULL COMMENT '变动情况(增减课时)秒', |
| | | `remain_period` bigint(20) NOT NULL COMMENT '变动后剩余(秒)', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | | `create_by` varchar(50) NULL DEFAULT NULL COMMENT '创建人', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| | |
| | | -- ---------------------------- |
| | | -- 考卷(组卷)表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_exam_paper`; |
| | | CREATE TABLE `train_exam`.`ex_exam_paper` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `code` varchar(12) NOT NULL COMMENT '编号', |
| | |
| | | `company_id` bigint NOT NULL COMMENT '公司id', |
| | | `category_id` bigint(20) NOT NULL COMMENT '分类ID', |
| | | `limit_time` int NOT NULL DEFAULT 0 COMMENT '考试限制时长', |
| | | `limit` tinyint NOT NULL DEFAULT 0 COMMENT '是否现在考试时间(0否,1是,默认0)', |
| | | `limited` tinyint NOT NULL DEFAULT 0 COMMENT '是否现在考试时间(0否,1是,默认0)', |
| | | `single_num` int NOT NULL DEFAULT 0 COMMENT '单选题目数量', |
| | | `single_score` int NOT NULL DEFAULT 0 COMMENT '单选题每题分数', |
| | | `single_bank_id` bigint(20) NULL COMMENT '单选题题库id', |
| | |
| | | `judge_method` tinyint NOT NULL DEFAULT 1 COMMENT '出题方式1随机,2顺序,默认1', |
| | | `pass_score` int NOT NULL DEFAULT 0 COMMENT '合格分数', |
| | | `del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标志(0代表存在,2代表删除,默认0)', |
| | | `deadline` datetime NOT NULL COMMENT '考试截止时间', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| | | `create_by` varchar(50) NULL DEFAULT NULL COMMENT '创建人', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
| | |
| | | -- ---------------------------- |
| | | -- 考卷与学员关系表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_paper_student`; |
| | | CREATE TABLE `train_exam`.`ex_paper_student` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `paper_id` bigint(20) NOT NULL COMMENT '考卷id', |
| | |
| | | -- ---------------------------- |
| | | -- 考题表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_question`; |
| | | CREATE TABLE `train_exam`.`ex_question` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `question_type` tinyint NOT NULL DEFAULT 1 COMMENT '考题类型(1单选题,2多选题,3判断题 默认1)', |
| | |
| | | -- ---------------------------- |
| | | -- 学员与考试题目关系表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_student_answer`; |
| | | CREATE TABLE `train_exam`.`ex_student_answer` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `paper_id` bigint(20) NOT NULL COMMENT '考卷id', |
| | |
| | | -- ---------------------------- |
| | | -- 试卷与题目关系表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_paper_question`; |
| | | CREATE TABLE `train_exam`.`ex_paper_question` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `paper_id` bigint(20) NOT NULL COMMENT '考卷id', |
| | |
| | | -- ---------------------------- |
| | | -- 线下教育登记表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_exam_record`; |
| | | CREATE TABLE `train_exam`.`ex_exam_record` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `company_id` bigint(20) NOT NULL COMMENT '公司id', |
| | | `student_id` bigint(20) NOT NULL COMMENT '学员id', |
| | | `plan_name` varchar(50) NOT NULL COMMENT '计划名称', |
| | | `course_name` varchar(50) NOT NULL COMMENT '课程名称', |
| | | `level` varchar(20) NOT NULL COMMENT '培训等级', |
| | | `level` tinyint NOT NULL DEFAULT 1 COMMENT '培训等级(1公司级 2部门级 3车间级 默认1)', |
| | | `period` int NOT NULL COMMENT '要求课时(分)', |
| | | `actual_period` int NOT NULL COMMENT '实际课时(分)', |
| | | `score` int NOT NULL COMMENT '考试成绩', |
| | |
| | | -- ---------------------------- |
| | | -- 题库表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_question_bank`; |
| | | CREATE TABLE `train_exam`.`ex_question_bank` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `name` varchar(50) NOT NULL COMMENT '题库名称', |
| | | `company_id` bigint NOT NULL COMMENT '公司id', |
| | | `company_id` bigint NULL COMMENT '公司id', |
| | | `category_id` bigint(20) NOT NULL COMMENT '分类ID', |
| | | `del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标志(0代表存在,2代表删除,默认0)', |
| | | `privatize` tinyint NOT NULL DEFAULT 0 COMMENT '课程公开私有属性(0私有,1公开 默认0)', |
| | |
| | | -- ---------------------------- |
| | | -- 学员与练习题关系表 |
| | | -- ---------------------------- |
| | | drop table if exists `train_exam`.`ex_exercise_answer`; |
| | | CREATE TABLE `train_exam`.`ex_exercise_answer` ( |
| | | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , |
| | | `bank_id` bigint(20) NOT NULL COMMENT '题库id', |
| | |
| | | `remark` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', |
| | | `version` int NULL DEFAULT 0 COMMENT '乐观锁', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | UNIQUE KEY `paper_student_id` (`student_id`,`question_id`) |
| | | UNIQUE KEY `question_student_id` (`student_id`,`question_id`) |
| | | ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '学员与练习题关系表' ROW_FORMAT = DYNAMIC; |
对比新文件 |
| | |
| | | ALTER TABLE `train_exam`.`ex_question` |
| | | MODIFY COLUMN `answer` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '答案'; |
对比新文件 |
| | |
| | | ALTER TABLE `train_exam`.`ex_paper_student` |
| | | ADD COLUMN `state` tinyint NOT NULL DEFAULT 0 COMMENT '状态:0待考试,1待批阅 2批阅完成'; |
对比新文件 |
| | |
| | | ALTER TABLE `train_exam`.`ex_exam_paper` |
| | | MODIFY COLUMN `single_num` int NULL DEFAULT 0 COMMENT '单选题目数量', |
| | | MODIFY COLUMN `single_score` int NULL DEFAULT 0 COMMENT '单选题每题分数', |
| | | MODIFY COLUMN `single_method` tinyint NULL DEFAULT 1 COMMENT '出题方式1随机,2顺序,默认1', |
| | | MODIFY COLUMN `multi_num` int NULL DEFAULT 0 COMMENT '多选题目数量', |
| | | MODIFY COLUMN `multi_score` int NULL DEFAULT 0 COMMENT '多选题每题分数', |
| | | MODIFY COLUMN `multi_method` tinyint NULL DEFAULT 1 COMMENT '出题方式1随机,2顺序,默认1', |
| | | MODIFY COLUMN `judge_num` int NULL DEFAULT 0 COMMENT '判断题目数量', |
| | | MODIFY COLUMN `judge_score` int NULL DEFAULT 0 COMMENT '判断题每题分数', |
| | | MODIFY COLUMN `judge_method` tinyint NULL DEFAULT 1 COMMENT '出题方式1随机,2顺序,默认1', |
| | | ADD COLUMN `easy_num` int NULL DEFAULT 0 COMMENT '简答题题目数量', |
| | | ADD COLUMN `easy_score` int NULL DEFAULT 0 COMMENT '简答题每题分数', |
| | | ADD COLUMN `easy_bank_id` bigint NULL COMMENT '简答题题库id', |
| | | ADD COLUMN `easy_method` tinyint NULL DEFAULT 1 COMMENT '出题方式1随机,2顺序,默认1'; |
对比新文件 |
| | |
| | | ALTER TABLE `train_exam`.`ex_student_answer` |
| | | MODIFY COLUMN `passed` tinyint NULL DEFAULT NULL COMMENT '是否正确(0错误,1正确,2待批改)', |
| | | ADD COLUMN `score` int NULL COMMENT '得分'; |
对比新文件 |
| | |
| | | ALTER TABLE `train_exam`.`ex_student_answer` |
| | | MODIFY COLUMN `answer` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '答案'; |
| | | |
| | | ALTER TABLE `train_exam`.`ex_exercise_answer` |
| | | MODIFY COLUMN `answer` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '答案'; |
对比新文件 |
| | |
| | | ALTER TABLE `train_exam`.`ex_question` |
| | | MODIFY COLUMN `company_id` bigint NULL COMMENT '公司id' AFTER `bank_id`; |
对比新文件 |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE configuration> |
| | | <configuration> |
| | | <!--引用默认日志配置--> |
| | | <include resource="org/springframework/boot/logging/logback/defaults.xml"/> |
| | | <!--使用默认的控制台日志输出实现--> |
| | | <include resource="org/springframework/boot/logging/logback/console-appender.xml"/> |
| | | <!--应用名称--> |
| | | <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/> |
| | | <!-- 日志输出格式 --> |
| | | <property name="log.pattern" |
| | | value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{requestId}] [%X{clientIP}] [%X{userId}] - [%C,%M,%L] - %msg%n"/> |
| | | |
| | | <property name="log.path" value="logs"/> |
| | | <!--日志文件保存路径--> |
| | | <property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/> |
| | | |
| | | |
| | | |
| | | <!-- 控制台输出 --> |
| | | <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
| | | <pattern>${log.pattern}</pattern> |
| | | <charset>utf8</charset> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- 系统日志输出 --> |
| | | <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- <file>${log.path}/zero-spring-info.log</file>--> |
| | | <!-- 循环政策:基于时间创建日志文件 --> |
| | | <!-- <file>--> |
| | | <!-- logs/zero-spring.log--> |
| | | <!-- </file>--> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <!-- 日志文件名格式 --> |
| | | <fileNamePattern>${log.path}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log</fileNamePattern> |
| | | <totalSizeCap>30GB</totalSizeCap> |
| | | <!--设置日志文件大小,超过就重新生成文件,默认50M--> |
| | | <maxFileSize>100MB</maxFileSize> |
| | | <!-- 日志最大的历史 30天 --> |
| | | <maxHistory>30</maxHistory> |
| | | </rollingPolicy> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <!-- 过滤的级别 --> |
| | | <level>INFO</level> |
| | | <!-- 匹配时的操作:接收(记录) --> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <!-- 不匹配时的操作:拒绝(不记录) --> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- <file>${log.path}/zero-spring-error.log</file>--> |
| | | <!-- 循环政策:基于时间创建日志文件 --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
| | | <!-- 日志文件名格式 --> |
| | | <fileNamePattern>${log.path}/${APP_NAME}-error-%d{yyyy-MM-dd}-%i.log</fileNamePattern> |
| | | <totalSizeCap>10GB</totalSizeCap> |
| | | <!--设置日志文件大小,超过就重新生成文件,默认50M--> |
| | | <maxFileSize>100MB</maxFileSize> |
| | | <!-- 日志最大的历史 30天 --> |
| | | <maxHistory>30</maxHistory> |
| | | </rollingPolicy> |
| | | <encoder> |
| | | <pattern>${log.pattern}</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <!-- 过滤的级别 --> |
| | | <level>ERROR</level> |
| | | <!-- 匹配时的操作:接收(记录) --> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <!-- 不匹配时的操作:拒绝(不记录) --> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | |
| | | <!--控制框架输出日志--> |
| | | <logger name="org.slf4j" level="INFO"/> |
| | | <logger name="springfox" level="INFO"/> |
| | | <logger name="io.swagger" level="INFO"/> |
| | | <logger name="org.springframework" level="INFO"/> |
| | | <logger name="org.hibernate.validator" level="INFO"/> |
| | | |
| | | <root level="INFO"> |
| | | <!-- <appender-ref ref="console"/>--> |
| | | <appender-ref ref="file_info"/> |
| | | <appender-ref ref="file_error"/> |
| | | </root> |
| | | |
| | | |
| | | <root level="DEBUG"> |
| | | <appender-ref ref="console"/> |
| | | </root> |
| | | </configuration> |
对比新文件 |
| | |
| | | package com.gkhy.exam.admin; |
| | | |
| | | import com.gkhy.exam.system.service.SysCommonService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.runner.RunWith; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.springframework.test.context.ActiveProfiles; |
| | | import org.springframework.test.context.junit4.SpringRunner; |
| | | |
| | | @RunWith(SpringRunner.class) |
| | | @SpringBootTest(classes = GkhyAdminApplication.class) |
| | | @ActiveProfiles("dev") |
| | | @Slf4j |
| | | public class ExcelTest { |
| | | @Autowired |
| | | private SysCommonService commonService; |
| | | |
| | | @Test |
| | | public void importTest(){ |
| | | commonService.importStudent(); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.admin; |
| | | |
| | | import com.gkhy.exam.framework.job.PaperStudentJob; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.junit.Test; |
| | | import org.junit.runner.RunWith; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.springframework.test.context.ActiveProfiles; |
| | | import org.springframework.test.context.junit4.SpringRunner; |
| | | |
| | | @RunWith(SpringRunner.class) |
| | | @SpringBootTest(classes = GkhyAdminApplication.class) |
| | | @ActiveProfiles("dev") |
| | | @Slf4j |
| | | public class JobTest { |
| | | @Autowired |
| | | private PaperStudentJob paperStudentJob; |
| | | |
| | | |
| | | @Test |
| | | public void jobTest(){ |
| | | paperStudentJob.doprogress(); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.Random; |
| | | |
| | | @RunWith(SpringRunner.class) |
| | |
| | | b.add("c"); |
| | | return aa; |
| | | } |
| | | |
| | | @Test |
| | | public void testNum(){ |
| | | Integer a=null; |
| | | int b=0; |
| | | if(Optional.ofNullable(a).orElse(0)>b){ |
| | | System.out.println("gggggg"); |
| | | }else{ |
| | | System.out.println("hhhhhh"); |
| | | } |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.admin; |
| | | |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.gkhy.exam.system.domain.ExQuestion; |
| | | import com.gkhy.exam.system.service.ExQuestionService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.junit.Test; |
| | | import org.junit.runner.RunWith; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.springframework.test.context.ActiveProfiles; |
| | | import org.springframework.test.context.junit4.SpringRunner; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Random; |
| | | |
| | | @RunWith(SpringRunner.class) |
| | | @SpringBootTest(classes = GkhyAdminApplication.class) |
| | | @ActiveProfiles("dev") |
| | | @Slf4j |
| | | public class QuestionTest { |
| | | @Autowired |
| | | private ExQuestionService questionService; |
| | | |
| | | // 定义选项数量 |
| | | private static final int OPTION_COUNT = 4; |
| | | // 随机生成器 |
| | | private static final Random random = new Random(); |
| | | |
| | | @Test |
| | | public void questionData(){ |
| | | List<ExQuestion>questions=new ArrayList<>(); |
| | | for(int i=0;i<300;i++){ |
| | | ExQuestion question=generateSingleQuestion(); |
| | | questions.add(question); |
| | | question=generateMultiQuestion(); |
| | | questions.add(question); |
| | | question=generateJudgeQuestion(); |
| | | questions.add(question); |
| | | if(questions.size()>100){ |
| | | questionService.saveBatch(questions); |
| | | questions.clear(); |
| | | } |
| | | } |
| | | if(questions.size()>0){ |
| | | questionService.saveBatch(questions); |
| | | questions.clear(); |
| | | } |
| | | // ExQuestion question=generateSingleQuestion(); |
| | | // System.out.println(question); |
| | | // question=generateMultiQuestion(); |
| | | // System.out.println(question); |
| | | // question=generateJudgeQuestion(); |
| | | // System.out.println(question); |
| | | } |
| | | |
| | | // 生成单选题目 |
| | | public ExQuestion generateSingleQuestion() { |
| | | int a=random.nextInt(1000); |
| | | int b=random.nextInt(1000); |
| | | int sum=a+b; |
| | | List<String> options=new ArrayList<>(); |
| | | options.add("A"); |
| | | options.add("B"); |
| | | options.add("C"); |
| | | options.add("D"); |
| | | int index=random.nextInt(4); |
| | | String title="算术运算题,整数"+a+"与整数"+b+"之和,等于多少?"; |
| | | JSONObject object=new JSONObject(); |
| | | object.put("analyze","无"); |
| | | JSONArray jsonArray=new JSONArray(); |
| | | for(int i=0;i<4;i++){ |
| | | if(i==index){ |
| | | JSONObject itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(index)); |
| | | itemObject.put("content",sum); |
| | | jsonArray.add(itemObject); |
| | | }else{ |
| | | JSONObject itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(i)); |
| | | itemObject.put("content",randomInt(sum)); |
| | | jsonArray.add(itemObject); |
| | | } |
| | | } |
| | | object.put("items",jsonArray); |
| | | ExQuestion question=new ExQuestion(); |
| | | question.setQuestionType(1); |
| | | question.setBankId(16L); |
| | | question.setCompanyId(21L); |
| | | question.setAnswer(options.get(index)); |
| | | question.setTitle(title); |
| | | question.setPrivatize(0); |
| | | question.setContent(JSONObject.toJSONString(object)); |
| | | return question; |
| | | } |
| | | |
| | | // 生成多选题目 |
| | | public ExQuestion generateMultiQuestion() { |
| | | int a=random.nextInt(1000); |
| | | int b=random.nextInt(1000); |
| | | int sum=a+b; |
| | | List<String> options=new ArrayList<>(); |
| | | options.add("A"); |
| | | options.add("B"); |
| | | options.add("C"); |
| | | options.add("D"); |
| | | options.add("E"); |
| | | int indexa=random.nextInt(5); |
| | | int indexb=random.nextInt(5); |
| | | String title="算术运算题,整数"+a+"与整数"+b+"之和,等于多少?"; |
| | | JSONObject object=new JSONObject(); |
| | | object.put("analyze","无"); |
| | | JSONArray jsonArray=new JSONArray(); |
| | | for(int i=0;i<5;i++){ |
| | | if(i==indexa){ |
| | | JSONObject itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(indexa)); |
| | | itemObject.put("content",sum); |
| | | jsonArray.add(itemObject); |
| | | }else if(i==indexb) { |
| | | JSONObject itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(indexb)); |
| | | itemObject.put("content",sum); |
| | | jsonArray.add(itemObject); |
| | | }else{ |
| | | JSONObject itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(i)); |
| | | itemObject.put("content",randomInt(sum)); |
| | | jsonArray.add(itemObject); |
| | | } |
| | | } |
| | | object.put("items",jsonArray); |
| | | ExQuestion question=new ExQuestion(); |
| | | question.setQuestionType(2); |
| | | question.setBankId(16L); |
| | | question.setCompanyId(21L); |
| | | String answer=""; |
| | | if(indexa==indexb){ |
| | | answer=options.get(indexa); |
| | | }else{ |
| | | if(indexa>indexb){ |
| | | answer=options.get(indexb)+","+options.get(indexa); |
| | | }else{ |
| | | answer=options.get(indexa)+","+options.get(indexb); |
| | | } |
| | | } |
| | | question.setAnswer(answer); |
| | | question.setTitle(title); |
| | | question.setPrivatize(0); |
| | | question.setContent(JSONObject.toJSONString(object)); |
| | | return question; |
| | | } |
| | | |
| | | // 生成判断题目 |
| | | public ExQuestion generateJudgeQuestion() { |
| | | int a=random.nextInt(1000); |
| | | int b=random.nextInt(1000); |
| | | int sum=a+b; |
| | | List<String> options=new ArrayList<>(); |
| | | options.add("A"); |
| | | options.add("B"); |
| | | int index=random.nextInt(2); |
| | | String title="算术运算题,整数"+a+"与整数"+b+"之和,等于="+(index==0?sum:randomInt(sum)); |
| | | JSONObject object=new JSONObject(); |
| | | object.put("analyze","无"); |
| | | JSONArray jsonArray=new JSONArray(); |
| | | JSONObject itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(0)); |
| | | itemObject.put("content","是"); |
| | | jsonArray.add(itemObject); |
| | | itemObject=new JSONObject(); |
| | | itemObject.put("prefix",options.get(1)); |
| | | itemObject.put("content","否"); |
| | | jsonArray.add(itemObject); |
| | | object.put("items",jsonArray); |
| | | ExQuestion question=new ExQuestion(); |
| | | question.setQuestionType(3); |
| | | question.setBankId(16L); |
| | | question.setCompanyId(21L); |
| | | question.setAnswer(index==0?options.get(0):options.get(1)); |
| | | question.setTitle(title); |
| | | question.setPrivatize(0); |
| | | question.setContent(JSONObject.toJSONString(object)); |
| | | return question; |
| | | } |
| | | |
| | | public String randomInt(int answer){ |
| | | int a=random.nextInt(2000); |
| | | while (a==answer) { |
| | | a = random.nextInt(2000); |
| | | } |
| | | return a+""; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | <artifactId>fastjson2</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alibaba.fastjson2</groupId> |
| | | <artifactId>fastjson2-extension</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alibaba.fastjson2</groupId> |
| | | <artifactId>fastjson2-extension-spring5</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.ben-manes.caffeine</groupId> |
| | | <artifactId>caffeine</artifactId> |
| | | </dependency> |
| | |
| | | <artifactId>jaudiotagger</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>easyexcel</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.annotation; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 数据脱敏注解,方法含有该注解表示需要数据脱敏 |
| | | */ |
| | | @Target({ElementType.PARAMETER,ElementType.METHOD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface DataDesensitization { |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.annotation; |
| | | |
| | | import com.gkhy.exam.common.enums.SensitiveTypeEnum; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 数据脱敏注解,字段上含有该注解表示需要数据脱敏 |
| | | */ |
| | | @Target({ElementType.FIELD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface DataDesensitizationType { |
| | | /** |
| | | * 脱敏类型(规则) |
| | | * @return |
| | | */ |
| | | SensitiveTypeEnum type(); |
| | | } |
| | |
| | | @Bean |
| | | public FFmpeg fFmpeg() { |
| | | String path = System.getProperty("user.dir"); |
| | | if(path.endsWith("exam-admin")){ |
| | | path=path.replace("\\exam-admin",""); |
| | | } |
| | | if (isLinux()){ |
| | | path+="ffmpeg/ffmpeg-linux/ffmpeg"; |
| | | path+="/ffmpeg/ffmpeg-linux/ffmpeg"; |
| | | }else if (isWindows()){ |
| | | path+="/ffmpeg/ffmpeg-win/bin/ffmpeg.exe"; |
| | | } |
| | |
| | | public FFprobe fFprobe() { |
| | | String path = System.getProperty("user.dir"); |
| | | if (isLinux()){ |
| | | path+="ffmpeg/ffmpeg-linux/ffprobe"; |
| | | path+="/ffmpeg/ffmpeg-linux/ffprobe"; |
| | | }else if (isWindows()){ |
| | | path+="/ffmpeg/ffmpeg-win/bin/ffprobe.exe"; |
| | | } |
| | |
| | | */ |
| | | public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", |
| | | "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" }; |
| | | |
| | | |
| | | /** |
| | | * 考试通过 |
| | | */ |
| | | public static final Integer EXAM_PASS = 1; |
| | | /** |
| | | * 考试未通过 |
| | | */ |
| | | public static final Integer EXAM_UNPASS = 0; |
| | | } |
| | |
| | | { |
| | | PageDomain pageDomain = new PageDomain(); |
| | | pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); |
| | | pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); |
| | | Integer pageSize=Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10); |
| | | if(pageSize>100){ |
| | | pageSize=100; |
| | | } |
| | | pageDomain.setPageSize(pageSize); |
| | | pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); |
| | | pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); |
| | | pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); |
| | |
| | | private Long id; |
| | | |
| | | @NotBlank(message = "登录账号不能为空") |
| | | @Length(min = 2, message = "登录账号长度不正确") |
| | | @ApiModelProperty(value = "登录账号",required = true) |
| | | @TableField("username") |
| | | private String username; |
| | |
| | | private Long companyId; |
| | | |
| | | @NotBlank(message = "密码不能为空") |
| | | @Length(min = 2, message = "密码长度不正确") |
| | | @ApiModelProperty(value = "密码",required = true) |
| | | @TableField("password") |
| | | private String password; |
| | |
| | | @TableField(exist = false) |
| | | private String companyName; |
| | | |
| | | @ApiModelProperty("剩余课时(分)") |
| | | @TableField(exist = false) |
| | | private Long remainPeriod; |
| | | |
| | | @ApiModelProperty("父级账号名称") |
| | | @TableField(exist = false) |
| | | private String parentName; |
| | | |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.enums; |
| | | |
| | | /** |
| | | * 考试试卷状态 |
| | | */ |
| | | public enum PaperStudentStateEnum { |
| | | WAIT_EXAM(0, "待考试"), |
| | | WAIT_REVIEW(1, "待批改"), |
| | | DONE_REVIEW(2, "批改完成"); |
| | | |
| | | private final Integer code; |
| | | private final String info; |
| | | |
| | | PaperStudentStateEnum(Integer code, String info) |
| | | { |
| | | this.code = code; |
| | | this.info = info; |
| | | } |
| | | |
| | | public Integer getCode() |
| | | { |
| | | return code; |
| | | } |
| | | |
| | | public String getInfo() |
| | | { |
| | | return info; |
| | | } |
| | | } |
| | |
| | | public enum QuestionTypeEnum { |
| | | SINGLE(1, "单选题"), |
| | | MULTI(2, "多选题"), |
| | | JUDGE(3, "判断题"); |
| | | JUDGE(3, "判断题"), |
| | | EASY(4, "简答题"); |
| | | |
| | | private final Integer code; |
| | | private final String info; |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.enums; |
| | | |
| | | /** |
| | | * 脱敏类型枚举 |
| | | */ |
| | | public enum SensitiveTypeEnum { |
| | | CHINESE_NAME, |
| | | ID_CARD, |
| | | MOBILE_PHONE; |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.enums; |
| | | |
| | | /** |
| | | * 考试试卷状态 |
| | | */ |
| | | public enum StudentAnswerPassEnum { |
| | | ERROR(0, "错误"), |
| | | CORRECT(1, "正确"), |
| | | WAIT_REVIEW(2, "待批改"); |
| | | |
| | | private final Integer code; |
| | | private final String info; |
| | | |
| | | StudentAnswerPassEnum(Integer code, String info) |
| | | { |
| | | this.code = code; |
| | | this.info = info; |
| | | } |
| | | |
| | | public Integer getCode() |
| | | { |
| | | return code; |
| | | } |
| | | |
| | | public String getInfo() |
| | | { |
| | | return info; |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.excel; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | @Getter |
| | | @Setter |
| | | public class StudentExcelData { |
| | | @ExcelProperty("用户序号") |
| | | private String index; |
| | | @ExcelProperty("公司名称") |
| | | private String companyName; |
| | | |
| | | @ExcelProperty("姓名") |
| | | private String name; |
| | | |
| | | @ExcelProperty("用户性别") |
| | | private String sex; |
| | | |
| | | @ExcelProperty("身份证号") |
| | | private String idNo; |
| | | |
| | | @ExcelProperty("手机号码") |
| | | private String phone; |
| | | |
| | | @ExcelProperty("密码") |
| | | private String password; |
| | | |
| | | @ExcelProperty("部门名称") |
| | | private String deptName; |
| | | |
| | | @ExcelProperty("是否是部门级账号") |
| | | private String isDept; |
| | | |
| | | @ExcelProperty("车间名称") |
| | | private String workShopName; |
| | | |
| | | @ExcelProperty("是否是车间级账号") |
| | | private String isWork; |
| | | |
| | | @ExcelProperty("岗位") |
| | | private String post; |
| | | |
| | | @ExcelProperty("职务") |
| | | private String duty; |
| | | |
| | | @ExcelProperty("备注") |
| | | private String remark; |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.excel; |
| | | |
| | | import com.alibaba.excel.context.AnalysisContext; |
| | | import com.alibaba.excel.event.AnalysisEventListener; |
| | | |
| | | public class StudentExcelDataListener extends AnalysisEventListener<StudentExcelData> { |
| | | @Override |
| | | public void invoke(StudentExcelData studentExcelData, AnalysisContext analysisContext) { |
| | | System.out.println(studentExcelData); |
| | | } |
| | | |
| | | @Override |
| | | public void doAfterAllAnalysed(AnalysisContext analysisContext) { |
| | | //所有数据解析完成后的操作 |
| | | System.out.println("doAfterAllAnalysed"); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.filter; |
| | | |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import org.springframework.http.HttpMethod; |
| | | |
| | | import javax.servlet.*; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 防止XSS攻击的过滤器 |
| | | * |
| | | */ |
| | | public class XssFilter implements Filter |
| | | { |
| | | /** |
| | | * 排除链接 |
| | | */ |
| | | public List<String> excludes = new ArrayList<>(); |
| | | |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException |
| | | { |
| | | String tempExcludes = filterConfig.getInitParameter("excludes"); |
| | | if (StringUtils.isNotBlank(tempExcludes)) |
| | | { |
| | | String[] url = tempExcludes.split(","); |
| | | for (int i = 0; url != null && i < url.length; i++) |
| | | { |
| | | excludes.add(url[i]); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| | | throws IOException, ServletException |
| | | { |
| | | HttpServletRequest req = (HttpServletRequest) request; |
| | | HttpServletResponse resp = (HttpServletResponse) response; |
| | | if (handleExcludeURL(req, resp)) |
| | | { |
| | | chain.doFilter(request, response); |
| | | return; |
| | | } |
| | | XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); |
| | | chain.doFilter(xssRequest, response); |
| | | } |
| | | |
| | | private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) |
| | | { |
| | | String url = request.getServletPath(); |
| | | String method = request.getMethod(); |
| | | // GET DELETE 不过滤 |
| | | if (method == null || HttpMethod.GET.matches(method) || HttpMethod.DELETE.matches(method)) |
| | | { |
| | | return true; |
| | | } |
| | | return StringUtils.matches(url, excludes); |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() |
| | | { |
| | | |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.filter; |
| | | |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import com.gkhy.exam.common.utils.html.EscapeUtil; |
| | | import org.apache.commons.io.IOUtils; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.MediaType; |
| | | |
| | | import javax.servlet.ReadListener; |
| | | import javax.servlet.ServletInputStream; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletRequestWrapper; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * XSS过滤处理 |
| | | * |
| | | */ |
| | | public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper |
| | | { |
| | | /** |
| | | * @param request |
| | | */ |
| | | public XssHttpServletRequestWrapper(HttpServletRequest request) |
| | | { |
| | | super(request); |
| | | } |
| | | |
| | | @Override |
| | | public String[] getParameterValues(String name) |
| | | { |
| | | String[] values = super.getParameterValues(name); |
| | | if (values != null) |
| | | { |
| | | int length = values.length; |
| | | String[] escapesValues = new String[length]; |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | // 防xss攻击和过滤前后空格 |
| | | escapesValues[i] = EscapeUtil.clean(values[i]).trim(); |
| | | } |
| | | return escapesValues; |
| | | } |
| | | return super.getParameterValues(name); |
| | | } |
| | | |
| | | @Override |
| | | public ServletInputStream getInputStream() throws IOException |
| | | { |
| | | // 非json类型,直接返回 |
| | | if (!isJsonRequest()) |
| | | { |
| | | return super.getInputStream(); |
| | | } |
| | | |
| | | // 为空,直接返回 |
| | | String json = IOUtils.toString(super.getInputStream(), "utf-8"); |
| | | if (StringUtils.isBlank(json)) |
| | | { |
| | | return super.getInputStream(); |
| | | } |
| | | |
| | | // xss过滤 |
| | | json = EscapeUtil.clean(json).trim(); |
| | | byte[] jsonBytes = json.getBytes("utf-8"); |
| | | final ByteArrayInputStream bis = new ByteArrayInputStream(jsonBytes); |
| | | return new ServletInputStream() |
| | | { |
| | | @Override |
| | | public boolean isFinished() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public int available() throws IOException |
| | | { |
| | | return jsonBytes.length; |
| | | } |
| | | |
| | | @Override |
| | | public void setReadListener(ReadListener readListener) |
| | | { |
| | | } |
| | | |
| | | @Override |
| | | public int read() throws IOException |
| | | { |
| | | return bis.read(); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * 是否是Json请求 |
| | | * |
| | | * @param request |
| | | */ |
| | | public boolean isJsonRequest() |
| | | { |
| | | String header = super.getHeader(HttpHeaders.CONTENT_TYPE); |
| | | return StringUtils.startWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.utils; |
| | | |
| | | import cn.hutool.core.util.DesensitizedUtil; |
| | | import com.gkhy.exam.common.annotation.DataDesensitizationType; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.common.api.CommonResult; |
| | | |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Field; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 脱密工具类,(缺陷,不支持子类数据脱密) |
| | | */ |
| | | public class DesenseUtil { |
| | | |
| | | public static void assertResult(Object data) throws ClassNotFoundException, IllegalAccessException { |
| | | if(data instanceof CommonResult){ |
| | | CommonResult cr= (CommonResult) data; |
| | | Object obj=cr.getData(); |
| | | if(obj instanceof CommonPage){ |
| | | assetListResult(((CommonPage)obj).getList()); |
| | | }else if (obj instanceof List){ |
| | | assetListResult(obj); |
| | | }else{ |
| | | assetOneResult(obj); |
| | | } |
| | | } |
| | | } |
| | | public static void assetListResult(Object data) throws ClassNotFoundException, IllegalAccessException { |
| | | List list=(List) data; |
| | | for (Object record : list) { |
| | | Class<?> targetClass = Class.forName(record.getClass().getName()); |
| | | Field[] fields = targetClass.getDeclaredFields(); |
| | | reflexUpdateData(record, fields); |
| | | } |
| | | } |
| | | |
| | | public static void assetOneResult(Object data) throws IllegalAccessException, ClassNotFoundException { |
| | | Class<?> targetClass = Class.forName(data.getClass().getName()); |
| | | Field[] fields=targetClass.getDeclaredFields(); |
| | | reflexUpdateData(data,fields); |
| | | } |
| | | |
| | | public static void reflexUpdateData(Object data, Field[] fields) throws IllegalAccessException { |
| | | for (Field field : fields) { |
| | | field.setAccessible(true); |
| | | Object value = field.get(data); |
| | | if (!(value instanceof String)) { |
| | | continue; |
| | | } |
| | | String valueStr = (String) value; |
| | | Annotation[] annotations = field.getDeclaredAnnotations(); |
| | | for (Annotation annotation : annotations) { |
| | | if (annotation instanceof DataDesensitizationType) { |
| | | DataDesensitizationType targetAnnotation = (DataDesensitizationType) annotation; |
| | | switch (targetAnnotation.type()) { |
| | | case CHINESE_NAME: { |
| | | field.set(data, DesensitizedUtil.chineseName(valueStr)); |
| | | break; |
| | | } |
| | | case ID_CARD: { |
| | | field.set(data, DesensitizedUtil.idCardNum(valueStr, 3, 3)); |
| | | break; |
| | | } |
| | | case MOBILE_PHONE: { |
| | | field.set(data, DesensitizedUtil.mobilePhone(valueStr)); |
| | | break; |
| | | } |
| | | default: { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | String path = new File(System.getProperty("user.dir")).getAbsolutePath(); |
| | | path=path+filePath.getBasePath()+mainName; |
| | | if (!FileUtil.exist(path)) { |
| | | FileUtil.mkdir(path); |
| | | FileUtil.del(path); |
| | | } |
| | | FileUtil.mkdir(path); |
| | | String m3u8FileName = path+"/" + mainName + ".m3u8"; |
| | | |
| | | //下面这一串参数别乱动,经过调优的,1G视频大概需要10秒左右,如果是大佬随意改 |
| | |
| | | .setStrict(FFmpegBuilder.Strict.STRICT) |
| | | .setFormat("hls") |
| | | .setPreset("ultrafast") |
| | | .addExtraArgs("-vsync", "2", "-c:v", "copy", "-c:a", "copy", "-tune", "fastdecode", "-hls_wrap", "0", "-hls_time", "10", "-hls_list_size", "0", "-threads", "12") |
| | | // .addExtraArgs("-vsync", "2", "-c:v", "copy", "-c:a", "copy", "-tune", "fastdecode", "-hls_wrap", "0", "-hls_time", "10", "-hls_list_size", "0", "-threads", "12") #新版本hls_wrap参数不支持 |
| | | // .addExtraArgs("-vsync", "2", "-c:v", "copy", "-c:a", "copy", "-tune", "fastdecode", "-hls_flags", "delete_segments", "-hls_time", "10", "-hls_list_size", "0", "-threads", "12") |
| | | .addExtraArgs("-vsync", "2", "-c:v", "copy", "-c:a", "copy", "-tune", "fastdecode", "-hls_flags", "delete_segments", "-hls_time", "10", "-hls_list_size", "0", "-threads", "6") |
| | | .done(); |
| | | |
| | | FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe); |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取用户 |
| | | **/ |
| | | public static LoginUserDetails getLoginUserWithoutError() |
| | | { |
| | | try |
| | | { |
| | | return (LoginUserDetails) getAuthentication().getPrincipal(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取Authentication |
| | |
| | | { |
| | | try |
| | | { |
| | | response.setStatus(200); |
| | | response.setContentType("application/json"); |
| | | response.setCharacterEncoding("utf-8"); |
| | | response.getWriter().print(string); |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.utils.html; |
| | | |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | |
| | | /** |
| | | * 转义和反转义工具类 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class EscapeUtil |
| | | { |
| | | public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; |
| | | |
| | | private static final char[][] TEXT = new char[64][]; |
| | | |
| | | static |
| | | { |
| | | for (int i = 0; i < 64; i++) |
| | | { |
| | | TEXT[i] = new char[] { (char) i }; |
| | | } |
| | | |
| | | // special HTML characters |
| | | TEXT['\''] = "'".toCharArray(); // 单引号 |
| | | TEXT['"'] = """.toCharArray(); // 双引号 |
| | | TEXT['&'] = "&".toCharArray(); // &符 |
| | | TEXT['<'] = "<".toCharArray(); // 小于号 |
| | | TEXT['>'] = ">".toCharArray(); // 大于号 |
| | | } |
| | | |
| | | /** |
| | | * 转义文本中的HTML字符为安全的字符 |
| | | * |
| | | * @param text 被转义的文本 |
| | | * @return 转义后的文本 |
| | | */ |
| | | public static String escape(String text) |
| | | { |
| | | return encode(text); |
| | | } |
| | | |
| | | /** |
| | | * 还原被转义的HTML特殊字符 |
| | | * |
| | | * @param content 包含转义符的HTML内容 |
| | | * @return 转换后的字符串 |
| | | */ |
| | | public static String unescape(String content) |
| | | { |
| | | return decode(content); |
| | | } |
| | | |
| | | /** |
| | | * 清除所有HTML标签,但是不删除标签内的内容 |
| | | * |
| | | * @param content 文本 |
| | | * @return 清除标签后的文本 |
| | | */ |
| | | public static String clean(String content) |
| | | { |
| | | return new HTMLFilter().filter(content); |
| | | } |
| | | |
| | | /** |
| | | * Escape编码 |
| | | * |
| | | * @param text 被编码的文本 |
| | | * @return 编码后的字符 |
| | | */ |
| | | private static String encode(String text) |
| | | { |
| | | if (StringUtils.isEmpty(text)) |
| | | { |
| | | return StringUtils.EMPTY; |
| | | } |
| | | |
| | | final StringBuilder tmp = new StringBuilder(text.length() * 6); |
| | | char c; |
| | | for (int i = 0; i < text.length(); i++) |
| | | { |
| | | c = text.charAt(i); |
| | | if (c < 256) |
| | | { |
| | | tmp.append("%"); |
| | | if (c < 16) |
| | | { |
| | | tmp.append("0"); |
| | | } |
| | | tmp.append(Integer.toString(c, 16)); |
| | | } |
| | | else |
| | | { |
| | | tmp.append("%u"); |
| | | if (c <= 0xfff) |
| | | { |
| | | // issue#I49JU8@Gitee |
| | | tmp.append("0"); |
| | | } |
| | | tmp.append(Integer.toString(c, 16)); |
| | | } |
| | | } |
| | | return tmp.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Escape解码 |
| | | * |
| | | * @param content 被转义的内容 |
| | | * @return 解码后的字符串 |
| | | */ |
| | | public static String decode(String content) |
| | | { |
| | | if (StringUtils.isEmpty(content)) |
| | | { |
| | | return content; |
| | | } |
| | | |
| | | StringBuilder tmp = new StringBuilder(content.length()); |
| | | int lastPos = 0, pos = 0; |
| | | char ch; |
| | | while (lastPos < content.length()) |
| | | { |
| | | pos = content.indexOf("%", lastPos); |
| | | if (pos == lastPos) |
| | | { |
| | | if (content.charAt(pos + 1) == 'u') |
| | | { |
| | | ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); |
| | | tmp.append(ch); |
| | | lastPos = pos + 6; |
| | | } |
| | | else |
| | | { |
| | | ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); |
| | | tmp.append(ch); |
| | | lastPos = pos + 3; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (pos == -1) |
| | | { |
| | | tmp.append(content.substring(lastPos)); |
| | | lastPos = content.length(); |
| | | } |
| | | else |
| | | { |
| | | tmp.append(content.substring(lastPos, pos)); |
| | | lastPos = pos; |
| | | } |
| | | } |
| | | } |
| | | return tmp.toString(); |
| | | } |
| | | |
| | | public static void main(String[] args) |
| | | { |
| | | String html = "<script>alert(1);</script>"; |
| | | String escape = EscapeUtil.escape(html); |
| | | // String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>"; |
| | | // String html = "<123"; |
| | | // String html = "123>"; |
| | | System.out.println("clean: " + EscapeUtil.clean(html)); |
| | | System.out.println("escape: " + escape); |
| | | System.out.println("unescape: " + EscapeUtil.unescape(escape)); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.common.utils.html; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * HTML过滤器,用于去除XSS漏洞隐患。 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public final class HTMLFilter |
| | | { |
| | | /** |
| | | * regex flag union representing /si modifiers in php |
| | | **/ |
| | | private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; |
| | | private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL); |
| | | private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); |
| | | private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); |
| | | private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); |
| | | private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); |
| | | private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); |
| | | private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); |
| | | private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); |
| | | private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); |
| | | private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); |
| | | private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); |
| | | private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); |
| | | private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); |
| | | private static final Pattern P_END_ARROW = Pattern.compile("^>"); |
| | | private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); |
| | | private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); |
| | | private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); |
| | | private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); |
| | | private static final Pattern P_AMP = Pattern.compile("&"); |
| | | private static final Pattern P_QUOTE = Pattern.compile("\""); |
| | | private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); |
| | | private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); |
| | | private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); |
| | | |
| | | // @xxx could grow large... maybe use sesat's ReferenceMap |
| | | private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>(); |
| | | private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * set of allowed html elements, along with allowed attributes for each element |
| | | **/ |
| | | private final Map<String, List<String>> vAllowed; |
| | | /** |
| | | * counts of open tags for each (allowable) html element |
| | | **/ |
| | | private final Map<String, Integer> vTagCounts = new HashMap<>(); |
| | | |
| | | /** |
| | | * html elements which must always be self-closing (e.g. "<img />") |
| | | **/ |
| | | private final String[] vSelfClosingTags; |
| | | /** |
| | | * html elements which must always have separate opening and closing tags (e.g. "<b></b>") |
| | | **/ |
| | | private final String[] vNeedClosingTags; |
| | | /** |
| | | * set of disallowed html elements |
| | | **/ |
| | | private final String[] vDisallowed; |
| | | /** |
| | | * attributes which should be checked for valid protocols |
| | | **/ |
| | | private final String[] vProtocolAtts; |
| | | /** |
| | | * allowed protocols |
| | | **/ |
| | | private final String[] vAllowedProtocols; |
| | | /** |
| | | * tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") |
| | | **/ |
| | | private final String[] vRemoveBlanks; |
| | | /** |
| | | * entities allowed within html markup |
| | | **/ |
| | | private final String[] vAllowedEntities; |
| | | /** |
| | | * flag determining whether comments are allowed in input String. |
| | | */ |
| | | private final boolean stripComment; |
| | | private final boolean encodeQuotes; |
| | | /** |
| | | * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>" |
| | | * becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped. |
| | | */ |
| | | private final boolean alwaysMakeTags; |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | public HTMLFilter() |
| | | { |
| | | vAllowed = new HashMap<>(); |
| | | |
| | | final ArrayList<String> a_atts = new ArrayList<>(); |
| | | a_atts.add("href"); |
| | | a_atts.add("target"); |
| | | vAllowed.put("a", a_atts); |
| | | |
| | | final ArrayList<String> img_atts = new ArrayList<>(); |
| | | img_atts.add("src"); |
| | | img_atts.add("width"); |
| | | img_atts.add("height"); |
| | | img_atts.add("alt"); |
| | | vAllowed.put("img", img_atts); |
| | | |
| | | final ArrayList<String> no_atts = new ArrayList<>(); |
| | | vAllowed.put("b", no_atts); |
| | | vAllowed.put("strong", no_atts); |
| | | vAllowed.put("i", no_atts); |
| | | vAllowed.put("em", no_atts); |
| | | |
| | | vSelfClosingTags = new String[] { "img" }; |
| | | vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" }; |
| | | vDisallowed = new String[] {}; |
| | | vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp. |
| | | vProtocolAtts = new String[] { "src", "href" }; |
| | | vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" }; |
| | | vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" }; |
| | | stripComment = true; |
| | | encodeQuotes = true; |
| | | alwaysMakeTags = false; |
| | | } |
| | | |
| | | /** |
| | | * Map-parameter configurable constructor. |
| | | * |
| | | * @param conf map containing configuration. keys match field names. |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public HTMLFilter(final Map<String, Object> conf) |
| | | { |
| | | |
| | | assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; |
| | | assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; |
| | | assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; |
| | | assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; |
| | | assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; |
| | | assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; |
| | | assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; |
| | | assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; |
| | | |
| | | vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed")); |
| | | vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); |
| | | vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); |
| | | vDisallowed = (String[]) conf.get("vDisallowed"); |
| | | vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); |
| | | vProtocolAtts = (String[]) conf.get("vProtocolAtts"); |
| | | vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); |
| | | vAllowedEntities = (String[]) conf.get("vAllowedEntities"); |
| | | stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; |
| | | encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; |
| | | alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; |
| | | } |
| | | |
| | | private void reset() |
| | | { |
| | | vTagCounts.clear(); |
| | | } |
| | | |
| | | // --------------------------------------------------------------- |
| | | // my versions of some PHP library functions |
| | | public static String chr(final int decimal) |
| | | { |
| | | return String.valueOf((char) decimal); |
| | | } |
| | | |
| | | public static String htmlSpecialChars(final String s) |
| | | { |
| | | String result = s; |
| | | result = regexReplace(P_AMP, "&", result); |
| | | result = regexReplace(P_QUOTE, """, result); |
| | | result = regexReplace(P_LEFT_ARROW, "<", result); |
| | | result = regexReplace(P_RIGHT_ARROW, ">", result); |
| | | return result; |
| | | } |
| | | |
| | | // --------------------------------------------------------------- |
| | | |
| | | /** |
| | | * given a user submitted input String, filter out any invalid or restricted html. |
| | | * |
| | | * @param input text (i.e. submitted by a user) than may contain html |
| | | * @return "clean" version of input, with only valid, whitelisted html elements allowed |
| | | */ |
| | | public String filter(final String input) |
| | | { |
| | | reset(); |
| | | String s = input; |
| | | |
| | | s = escapeComments(s); |
| | | |
| | | s = balanceHTML(s); |
| | | |
| | | s = checkTags(s); |
| | | |
| | | s = processRemoveBlanks(s); |
| | | |
| | | // s = validateEntities(s); |
| | | |
| | | return s; |
| | | } |
| | | |
| | | public boolean isAlwaysMakeTags() |
| | | { |
| | | return alwaysMakeTags; |
| | | } |
| | | |
| | | public boolean isStripComments() |
| | | { |
| | | return stripComment; |
| | | } |
| | | |
| | | private String escapeComments(final String s) |
| | | { |
| | | final Matcher m = P_COMMENTS.matcher(s); |
| | | final StringBuffer buf = new StringBuffer(); |
| | | if (m.find()) |
| | | { |
| | | final String match = m.group(1); // (.*?) |
| | | m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->")); |
| | | } |
| | | m.appendTail(buf); |
| | | |
| | | return buf.toString(); |
| | | } |
| | | |
| | | private String balanceHTML(String s) |
| | | { |
| | | if (alwaysMakeTags) |
| | | { |
| | | // |
| | | // try and form html |
| | | // |
| | | s = regexReplace(P_END_ARROW, "", s); |
| | | // 不追加结束标签 |
| | | s = regexReplace(P_BODY_TO_END, "<$1>", s); |
| | | s = regexReplace(P_XML_CONTENT, "$1<$2", s); |
| | | |
| | | } |
| | | else |
| | | { |
| | | // |
| | | // escape stray brackets |
| | | // |
| | | s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); |
| | | s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); |
| | | |
| | | // |
| | | // the last regexp causes '<>' entities to appear |
| | | // (we need to do a lookahead assertion so that the last bracket can |
| | | // be used in the next pass of the regexp) |
| | | // |
| | | s = regexReplace(P_BOTH_ARROWS, "", s); |
| | | } |
| | | |
| | | return s; |
| | | } |
| | | |
| | | private String checkTags(String s) |
| | | { |
| | | Matcher m = P_TAGS.matcher(s); |
| | | |
| | | final StringBuffer buf = new StringBuffer(); |
| | | while (m.find()) |
| | | { |
| | | String replaceStr = m.group(1); |
| | | replaceStr = processTag(replaceStr); |
| | | m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); |
| | | } |
| | | m.appendTail(buf); |
| | | |
| | | // these get tallied in processTag |
| | | // (remember to reset before subsequent calls to filter method) |
| | | final StringBuilder sBuilder = new StringBuilder(buf.toString()); |
| | | for (String key : vTagCounts.keySet()) |
| | | { |
| | | for (int ii = 0; ii < vTagCounts.get(key); ii++) |
| | | { |
| | | sBuilder.append("</").append(key).append(">"); |
| | | } |
| | | } |
| | | s = sBuilder.toString(); |
| | | |
| | | return s; |
| | | } |
| | | |
| | | private String processRemoveBlanks(final String s) |
| | | { |
| | | String result = s; |
| | | for (String tag : vRemoveBlanks) |
| | | { |
| | | if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) |
| | | { |
| | | P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">")); |
| | | } |
| | | result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); |
| | | if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) |
| | | { |
| | | P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); |
| | | } |
| | | result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) |
| | | { |
| | | Matcher m = regex_pattern.matcher(s); |
| | | return m.replaceAll(replacement); |
| | | } |
| | | |
| | | private String processTag(final String s) |
| | | { |
| | | // ending tags |
| | | Matcher m = P_END_TAG.matcher(s); |
| | | if (m.find()) |
| | | { |
| | | final String name = m.group(1).toLowerCase(); |
| | | if (allowed(name)) |
| | | { |
| | | if (!inArray(name, vSelfClosingTags)) |
| | | { |
| | | if (vTagCounts.containsKey(name)) |
| | | { |
| | | vTagCounts.put(name, vTagCounts.get(name) - 1); |
| | | return "</" + name + ">"; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // starting tags |
| | | m = P_START_TAG.matcher(s); |
| | | if (m.find()) |
| | | { |
| | | final String name = m.group(1).toLowerCase(); |
| | | final String body = m.group(2); |
| | | String ending = m.group(3); |
| | | |
| | | // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); |
| | | if (allowed(name)) |
| | | { |
| | | final StringBuilder params = new StringBuilder(); |
| | | |
| | | final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); |
| | | final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); |
| | | final List<String> paramNames = new ArrayList<>(); |
| | | final List<String> paramValues = new ArrayList<>(); |
| | | while (m2.find()) |
| | | { |
| | | paramNames.add(m2.group(1)); // ([a-z0-9]+) |
| | | paramValues.add(m2.group(3)); // (.*?) |
| | | } |
| | | while (m3.find()) |
| | | { |
| | | paramNames.add(m3.group(1)); // ([a-z0-9]+) |
| | | paramValues.add(m3.group(3)); // ([^\"\\s']+) |
| | | } |
| | | |
| | | String paramName, paramValue; |
| | | for (int ii = 0; ii < paramNames.size(); ii++) |
| | | { |
| | | paramName = paramNames.get(ii).toLowerCase(); |
| | | paramValue = paramValues.get(ii); |
| | | |
| | | // debug( "paramName='" + paramName + "'" ); |
| | | // debug( "paramValue='" + paramValue + "'" ); |
| | | // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); |
| | | |
| | | if (allowedAttribute(name, paramName)) |
| | | { |
| | | if (inArray(paramName, vProtocolAtts)) |
| | | { |
| | | paramValue = processParamProtocol(paramValue); |
| | | } |
| | | params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\""); |
| | | } |
| | | } |
| | | |
| | | if (inArray(name, vSelfClosingTags)) |
| | | { |
| | | ending = " /"; |
| | | } |
| | | |
| | | if (inArray(name, vNeedClosingTags)) |
| | | { |
| | | ending = ""; |
| | | } |
| | | |
| | | if (ending == null || ending.length() < 1) |
| | | { |
| | | if (vTagCounts.containsKey(name)) |
| | | { |
| | | vTagCounts.put(name, vTagCounts.get(name) + 1); |
| | | } |
| | | else |
| | | { |
| | | vTagCounts.put(name, 1); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | ending = " /"; |
| | | } |
| | | return "<" + name + params + ending + ">"; |
| | | } |
| | | else |
| | | { |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | // comments |
| | | m = P_COMMENT.matcher(s); |
| | | if (!stripComment && m.find()) |
| | | { |
| | | return "<" + m.group() + ">"; |
| | | } |
| | | |
| | | return ""; |
| | | } |
| | | |
| | | private String processParamProtocol(String s) |
| | | { |
| | | s = decodeEntities(s); |
| | | final Matcher m = P_PROTOCOL.matcher(s); |
| | | if (m.find()) |
| | | { |
| | | final String protocol = m.group(1); |
| | | if (!inArray(protocol, vAllowedProtocols)) |
| | | { |
| | | // bad protocol, turn into local anchor link instead |
| | | s = "#" + s.substring(protocol.length() + 1); |
| | | if (s.startsWith("#//")) |
| | | { |
| | | s = "#" + s.substring(3); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return s; |
| | | } |
| | | |
| | | private String decodeEntities(String s) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | |
| | | Matcher m = P_ENTITY.matcher(s); |
| | | while (m.find()) |
| | | { |
| | | final String match = m.group(1); |
| | | final int decimal = Integer.decode(match).intValue(); |
| | | m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); |
| | | } |
| | | m.appendTail(buf); |
| | | s = buf.toString(); |
| | | |
| | | buf = new StringBuffer(); |
| | | m = P_ENTITY_UNICODE.matcher(s); |
| | | while (m.find()) |
| | | { |
| | | final String match = m.group(1); |
| | | final int decimal = Integer.valueOf(match, 16).intValue(); |
| | | m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); |
| | | } |
| | | m.appendTail(buf); |
| | | s = buf.toString(); |
| | | |
| | | buf = new StringBuffer(); |
| | | m = P_ENCODE.matcher(s); |
| | | while (m.find()) |
| | | { |
| | | final String match = m.group(1); |
| | | final int decimal = Integer.valueOf(match, 16).intValue(); |
| | | m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); |
| | | } |
| | | m.appendTail(buf); |
| | | s = buf.toString(); |
| | | |
| | | s = validateEntities(s); |
| | | return s; |
| | | } |
| | | |
| | | private String validateEntities(final String s) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | |
| | | // validate entities throughout the string |
| | | Matcher m = P_VALID_ENTITIES.matcher(s); |
| | | while (m.find()) |
| | | { |
| | | final String one = m.group(1); // ([^&;]*) |
| | | final String two = m.group(2); // (?=(;|&|$)) |
| | | m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); |
| | | } |
| | | m.appendTail(buf); |
| | | |
| | | return encodeQuotes(buf.toString()); |
| | | } |
| | | |
| | | private String encodeQuotes(final String s) |
| | | { |
| | | if (encodeQuotes) |
| | | { |
| | | StringBuffer buf = new StringBuffer(); |
| | | Matcher m = P_VALID_QUOTES.matcher(s); |
| | | while (m.find()) |
| | | { |
| | | final String one = m.group(1); // (>|^) |
| | | final String two = m.group(2); // ([^<]+?) |
| | | final String three = m.group(3); // (<|$) |
| | | // 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two) |
| | | m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three)); |
| | | } |
| | | m.appendTail(buf); |
| | | return buf.toString(); |
| | | } |
| | | else |
| | | { |
| | | return s; |
| | | } |
| | | } |
| | | |
| | | private String checkEntity(final String preamble, final String term) |
| | | { |
| | | |
| | | return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; |
| | | } |
| | | |
| | | private boolean isValidEntity(final String entity) |
| | | { |
| | | return inArray(entity, vAllowedEntities); |
| | | } |
| | | |
| | | private static boolean inArray(final String s, final String[] array) |
| | | { |
| | | for (String item : array) |
| | | { |
| | | if (item != null && item.equals(s)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private boolean allowed(final String name) |
| | | { |
| | | return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); |
| | | } |
| | | |
| | | private boolean allowedAttribute(final String name, final String paramName) |
| | | { |
| | | return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.framework.aspectj; |
| | | |
| | | import com.gkhy.exam.common.annotation.DataDesensitization; |
| | | import com.gkhy.exam.common.utils.DesenseUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.aspectj.lang.ProceedingJoinPoint; |
| | | import org.aspectj.lang.annotation.Around; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Pointcut; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * 数据脱密 |
| | | */ |
| | | @Aspect |
| | | @Component |
| | | @Slf4j |
| | | public class DataDesensitizationAspect { |
| | | @Autowired |
| | | private HttpServletRequest request; |
| | | @Pointcut("@annotation(com.gkhy.exam.common.annotation.DataDesensitization)") |
| | | public void pointcut(){} |
| | | |
| | | @Around("pointcut()") |
| | | public Object doaround(ProceedingJoinPoint point) throws Throwable { |
| | | Object object=point.proceed(); |
| | | String uri = request.getRequestURI(); |
| | | // if(!uri.startsWith("/app/api")){ |
| | | // return object; |
| | | // } |
| | | MethodSignature signature = (MethodSignature) point.getSignature(); |
| | | Method method = signature.getMethod(); |
| | | if(!method.isAnnotationPresent(DataDesensitization.class)){ |
| | | return object; |
| | | } |
| | | DesenseUtil.assertResult(object); |
| | | return object; |
| | | } |
| | | } |
| | |
| | | package com.gkhy.exam.framework.aspectj; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.URLUtil; |
| | | import cn.hutool.extra.servlet.ServletUtil; |
| | | import cn.hutool.json.JSONObject; |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.gkhy.exam.common.annotation.Log; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.BusinessStatus; |
| | | import com.gkhy.exam.common.filter.PropertyPreExcludeFilter; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.common.utils.ServletUtils; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import com.gkhy.exam.system.domain.SysOperLog; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.ArrayUtils; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.AfterReturning; |
| | | import org.aspectj.lang.ProceedingJoinPoint; |
| | | import org.aspectj.lang.Signature; |
| | | import org.aspectj.lang.annotation.AfterThrowing; |
| | | import org.aspectj.lang.annotation.Around; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.aspectj.lang.annotation.Pointcut; |
| | | import org.aspectj.lang.reflect.MethodSignature; |
| | | import org.springframework.core.NamedThreadLocal; |
| | | import org.springframework.http.HttpMethod; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.validation.BindingResult; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestParam; |
| | | import org.springframework.web.context.request.RequestContextHolder; |
| | | import org.springframework.web.context.request.ServletRequestAttributes; |
| | | |
| | | import javax.servlet.ServletRequest; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.lang.reflect.Method; |
| | | import java.lang.reflect.Parameter; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | |
| | | public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; |
| | | private static final ThreadLocal<Long> TIME_THREADLOCAL=new NamedThreadLocal<>("Cost Time"); |
| | | |
| | | /** |
| | | * 处理请求前执行 |
| | | * @param joinPoint |
| | | * @param controllerLog |
| | | */ |
| | | @Before(value = "@annotation(controllerLog)") |
| | | public void doBefore(JoinPoint joinPoint, Log controllerLog){ |
| | | TIME_THREADLOCAL.set(System.currentTimeMillis()); |
| | | @Pointcut("execution(public * com.gkhy.exam.*.controller..*.*(..))") |
| | | public void logPointCut(){ |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 处理完请求后执行 |
| | | * @param joinPoint |
| | | * @param controllerLog |
| | | * @param jsonResult |
| | | * |
| | | * @param joinPoint 切点 |
| | | */ |
| | | @AfterReturning(pointcut = "@annotation(controllerLog)",returning ="jsonResult" ) |
| | | public void doAfterReturning(JoinPoint joinPoint,Log controllerLog,Object jsonResult){ |
| | | handleLog(joinPoint,controllerLog,null,jsonResult); |
| | | @Around("logPointCut()") |
| | | public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{ |
| | | SysUser user= SecurityUtils.getLoginUserWithoutError()!=null?SecurityUtils.getLoginUserWithoutError().getUser():null; |
| | | long startTime = System.currentTimeMillis(); |
| | | //获取当前请求对象 |
| | | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
| | | HttpServletRequest request = attributes.getRequest(); |
| | | Signature signature = joinPoint.getSignature(); |
| | | MethodSignature methodSignature = (MethodSignature) signature; |
| | | Method method = methodSignature.getMethod(); |
| | | StringBuffer requestURL = request.getRequestURL(); |
| | | JSONObject webLog = new JSONObject(); |
| | | String urlStr = request.getRequestURL().toString(); |
| | | webLog.put("basePath", StringUtils.removeSuffix(urlStr, URLUtil.url(urlStr).getPath())); |
| | | webLog.put("ip", ServletUtil.getClientIP(request,null)); |
| | | webLog.put("method",request.getMethod()); |
| | | Object params=getParameter(method, joinPoint.getArgs()); |
| | | |
| | | webLog.put("parameter",params); |
| | | webLog.put("uri",request.getRequestURI()); |
| | | webLog.put("url",requestURL.toString()); |
| | | if(user!=null) { |
| | | webLog.put("userName", user.getName()); |
| | | } |
| | | log.info(webLog.toString()); |
| | | Object result = joinPoint.proceed(); |
| | | if (result == null) { |
| | | //如果切到了 没有返回类型的void方法,这里直接返回 |
| | | return null; |
| | | } |
| | | long endTime = System.currentTimeMillis(); |
| | | webLog.put("result",StringUtils.sub(JSON.toJSONString(result),0,2000)); |
| | | webLog.put("spendTime",endTime - startTime); |
| | | log.info(webLog.toString()); |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 拦截异常操作 |
| | | * @param joinPoint |
| | | * @param controllerLog |
| | | * @param e |
| | | */ |
| | | @AfterThrowing(value = "@annotation(controllerLog)",throwing = "e") |
| | | public void doAfterThrowing(JoinPoint joinPoint,Log controllerLog,Exception e){ |
| | | handleLog(joinPoint,controllerLog,e,null); |
| | | @AfterThrowing(value = "logPointCut()", throwing = "e") |
| | | public void doAfterThrowing(JoinPoint joinPoint,Exception e){ |
| | | //获取当前请求对象 |
| | | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
| | | HttpServletRequest request = attributes.getRequest(); |
| | | String urlStr = request.getRequestURL().toString(); |
| | | log.error("@AfterThrowing异常通知:url={},出错了error_message={}", urlStr,e.getMessage()); |
| | | } |
| | | |
| | | protected void handleLog(final JoinPoint joinPoint,Log controllerLog,final Exception e,Object jsonResult){ |
| | | try{ |
| | | HttpServletRequest request= ServletUtils.getRequest(); |
| | | SysUser user= SecurityUtils.getLoginUser().getUser(); |
| | | SysOperLog operLog=new SysOperLog(); |
| | | operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); |
| | | |
| | | String ip= cn.hutool.extra.servlet.ServletUtil.getClientIP(request); |
| | | operLog.setOperIp(ip); |
| | | operLog.setOperUrl(StringUtils.sub(request.getRequestURI(),0,255)); |
| | | if(user!=null){ |
| | | operLog.setOperName(user.getUsername()); |
| | | /** |
| | | * 根据方法和传入的参数获取请求参数 |
| | | */ |
| | | private Object getParameter(Method method, Object[] args) { |
| | | List<Object> argList = new ArrayList<>(); |
| | | Parameter[] parameters = method.getParameters(); |
| | | for (int i = 0; i < parameters.length; i++) { |
| | | //将RequestBody注解修饰的参数作为请求参数 |
| | | RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); |
| | | if (requestBody != null) { |
| | | argList.add(args[i]); |
| | | } |
| | | if(e!=null){ |
| | | operLog.setStatus(BusinessStatus.FAIL.ordinal()); |
| | | operLog.setErrorMsg(StringUtils.sub(e.getMessage(),0,2000)); |
| | | } |
| | | String className=joinPoint.getTarget().getClass().getName(); |
| | | String methodName=joinPoint.getSignature().getName(); |
| | | operLog.setMethod(className+"."+methodName+"()"); |
| | | operLog.setRequestMethod(request.getMethod()); |
| | | getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); |
| | | operLog.setCostTime(System.currentTimeMillis()-TIME_THREADLOCAL.get()); |
| | | log.info(JSON.toJSONString(operLog)); |
| | | // AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); |
| | | }catch (Exception exp){ |
| | | log.error("异常信息:{}",exp.getMessage()); |
| | | exp.printStackTrace(); |
| | | }finally { |
| | | TIME_THREADLOCAL.remove(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取注解中对方法的描述信息 用于Controller层注解 |
| | | * |
| | | * @param log 日志 |
| | | * @param operLog 操作日志 |
| | | * @throws Exception |
| | | */ |
| | | public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception |
| | | { |
| | | // 设置action动作 |
| | | operLog.setBusinessType(log.businessType().ordinal()); |
| | | // 设置标题 |
| | | operLog.setTitle(log.title()); |
| | | // 设置操作人类别 |
| | | operLog.setOperatorType(log.operatorType().ordinal()); |
| | | // 是否需要保存request,参数和值 |
| | | if (log.isSaveRequestData()) |
| | | { |
| | | // 获取参数的信息,传入到数据库中。 |
| | | setRequestValue(joinPoint, operLog, log.excludeParamNames()); |
| | | } |
| | | // 是否需要保存response,参数和值 |
| | | if (log.isSaveResponseData() && ObjectUtil.isNotNull(jsonResult)) |
| | | { |
| | | operLog.setJsonResult(StringUtils.sub(JSON.toJSONString(jsonResult), 0, 2000)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取请求的参数,放到log中 |
| | | * |
| | | * @param operLog 操作日志 |
| | | * @throws Exception 异常 |
| | | */ |
| | | private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception |
| | | { |
| | | Map<?, ?> paramsMap = getParamMap(ServletUtils.getRequest()); |
| | | String requestMethod = operLog.getRequestMethod(); |
| | | if (ObjectUtil.isEmpty(paramsMap) |
| | | && (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))) |
| | | { |
| | | String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); |
| | | operLog.setOperParam(StringUtils.sub(params, 0, 2000)); |
| | | } |
| | | else{ |
| | | operLog.setOperParam(StringUtils.sub(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获得所有请求参数 |
| | | * |
| | | * @param request 请求对象{@link ServletRequest} |
| | | * @return Map |
| | | */ |
| | | private Map<String, String> getParamMap(ServletRequest request) |
| | | { |
| | | Map<String, String> params = new HashMap<>(); |
| | | Map<String, String[]> map = request.getParameterMap(); |
| | | for (Map.Entry<String, String[]> entry : Collections.unmodifiableMap(map).entrySet()) |
| | | { |
| | | params.put(entry.getKey(), StringUtils.join(",",entry.getValue())); |
| | | } |
| | | return params; |
| | | } |
| | | |
| | | /** |
| | | * 参数拼装 |
| | | */ |
| | | private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) |
| | | { |
| | | String params = ""; |
| | | if (paramsArray != null && paramsArray.length > 0) |
| | | { |
| | | for (Object o : paramsArray) |
| | | { |
| | | if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) |
| | | { |
| | | try |
| | | { |
| | | String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); |
| | | params += jsonObj.toString() + " "; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } |
| | | //将RequestParam注解修饰的参数作为请求参数 |
| | | RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); |
| | | if (requestParam != null) { |
| | | Map<String, Object> map = new HashMap<>(); |
| | | String key = parameters[i].getName(); |
| | | if (StringUtils.isNotEmpty(requestParam.value())) { |
| | | key = requestParam.value(); |
| | | } |
| | | map.put(key, args[i]); |
| | | argList.add(map); |
| | | } |
| | | } |
| | | return params.trim(); |
| | | } |
| | | |
| | | /** |
| | | * 忽略敏感属性 |
| | | */ |
| | | public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames) |
| | | { |
| | | return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames)); |
| | | } |
| | | |
| | | /** |
| | | * 判断是否需要过滤的对象。 |
| | | * |
| | | * @param o 对象信息。 |
| | | * @return 如果是需要过滤的对象,则返回true;否则返回false。 |
| | | */ |
| | | @SuppressWarnings("rawtypes") |
| | | public boolean isFilterObject(final Object o) |
| | | { |
| | | Class<?> clazz = o.getClass(); |
| | | if (clazz.isArray()) |
| | | { |
| | | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); |
| | | if (argList.size() == 0) { |
| | | return null; |
| | | } else if (argList.size() == 1) { |
| | | return argList.get(0); |
| | | } else { |
| | | return argList; |
| | | } |
| | | else if (Collection.class.isAssignableFrom(clazz)) |
| | | { |
| | | Collection collection = (Collection) o; |
| | | for (Object value : collection) |
| | | { |
| | | return value instanceof MultipartFile; |
| | | } |
| | | } |
| | | else if (Map.class.isAssignableFrom(clazz)) |
| | | { |
| | | Map map = (Map) o; |
| | | for (Object value : map.entrySet()) |
| | | { |
| | | Map.Entry entry = (Map.Entry) value; |
| | | return entry.getValue() instanceof MultipartFile; |
| | | } |
| | | } |
| | | return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse |
| | | || o instanceof BindingResult; |
| | | } |
| | | |
| | | |
| | |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Conditional; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.context.annotation.EnableAspectJAutoProxy; |
| | | import org.springframework.web.cors.CorsConfiguration; |
| | |
| | | final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); |
| | | final CorsConfiguration corsConfiguration = new CorsConfiguration(); |
| | | //是否允许请求带有验证信息 |
| | | // corsConfiguration.setAllowCredentials(true); |
| | | // corsConfiguration.setAllowedOrigins(Arrays.asList("*")); |
| | | // corsConfiguration.setAllowedMethods(Arrays.asList("*")); |
| | | // corsConfiguration.setAllowCredentials(true); |
| | | // corsConfiguration.setMaxAge(168000L); |
| | | |
| | | //是否允许请求带有验证信息 |
| | | corsConfiguration.setAllowCredentials(true); |
| | | // 允许访问的客户端域名 |
| | | corsConfiguration.addAllowedOriginPattern("*"); |
| | |
| | | corsConfiguration.addAllowedHeader("*"); |
| | | // 允许访问的方法名,GET POST等 |
| | | corsConfiguration.addAllowedMethod("*"); |
| | | corsConfiguration.setMaxAge(168000L); |
| | | urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); |
| | | return new CorsFilter(urlBasedCorsConfigurationSource); |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.framework.config; |
| | | |
| | | import com.alibaba.fastjson2.JSONWriter; |
| | | import com.alibaba.fastjson2.support.config.FastJsonConfig; |
| | | import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.http.converter.HttpMessageConverter; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @Configuration |
| | | public class FastjsonConfig implements WebMvcConfigurer { |
| | | |
| | | @Override |
| | | public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { |
| | | FastJsonConfig config=new FastJsonConfig(); |
| | | config.setDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | config.setCharset(StandardCharsets.UTF_8); |
| | | config.setWriterFeatures( |
| | | JSONWriter.Feature.WriteNullListAsEmpty, |
| | | //json格式化 |
| | | JSONWriter.Feature.PrettyFormat, |
| | | //输出map中value为null的数据 |
| | | JSONWriter.Feature.WriteMapNullValue, |
| | | //输出boolean 为 false |
| | | JSONWriter.Feature.WriteNullBooleanAsFalse, |
| | | //输出list 为 [] |
| | | JSONWriter.Feature.WriteNullListAsEmpty, |
| | | //输出number 为 0 |
| | | JSONWriter.Feature.WriteNullNumberAsZero, |
| | | //输出字符串 为 "" |
| | | JSONWriter.Feature.WriteNullStringAsEmpty, |
| | | //对map进行排序 |
| | | JSONWriter.Feature.MapSortField |
| | | ); |
| | | // 2. 添加fastjson转换器 |
| | | FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); |
| | | List<MediaType> supportedMediaTypes = new ArrayList<>(); |
| | | |
| | | // 3. 添加支持的媒体类型 |
| | | supportedMediaTypes.add(MediaType.APPLICATION_JSON); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_PDF); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML); |
| | | supportedMediaTypes.add(MediaType.APPLICATION_XML); |
| | | supportedMediaTypes.add(MediaType.IMAGE_GIF); |
| | | supportedMediaTypes.add(MediaType.IMAGE_JPEG); |
| | | supportedMediaTypes.add(MediaType.IMAGE_PNG); |
| | | supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM); |
| | | supportedMediaTypes.add(MediaType.TEXT_HTML); |
| | | supportedMediaTypes.add(MediaType.TEXT_MARKDOWN); |
| | | supportedMediaTypes.add(MediaType.TEXT_PLAIN); |
| | | supportedMediaTypes.add(MediaType.TEXT_XML); |
| | | |
| | | converter.setSupportedMediaTypes(supportedMediaTypes); |
| | | |
| | | //4 将convert添加到converters |
| | | converter.setFastJsonConfig(config); |
| | | converters.add(0,converter); |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.framework.config; |
| | | |
| | | |
| | | import com.gkhy.exam.common.filter.RepeatableFilter; |
| | | import com.gkhy.exam.common.filter.XssFilter; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import javax.servlet.DispatcherType; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Filter配置 |
| | | * |
| | | */ |
| | | @Configuration |
| | | public class FilterConfig |
| | | { |
| | | @Value("${xss.excludes}") |
| | | private String excludes; |
| | | |
| | | @Value("${xss.urlPatterns}") |
| | | private String urlPatterns; |
| | | |
| | | @SuppressWarnings({ "rawtypes", "unchecked" }) |
| | | @Bean |
| | | @ConditionalOnProperty(value = "xss.enabled", havingValue = "true") |
| | | public FilterRegistrationBean xssFilterRegistration() |
| | | { |
| | | FilterRegistrationBean registration = new FilterRegistrationBean(); |
| | | registration.setDispatcherTypes(DispatcherType.REQUEST); |
| | | registration.setFilter(new XssFilter()); |
| | | StringUtils.split(urlPatterns,10); |
| | | registration.addUrlPatterns(String.join(",",StringUtils.split(urlPatterns, ","))); |
| | | registration.setName("xssFilter"); |
| | | registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); |
| | | Map<String, String> initParameters = new HashMap<String, String>(); |
| | | initParameters.put("excludes", excludes); |
| | | registration.setInitParameters(initParameters); |
| | | return registration; |
| | | } |
| | | |
| | | /** |
| | | * 重复请求校验 |
| | | * @return |
| | | */ |
| | | @SuppressWarnings({ "rawtypes", "unchecked" }) |
| | | @Bean |
| | | public FilterRegistrationBean someFilterRegistration() |
| | | { |
| | | FilterRegistrationBean registration = new FilterRegistrationBean(); |
| | | registration.setFilter(new RepeatableFilter()); |
| | | registration.addUrlPatterns("/*"); |
| | | registration.setName("repeatableFilter"); |
| | | registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); |
| | | return registration; |
| | | } |
| | | |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.framework.event; |
| | | |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import org.springframework.context.ApplicationEvent; |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public class PaperStudentEvent extends ApplicationEvent { |
| | | private ExPaperStudent paperStudent; |
| | | |
| | | public PaperStudentEvent(ExPaperStudent paperStudent) { |
| | | super(paperStudent); |
| | | this.paperStudent=paperStudent; |
| | | } |
| | | } |
对比新文件 |
| | |
| | | package com.gkhy.exam.framework.event; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.gkhy.exam.common.enums.PaperStudentStateEnum; |
| | | import com.gkhy.exam.common.enums.QuestionTypeEnum; |
| | | import com.gkhy.exam.common.enums.StudentAnswerPassEnum; |
| | | import com.gkhy.exam.system.domain.ExExamPaper; |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.domain.ExQuestion; |
| | | import com.gkhy.exam.system.domain.ExStudentAnswer; |
| | | import com.gkhy.exam.system.service.ExExamPaperService; |
| | | import com.gkhy.exam.system.service.ExPaperStudentService; |
| | | import com.gkhy.exam.system.service.ExQuestionService; |
| | | import com.gkhy.exam.system.service.ExStudentAnswerService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.event.EventListener; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Optional; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Slf4j |
| | | @Component |
| | | public class PaperStudentListener { |
| | | @Autowired |
| | | private ExExamPaperService examPaperService; |
| | | @Autowired |
| | | private ExStudentAnswerService studentAnswerService; |
| | | @Autowired |
| | | private ExQuestionService questionService; |
| | | @Autowired |
| | | private ExPaperStudentService paperStudentService; |
| | | |
| | | @EventListener |
| | | public void PaperStudentListener(ExPaperStudent paperStudent){ |
| | | ExExamPaper examPaper=examPaperService.getById(paperStudent.getPaperId()); |
| | | List<ExStudentAnswer> studentAnswerList=studentAnswerService.list(Wrappers.<ExStudentAnswer>lambdaQuery() |
| | | .eq(true,ExStudentAnswer::getStudentId,paperStudent.getStudentId()) |
| | | .eq(true,ExStudentAnswer::getPaperId,paperStudent.getPaperId())); |
| | | List<ExQuestion> questionList=questionService.selectQuestionByPaperId(paperStudent.getPaperId()); |
| | | Map<Long, ExQuestion> collectMap = questionList.stream().collect(Collectors.toMap(ExQuestion::getId, k -> k)); |
| | | Integer totalScore=0; |
| | | for(ExStudentAnswer studentAnswer:studentAnswerList){ |
| | | ExQuestion question=collectMap.get(studentAnswer.getQuestionId()); |
| | | if(question.getQuestionType().equals(QuestionTypeEnum.EASY.getCode())){ |
| | | studentAnswer.setPassed(StudentAnswerPassEnum.WAIT_REVIEW.getCode()); |
| | | }else{ |
| | | if(studentAnswer.getAnswer().equals(question.getAnswer())){ |
| | | studentAnswer.setPassed(StudentAnswerPassEnum.CORRECT.getCode()); |
| | | studentAnswer.setScore(getScore(examPaper,question.getQuestionType())); |
| | | totalScore=totalScore+studentAnswer.getScore(); |
| | | }else{ |
| | | studentAnswer.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | studentAnswer.setScore(0); |
| | | } |
| | | } |
| | | } |
| | | studentAnswerService.updateBatchById(studentAnswerList); |
| | | if(Optional.ofNullable(examPaper.getEasyNum()).orElse(0)<=0){ |
| | | //没有简答题,直接批改试卷 |
| | | paperStudent.setScore(totalScore); |
| | | paperStudent.setState(PaperStudentStateEnum.DONE_REVIEW.getCode()); |
| | | paperStudentService.updateById(paperStudent); |
| | | } |
| | | } |
| | | |
| | | private Integer getScore(ExExamPaper examPaper,Integer questionType){ |
| | | if(questionType.equals(QuestionTypeEnum.SINGLE.getCode())){ |
| | | return examPaper.getSingleScore(); |
| | | }else if(questionType.equals(QuestionTypeEnum.MULTI.getCode())){ |
| | | return examPaper.getMultiScore(); |
| | | }else if(questionType.equals(QuestionTypeEnum.JUDGE.getCode())){ |
| | | return examPaper.getJudgeScore(); |
| | | }else if(questionType.equals(QuestionTypeEnum.EASY.getCode())){ |
| | | return examPaper.getEasyScore(); |
| | | } |
| | | return 0; |
| | | } |
| | | } |
| | |
| | | public CommonResult handleRuntimeException(RuntimeException ex, HttpServletRequest request) |
| | | { |
| | | writeExceptionLogFile(ex); |
| | | return CommonResult.failed(ex.getMessage()); |
| | | return CommonResult.failed("内部服务异常"); |
| | | } |
| | | |
| | | /** |
对比新文件 |
| | |
| | | package com.gkhy.exam.framework.job; |
| | | |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.mapper.ExPaperStudentMapper; |
| | | import com.gkhy.exam.system.service.ExPaperStudentService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneOffset; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 考生考试超时处理job |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class PaperStudentJob { |
| | | @Autowired |
| | | private ExPaperStudentMapper paperStudentMapper; |
| | | @Autowired |
| | | private ExPaperStudentService paperStudentService; |
| | | |
| | | /** |
| | | * 建议:每1小时秒执行一次 |
| | | */ |
| | | @Scheduled(cron = "0 */10 * * * ?") |
| | | public void doprogress() { |
| | | try { |
| | | int pageIndex = 1; |
| | | int pageSize = 20; |
| | | while (true) { |
| | | List<ExPaperStudent> paperStudentList = paperStudentMapper.selectNoCompleteStudent((pageIndex - 1) * pageSize, pageSize); |
| | | if (paperStudentList.isEmpty()) { |
| | | break; |
| | | } |
| | | for (ExPaperStudent paperStudent : paperStudentList) { |
| | | handle(paperStudent); |
| | | } |
| | | if (paperStudentList.size() < pageSize) { |
| | | break; |
| | | } |
| | | pageIndex = pageIndex + 1; |
| | | } |
| | | }catch (Exception e){ |
| | | log.error("PaperStudentJob doprogress error:{}",e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | public void handle(ExPaperStudent pStudent){ |
| | | Long currentDateTime = System.currentTimeMillis(); |
| | | LocalDateTime deadline = pStudent.getExamPaper().getDeadline(); |
| | | if (currentDateTime - deadline.toInstant(ZoneOffset.of("+8")).toEpochMilli() < 0) { |
| | | if(pStudent.getExamPaper().getLimited()==1){ |
| | | if (pStudent.getStartTime() == null) { |
| | | return; |
| | | } |
| | | if(currentDateTime - pStudent.getStartTime() < pStudent.getExamPaper().getLimitTime() * 60 * 1000) { |
| | | return; |
| | | } |
| | | }else { |
| | | return; |
| | | } |
| | | } |
| | | paperStudentService.handlePaperData(pStudent); |
| | | } |
| | | |
| | | } |
| | |
| | | import com.gkhy.exam.system.domain.ExStudentStudy; |
| | | import com.gkhy.exam.system.mapper.ExResourceMapper; |
| | | import com.gkhy.exam.system.mapper.ExStudentStudyMapper; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | /** |
| | | * 学习进度job |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class UserStudyJob { |
| | | @Autowired |
| | |
| | | * 建议:每10秒执行一次 |
| | | */ |
| | | @Scheduled(cron = "*/10 * * * * ?") |
| | | public void progress(){ |
| | | Set<String> keys = redisUtils.keys(CacheConstant.STUDY_PROCESS_KEY + "*"); |
| | | if(ObjectUtil.isNotEmpty(keys)){ |
| | | for(String key:keys){ |
| | | ExStudentStudy studentStudy = (ExStudentStudy) redisUtils.get(key); |
| | | ExResource resource=resourceMapper.selectById(studentStudy.getResourceId()); |
| | | if(ResourceTypeEnum.VIDEO.getCode().equals(resource.getResourceType())||ResourceTypeEnum.AUDIO.getCode().equals(resource.getResourceType())){ |
| | | studentStudy.setProgress(new BigDecimal(studentStudy.getCurrentDuration()).divide(new BigDecimal(resource.getResourceLength()),BigDecimal.ROUND_CEILING).multiply(BigDecimal.valueOf(100))); |
| | | }else{ |
| | | studentStudy.setProgress(BigDecimal.valueOf(studentStudy.getCurrentPage()).divide(BigDecimal.valueOf(resource.getDocPage()).multiply(BigDecimal.valueOf(100)))); |
| | | |
| | | public void doprogress(){ |
| | | try { |
| | | Set<String> keys = redisUtils.keys(CacheConstant.STUDY_PROCESS_KEY + "*"); |
| | | if (ObjectUtil.isNotEmpty(keys)) { |
| | | for (String key : keys) { |
| | | ExStudentStudy studentStudy = (ExStudentStudy) redisUtils.get(key); |
| | | ExResource resource = resourceMapper.selectById(studentStudy.getResourceId()); |
| | | if (ResourceTypeEnum.VIDEO.getCode().equals(resource.getResourceType()) || ResourceTypeEnum.AUDIO.getCode().equals(resource.getResourceType())) { |
| | | studentStudy.setProgress(new BigDecimal(studentStudy.getCurrentDuration()).divide(new BigDecimal(resource.getResourceLength()), BigDecimal.ROUND_CEILING).multiply(BigDecimal.valueOf(100))); |
| | | } else { |
| | | studentStudy.setProgress(BigDecimal.valueOf(studentStudy.getCurrentPage()).divide(BigDecimal.valueOf(resource.getDocPage()).multiply(BigDecimal.valueOf(100)))); |
| | | } |
| | | studentStudyMapper.updateById(studentStudy); |
| | | redisUtils.del(key); |
| | | } |
| | | studentStudyMapper.updateById(studentStudy); |
| | | redisUtils.del(key); |
| | | } |
| | | }catch (Exception e){ |
| | | log.error("UserStudyJob doprogress error:{}",e.getMessage()); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 统计学员学习总进度 |
| | | */ |
| | | public void staticProgress(){ |
| | | |
| | | } |
| | | } |
| | |
| | | permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll()); |
| | | |
| | | httpSecurity |
| | | .cors().and() |
| | | // CSRF禁用,因为不使用session |
| | | .csrf().disable() |
| | | // 禁用HTTP响应标头 |
| | |
| | | // 过滤请求 |
| | | .authorizeRequests() |
| | | // 对于登录login 注册register 验证码captchaImage 允许匿名访问 |
| | | .antMatchers("/**/login", "/register", "/system/captcha/captchaImage").permitAll() |
| | | .antMatchers("/**/login", "/register", "/system/captcha/captchaImage","/system/common/importExcel").permitAll() |
| | | // 静态资源,可匿名访问 |
| | | .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**","/**/favicon.ico","/**/images/**").permitAll() |
| | | .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() |
| | |
| | | httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 强散列哈希加密实现 |
| | | */ |
| | |
| | | { |
| | | String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); |
| | | log.error(msg); |
| | | ServletUtils.renderString(response, JSON.toJSONString(CommonResult.failed(ResultCode.FORBIDDEN,msg))); |
| | | ServletUtils.renderString(response, JSON.toJSONString(CommonResult.failed(ResultCode.UNAUTHORIZED,msg))); |
| | | |
| | | } |
| | | } |
| | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Component |
| | |
| | | private TokenService tokenService; |
| | | @Autowired |
| | | private ExStudentService studentService; |
| | | @Autowired |
| | | private HttpServletRequest request; |
| | | |
| | | |
| | | |
| | |
| | | authentication = authenticationManager.authenticate(authenticationToken); |
| | | LoginUserDetails loginUserDetails= (LoginUserDetails) authentication.getPrincipal(); |
| | | passwordService.validate(loginUserDetails.getUser(),password); |
| | | AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_SUCCESS, "登录成功")); |
| | | // AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_SUCCESS, "登录成功")); |
| | | recordLoginInfo(loginUserDetails.getUser().getId(),LoginUserTagEnum.ADMIN_USER); |
| | | return createLoginUser(loginUserDetails,LoginUserTagEnum.ADMIN_USER); |
| | | }catch (Exception e){ |
| | | if (e instanceof BadCredentialsException) |
| | | { |
| | | AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, "用户密码不匹配")); |
| | | // AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, "用户密码不匹配")); |
| | | throw new ApiException("用户密码不匹配"); |
| | | } |
| | | else |
| | | { |
| | | AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, e.getMessage())); |
| | | // AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, e.getMessage())); |
| | | throw new ApiException(e.getMessage()); |
| | | } |
| | | }finally { |
| | |
| | | authentication = authenticationManager.authenticate(authenticationToken); |
| | | LoginUserDetails loginUserDetails= (LoginUserDetails) authentication.getPrincipal(); |
| | | passwordService.validate(loginUserDetails.getUser(),password); |
| | | AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_SUCCESS, "登录成功")); |
| | | // AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_SUCCESS, "登录成功")); |
| | | recordLoginInfo(loginUserDetails.getUser().getId(),LoginUserTagEnum.STUDENT_USER); |
| | | return createLoginUser(loginUserDetails,LoginUserTagEnum.STUDENT_USER); |
| | | }catch (Exception e){ |
| | | if (e instanceof BadCredentialsException) |
| | | { |
| | | AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, "用户密码不匹配")); |
| | | // AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, "用户密码不匹配")); |
| | | throw new ApiException("用户密码不匹配"); |
| | | } |
| | | else |
| | | { |
| | | AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, e.getMessage())); |
| | | // AsyncManager.me().execute(AsyncFactory.recordLoginInfo(username, Constant.LOGIN_FAIL, e.getMessage())); |
| | | throw new ApiException(e.getMessage()); |
| | | } |
| | | }finally { |
| | |
| | | } |
| | | |
| | | |
| | | public void logout(){ |
| | | tokenService.delTokenCache(request); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | package com.gkhy.exam.framework.web.service; |
| | | |
| | | import cn.hutool.crypto.digest.DigestUtil; |
| | | import com.gkhy.exam.common.api.ResultCode; |
| | | import com.gkhy.exam.common.constant.CacheConstant; |
| | | import com.gkhy.exam.common.domain.model.LoginUser; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.RedisUtils; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import io.jsonwebtoken.Claims; |
| | | import io.jsonwebtoken.ExpiredJwtException; |
| | | import io.jsonwebtoken.Jwts; |
| | | import io.jsonwebtoken.SignatureAlgorithm; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | * 从token中获取JWT中的负载 |
| | | */ |
| | | private Claims getClaimsFromToken(String token) { |
| | | Claims claims = null; |
| | | try { |
| | | claims = Jwts.parser() |
| | | return Jwts.parser() |
| | | .setSigningKey(SECRET) |
| | | .parseClaimsJws(token) |
| | | .getBody(); |
| | | } catch (Exception e) { |
| | | log.error("JWT格式验证失败:{}", token); |
| | | } |
| | | return claims; |
| | | } |
| | | |
| | | /** |
| | |
| | | try { |
| | | Claims claims = getClaimsFromToken(token); |
| | | username = claims.getSubject(); |
| | | } catch (Exception e) { |
| | | username = null; |
| | | } catch (ExpiredJwtException e) { |
| | | log.error("JWT过期:{}", token); |
| | | throw new ApiException(ResultCode.UNAUTHORIZED); |
| | | } |
| | | return username; |
| | | } |
| | |
| | | String tagUsername = getUserNameFromToken(token); |
| | | String username=tagUsername.substring(0,tagUsername.lastIndexOf("_")); |
| | | if(StringUtils.isBlank(username)||!username.equals(userDetails.getUsername())){ |
| | | return false; |
| | | throw new ApiException(ResultCode.UNAUTHORIZED); |
| | | } |
| | | String tokenKey=redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+md5Encode(token)); |
| | | String userKey=redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+username); |
| | | String cacheToken= (String) redisUtils.get(tokenKey); |
| | | if(StringUtils.isBlank(cacheToken)||isTokenExpired(cacheToken)){ |
| | | return false; |
| | | throw new ApiException(ResultCode.UNAUTHORIZED); |
| | | } |
| | | if(isNeedUpdate(cacheToken)){ |
| | | String newToken=createToken(tagUsername); |
| | |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | |
| | | |
| | | |
| | | |
| | | public void delTokenCache(HttpServletRequest request){ |
| | | String token=getToken(request); |
| | | String tokenKey=redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+md5Encode(token)); |
| | | redisUtils.del(tokenKey); |
| | | String tagUsername = getUserNameFromToken(token); |
| | | String username=tagUsername.substring(0,tagUsername.lastIndexOf("_")); |
| | | if(!StringUtils.isBlank(username)){ |
| | | String userKey=redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+username); |
| | | redisUtils.del(userKey); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | @TableField("origin") |
| | | private String origin; |
| | | |
| | | @ApiModelProperty("变动情况(增减课时)") |
| | | @ApiModelProperty("变动情况(增减课时)秒") |
| | | @TableField("modify_period") |
| | | private Integer modifyPeriod; |
| | | private Long modifyPeriod; |
| | | |
| | | @ApiModelProperty("变动后剩余(分)") |
| | | @ApiModelProperty("变动后剩余(秒)") |
| | | @TableField("remain_period") |
| | | private Integer remainPeriod; |
| | | private Long remainPeriod; |
| | | |
| | | @ApiModelProperty("创建时间") |
| | | @TableField("create_time") |
| | |
| | | import lombok.experimental.Accessors; |
| | | import org.hibernate.validator.constraints.Length; |
| | | |
| | | import javax.validation.constraints.Min; |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | |
| | | @TableField("introduce") |
| | | private String introduce; |
| | | |
| | | @ApiModelProperty("审批状态(0创建,1待审核,2审批通过,3审批不通过 默认0)") |
| | | @ApiModelProperty("审批状态(0待提交,1待审核,2审批通过,3审批不通过 默认0)") |
| | | @TableField("state") |
| | | private Integer state; |
| | | |
| | | @NotNull(message = "提交公司id不能为空") |
| | | @ApiModelProperty(value = "提交公司id",required = true) |
| | | @TableField("company_id") |
| | | private Long companyId; |
| | |
| | | @TableField("privatize") |
| | | private Integer privatize; |
| | | |
| | | @NotNull(message = "要求课时不能为空") |
| | | @ApiModelProperty(value = "要求课时(秒)",required = true) |
| | | @Min(value = 0,message = "课时格式不正确") |
| | | @TableField("period") |
| | | private Long period; |
| | | @Length(min = 0, max = 50, message = "审批意见不能超过50个字符") |
| | | @ApiModelProperty("审批意见") |
| | | @TableField("message") |
| | | private String message; |
| | | |
| | | |
| | | @ApiModelProperty("乐观锁") |
| | |
| | | private String categoryName; |
| | | |
| | | |
| | | @ApiModelProperty(value = "要求课时(秒) 所有小结总和") |
| | | @TableField(exist = false) |
| | | private Long period; |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | @ApiModelProperty("课程课时") |
| | | @TableField(exist = false) |
| | | private Integer coursePeriod; |
| | | private Long coursePeriod; |
| | | |
| | | @ApiModelProperty("课程名称") |
| | | @TableField(exist = false) |
| | | private String courseName; |
| | | |
| | | @ApiModelProperty("学员人数") |
| | | @TableField(exist = false) |
| | | private Integer studentCount; |
| | | |
| | | @ApiModelProperty("公司名称") |
| | | @TableField(exist = false) |
| | | private String companyName; |
| | | |
| | | @ApiModelProperty("完成人数") |
| | | @TableField(exist = false) |
| | | private Integer finishCount; |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import com.gkhy.exam.system.domain.vo.PaperStudentInfoVO; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | |
| | | private Integer limitTime; |
| | | |
| | | @ApiModelProperty("是否限制考试时间(0否,1是,默认0)") |
| | | @TableField("limit") |
| | | private Integer limit; |
| | | @TableField("limited") |
| | | private Integer limited; |
| | | |
| | | @NotNull(message = "单选题目数量不能为空") |
| | | @Min(value = 1,message = "单选题目数量必须大于0") |
| | | // @NotNull(message = "单选题目数量不能为空") |
| | | // @Min(value = 1,message = "单选题目数量必须大于0") |
| | | @ApiModelProperty(value = "单选题目数量",required = true) |
| | | @TableField("single_num") |
| | | private Integer singleNum; |
| | | |
| | | @NotNull(message = "单选题每题分数不能为空") |
| | | @Min(value = 1,message = "单选题每题分数必须大于0") |
| | | // @NotNull(message = "单选题每题分数不能为空") |
| | | // @Min(value = 1,message = "单选题每题分数必须大于0") |
| | | @ApiModelProperty(value = "单选题每题分数",required = true) |
| | | @TableField("single_score") |
| | | private Integer singleScore; |
| | | |
| | | @NotNull(message = "单选题题库不能为空") |
| | | // @NotNull(message = "单选题题库不能为空") |
| | | @ApiModelProperty(value = "单选题题库id",required = true) |
| | | @TableField("single_bank_id") |
| | | private Long singleBankId; |
| | | |
| | | @NotNull(message = "单选题出题方式不能为空") |
| | | // @NotNull(message = "单选题出题方式不能为空") |
| | | @ApiModelProperty(value = "单选题出题方式1随机,2顺序,默认1",required = true) |
| | | @TableField("single_method") |
| | | private Integer singleMethod; |
| | | |
| | | @NotNull(message = "多选题目数量不能为空") |
| | | @Min(value = 1,message = "多选题目数量必须大于0") |
| | | // @NotNull(message = "多选题目数量不能为空") |
| | | // @Min(value = 1,message = "多选题目数量必须大于0") |
| | | @ApiModelProperty(value = "多选题目数量",required = true) |
| | | @TableField("multi_num") |
| | | private Integer multiNum; |
| | | |
| | | @NotNull(message = "多选题每题分数不能为空") |
| | | @Min(value = 1,message = "多选题每题分数必须大于0") |
| | | // @NotNull(message = "多选题每题分数不能为空") |
| | | // @Min(value = 1,message = "多选题每题分数必须大于0") |
| | | @ApiModelProperty(value = "多选题每题分数",required = true) |
| | | @TableField("multi_score") |
| | | private Integer multiScore; |
| | | |
| | | @NotNull(message = "多选题题库不能为空") |
| | | // @NotNull(message = "多选题题库不能为空") |
| | | @ApiModelProperty(value = "多选题题库id",required = true) |
| | | @TableField("multi_bank_id") |
| | | private Long multiBankId; |
| | | |
| | | @NotNull(message = "多选题出题方式不能为空") |
| | | // @NotNull(message = "多选题出题方式不能为空") |
| | | @ApiModelProperty(value = "多选题出题方式1随机,2顺序,默认1",required = true) |
| | | @TableField("multi_method") |
| | | private Integer multiMethod; |
| | | |
| | | @NotNull(message = "判断题目数量不能为空") |
| | | @Min(value = 1,message = "判断题目数量必须大于0") |
| | | // @NotNull(message = "判断题目数量不能为空") |
| | | // @Min(value = 1,message = "判断题目数量必须大于0") |
| | | @ApiModelProperty(value = "判断题目数量",required = true) |
| | | @TableField("judge_num") |
| | | private Integer judgeNum; |
| | | |
| | | @NotNull(message = "判断题每题分数不能为空") |
| | | @Min(value = 1,message = "判断题每题分数必须大于0") |
| | | // @NotNull(message = "判断题每题分数不能为空") |
| | | // @Min(value = 1,message = "判断题每题分数必须大于0") |
| | | @ApiModelProperty(value = "判断题每题分数",required = true) |
| | | @TableField("judge_score") |
| | | private Integer judgeScore; |
| | | |
| | | @NotNull(message = "判断题题库不能为空") |
| | | // @NotNull(message = "判断题题库不能为空") |
| | | @ApiModelProperty(value = "判断题题库id",required = true) |
| | | @TableField("judge_bank_id") |
| | | private Long judgeBankId; |
| | | |
| | | @NotNull(message = "判断题出题方式不能为空") |
| | | // @NotNull(message = "判断题出题方式不能为空") |
| | | @ApiModelProperty(value = "判断题出题方式1随机,2顺序,默认1",required = true) |
| | | @TableField("judge_method") |
| | | private Integer judgeMethod; |
| | | |
| | | @ApiModelProperty(value = "简答题题目数量",required = true) |
| | | @TableField("easy_num") |
| | | private Integer easyNum; |
| | | |
| | | // @NotNull(message = "简答题每题分数不能为空") |
| | | // @Min(value = 1,message = "简答题每题分数必须大于0") |
| | | @ApiModelProperty(value = "简答题每题分数",required = true) |
| | | @TableField("easy_score") |
| | | private Integer easyScore; |
| | | |
| | | // @NotNull(message = "简答题题库不能为空") |
| | | @ApiModelProperty(value = "简答题题库id",required = true) |
| | | @TableField("easy_bank_id") |
| | | private Long easyBankId; |
| | | |
| | | // @NotNull(message = "简答题出题方式不能为空") |
| | | @ApiModelProperty(value = "简答题出题方式1随机,2顺序,默认1",required = true) |
| | | @TableField("easy_method") |
| | | private Integer easyMethod; |
| | | |
| | | |
| | | @NotNull(message = "合格分数不能为空") |
| | | @Min(value = 1,message = "合格分数必须大于0") |
| | | @ApiModelProperty(value = "合格分数",required = true) |
| | | @TableField("pass_score") |
| | | private Integer passScore; |
| | | |
| | | @NotNull(message = "考试截止时间不能为空") |
| | | @ApiModelProperty("考试截止时间") |
| | | @TableField("deadline") |
| | | private LocalDateTime deadline; |
| | | |
| | | @ApiModelProperty("创建时间") |
| | | @TableField("create_time") |
| | |
| | | |
| | | @ApiModelProperty("单选题是否重新出题,0否 1是(编辑时传参)") |
| | | @TableField(exist = false) |
| | | private Integer singleRebuild; |
| | | private Integer singleRebuild=0; |
| | | |
| | | @ApiModelProperty("多选题是否重新出题,0否 1是(编辑时传参)") |
| | | @TableField(exist = false) |
| | | private Integer multiRebuild; |
| | | private Integer multiRebuild=0; |
| | | |
| | | @ApiModelProperty("判断题是否重新出题,0否 1是(编辑时传参)") |
| | | @TableField(exist = false) |
| | | private Integer judgeRebuild; |
| | | private Integer judgeRebuild=0; |
| | | |
| | | @ApiModelProperty("单选题列表") |
| | | @ApiModelProperty("简答题是否重新出题,0否 1是(编辑时传参)") |
| | | @TableField(exist = false) |
| | | private List<ExQuestion> singleQuestions; |
| | | private Integer easyRebuild=0; |
| | | |
| | | @ApiModelProperty("多选题列表") |
| | | @ApiModelProperty("题目列表") |
| | | @TableField(exist = false) |
| | | private List<ExQuestion> multiQuestions; |
| | | private List<ExQuestion> questions; |
| | | |
| | | @ApiModelProperty("判断题列表") |
| | | @ApiModelProperty("学员统计信息") |
| | | @TableField(exist = false) |
| | | private List<ExQuestion> judgeQuestions; |
| | | private PaperStudentInfoVO paperStudentInfoVO; |
| | | |
| | | @ApiModelProperty("单选题题库名称") |
| | | @TableField(exist = false) |
| | | private String singleBankName; |
| | | @ApiModelProperty("多选题题库名称") |
| | | @TableField(exist = false) |
| | | private String multiBankName; |
| | | @ApiModelProperty("判断题题库名称") |
| | | @TableField(exist = false) |
| | | private String judgeBankName; |
| | | @ApiModelProperty("简答题题库名称") |
| | | @TableField(exist = false) |
| | | private String easyBankName; |
| | | |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @Setter |
| | | @TableName("ex_exam_record") |
| | | @ApiModel(value = "ExExamRecord对象", description = "线下教育登记表") |
| | | @JsonInclude(NON_NULL) |
| | | public class ExExamRecord implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | @TableField("company_id") |
| | | private Long companyId; |
| | | |
| | | @ApiModelProperty("学员id") |
| | | @NotNull(message = "学员id不能为空") |
| | | @ApiModelProperty(value = "学员id",required = true) |
| | | @TableField("student_id") |
| | | private Long studentId; |
| | | |
| | | @ApiModelProperty("计划名称") |
| | | @NotBlank(message = "计划名称不能为空") |
| | | @ApiModelProperty(value = "计划名称",required = true) |
| | | @TableField("plan_name") |
| | | private String planName; |
| | | |
| | | @ApiModelProperty("课程名称") |
| | | @NotBlank(message = "课程名称不能为空") |
| | | @ApiModelProperty(value = "课程名称",required = true) |
| | | @TableField("course_name") |
| | | private String courseName; |
| | | |
| | | @ApiModelProperty("培训等级") |
| | | @NotNull(message = "培训等级不能为空") |
| | | @ApiModelProperty(value = "培训等级(1公司级 2部门级 3车间级 默认1)",required = true) |
| | | @TableField("level") |
| | | private String level; |
| | | private Integer level; |
| | | |
| | | @ApiModelProperty("要求课时(分)") |
| | | @NotNull(message = "要求课时不能为空") |
| | | @ApiModelProperty(value = "要求课时(分)",required = true) |
| | | @TableField("period") |
| | | private Integer period; |
| | | |
| | | @ApiModelProperty("实际课时(分)") |
| | | @NotNull(message = "实际课时不能为空") |
| | | @ApiModelProperty(value = "实际课时(分)",required = true) |
| | | @TableField("actual_period") |
| | | private Integer actualPeriod; |
| | | |
| | | @NotNull(message = "考试成绩不能为空") |
| | | @ApiModelProperty("考试成绩") |
| | | @TableField("score") |
| | | private Integer score; |
| | | |
| | | @NotNull(message = "是否合格不能为空") |
| | | @ApiModelProperty("是否合格,0不合格 1合格 默认0") |
| | | @TableField("passed") |
| | | private Integer passed; |
| | |
| | | @TableField(exist = false) |
| | | private String companyName; |
| | | |
| | | @ApiModelProperty("学生对象") |
| | | @TableField(exist = false) |
| | | private ExStudent student; |
| | | |
| | | |
| | | } |
| | |
| | | package com.gkhy.exam.system.domain; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.*; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @Setter |
| | | @TableName("ex_exercise_answer") |
| | | @ApiModel(value = "ExExerciseAnswer对象", description = "学员与练习题关系表") |
| | | @JsonInclude(NON_NULL) |
| | | public class ExExerciseAnswer implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | @TableName("ex_paper_student") |
| | | @ApiModel(value = "ExPaperStudent对象", description = "学员与考试题目关系表") |
| | | @JsonInclude(NON_NULL) |
| | | public class ExPaperStudent implements Serializable { |
| | | public class ExPaperStudent implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | |
| | | @TableField("passed") |
| | | private Integer passed; |
| | | |
| | | @ApiModelProperty("是否完成考试(0否,1是 默认0)") |
| | | @TableField("completed") |
| | | private Integer completed; |
| | | // @ApiModelProperty("是否完成考试(0否,1是 默认0)") |
| | | // @TableField("completed") |
| | | // private Integer completed; |
| | | |
| | | @ApiModelProperty("考试时长(分钟)") |
| | | @TableField("use_time") |
| | |
| | | @ApiModelProperty("考试结束时间(时间戳13位ms)") |
| | | @TableField("end_time") |
| | | private Long endTime; |
| | | |
| | | @ApiModelProperty("状态:0待考试,1待批阅 2批阅完成,默认0") |
| | | @TableField("state") |
| | | private Integer state; |
| | | |
| | | @ApiModelProperty("创建时间") |
| | | @TableField("create_time") |
| | |
| | | @TableField("create_id") |
| | | private Long createId; |
| | | |
| | | @ApiModelProperty(value = "学生名称",required = true) |
| | | @ApiModelProperty(value = "学生名称") |
| | | @TableField(exist = false) |
| | | private String studentName; |
| | | |
| | | @ApiModelProperty(value = "学生手机号",required = true) |
| | | @ApiModelProperty(value = "学生手机号") |
| | | @TableField(exist = false) |
| | | private String studentPhone; |
| | | |
| | | @ApiModelProperty(value = "分配人名称",required = true) |
| | | @ApiModelProperty(value = "分配人名称") |
| | | @TableField(exist = false) |
| | | private String createName; |
| | | |
| | | @ApiModelProperty(value = "公司id") |
| | | @TableField(exist = false) |
| | | private Long companyId; |
| | | |
| | | @ApiModelProperty(value = "公司名称") |
| | | @TableField(exist = false) |
| | | private String companyName; |
| | | |
| | | @ApiModelProperty("试卷对象") |
| | | @TableField(exist = false) |
| | |
| | | @TableField(exist = false) |
| | | private ExStudent student; |
| | | |
| | | @ApiModelProperty("单选题列表") |
| | | @TableField(exist = false) |
| | | private List<ExQuestion> singleQuestions; |
| | | |
| | | @ApiModelProperty("多选题列表") |
| | | @ApiModelProperty("题目列表") |
| | | @TableField(exist = false) |
| | | private List<ExQuestion> multiQuestions; |
| | | private List<ExQuestion> questions; |
| | | |
| | | @ApiModelProperty("判断题列表") |
| | | @TableField(exist = false) |
| | | private List<ExQuestion> judgeQuestions; |
| | | |
| | | } |
| | |
| | | @TableField(exist = false) |
| | | private String createName; |
| | | |
| | | @ApiModelProperty("课时") |
| | | @TableField(exist = false) |
| | | private Integer period; |
| | | |
| | | @ApiModelProperty("课程对象") |
| | | @TableField(exist = false) |
| | | private ExCourse course; |
| | | |
| | | |
| | | @ApiModelProperty("企业id") |
| | | @TableField(exist = false) |
| | | private Long companyId; |
| | | |
| | | @ApiModelProperty("企业名称") |
| | | @TableField(exist = false) |
| | | private String companyName; |
| | | |
| | | } |
| | |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Long id; |
| | | @NotNull(message = "考题类型不能为空") |
| | | @ApiModelProperty(value = "考题类型(1单选题,2多选题,3判断题 默认1)",required = true) |
| | | @ApiModelProperty(value = "考题类型(1单选题,2多选题,3判断题,4简单题 默认1)",required = true) |
| | | @TableField("question_type") |
| | | private Integer questionType; |
| | | |
| | |
| | | @TableField("bank_id") |
| | | private Long bankId; |
| | | |
| | | @NotNull(message = "公司id不能为空") |
| | | |
| | | @ApiModelProperty("公司id") |
| | | @TableField("company_id") |
| | | private Long companyId; |
| | |
| | | @TableField("status") |
| | | private Integer status; |
| | | |
| | | @NotBlank(message = "答案不能为空") |
| | | @NotBlank(message = "答案不能为空(判断题对传1,错误0)") |
| | | @ApiModelProperty(value = "答案",required = true) |
| | | @TableField("answer") |
| | | private String answer; |
| | |
| | | /** |
| | | * json格式: |
| | | * 单选和多选 {"analyze":"",items:[{"prefix":"A","content":"xxxx"},{"prefix":"B","content":"xxxx"},{"prefix":"C","content":"xxxx"},{"prefix":"D","content":"xxxx"}]} |
| | | * 判断题 {"analyze":""} |
| | | * 判断题 {"analyze":"",items[{"prefix":"A","content":"是"},{"prefix":"B","content":"否"}]} |
| | | * 简答题 {"analyze":""} |
| | | */ |
| | | @ApiModelProperty("题目内容(json字符串)") |
| | | @TableField("content") |
| | |
| | | @TableField(exist = false) |
| | | private ExExerciseAnswer exExerciseAnswer; |
| | | |
| | | @ApiModelProperty("题库名称") |
| | | @TableField(exist = false) |
| | | private String bankName; |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | @TableField(exist = false) |
| | | private Long studentId; |
| | | |
| | | @ApiModelProperty("题目数量") |
| | | @ApiModelProperty("题目总数量") |
| | | @TableField(exist = false) |
| | | private Integer totalCount; |
| | | |
| | | @ApiModelProperty("单选题数量") |
| | | @TableField(exist = false) |
| | | private Integer singleCount; |
| | | |
| | | @ApiModelProperty("多选题数量") |
| | | @TableField(exist = false) |
| | | private Integer multiCount; |
| | | |
| | | @ApiModelProperty("判断题数量") |
| | | @TableField(exist = false) |
| | | private Integer judgeCount; |
| | | |
| | | @ApiModelProperty("学员练习数量") |
| | | @TableField(exist = false) |
| | | private Integer exerciseCount; |
| | | |
| | | @ApiModelProperty("分类名称") |
| | | @TableField(exist = false) |
| | | private String categoryName; |
| | | |
| | | @ApiModelProperty("最新刷题的题目id") |
| | | @TableField(exist = false) |
| | | private Long questionId; |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import com.gkhy.exam.common.annotation.DataDesensitizationType; |
| | | import com.gkhy.exam.common.domain.BaseEntity; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.SensitiveTypeEnum; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | import javax.validation.constraints.Pattern; |
| | | import java.io.Serializable; |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | |
| | | @Accessors(chain = true) |
| | | @ApiModel(value = "ExStudent对象", description = "学员表") |
| | | @JsonInclude(NON_NULL) |
| | | public class ExStudent implements Serializable { |
| | | public class ExStudent extends BaseEntity { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | |
| | | @TableField("phone") |
| | | private String phone; |
| | | |
| | | @DataDesensitizationType(type = SensitiveTypeEnum.ID_CARD) |
| | | @NotBlank(message = "身份证号不能为空") |
| | | @Length(min = 18, max = 18, message = "身份证号只能为18位") |
| | | @ApiModelProperty(value = "身份证号",required = true) |
| | |
| | | @TableField("create_id") |
| | | private Long createId; |
| | | |
| | | @ApiModelProperty("创建时间") |
| | | @TableField("create_time") |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty("创建人") |
| | | @TableField("create_by") |
| | | private String createBy; |
| | | |
| | | @ApiModelProperty("更新时间") |
| | | @TableField("update_time") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @ApiModelProperty("更新人") |
| | | @TableField("update_by") |
| | | private String updateBy; |
| | | |
| | | @ApiModelProperty("备注") |
| | | @TableField("remark") |
| | | private String remark; |
| | | |
| | | @ApiModelProperty("乐观锁") |
| | | @TableField("version") |
| | | private Integer version; |
| | |
| | | @TableField(exist = false) |
| | | private SysCompany company; |
| | | |
| | | @ApiModelProperty("创建人信息") |
| | | @TableField(exist = false) |
| | | private SysUser createUser; |
| | | |
| | | |
| | | } |
| | |
| | | @TableField("answer") |
| | | private String answer; |
| | | |
| | | @ApiModelProperty("是否正确(0错误,1正确)") |
| | | @ApiModelProperty("得分") |
| | | @TableField("score") |
| | | private Integer score; |
| | | |
| | | @ApiModelProperty("是否正确(0错误,1正确,2待批改)") |
| | | @TableField("passed") |
| | | private Integer passed; |
| | | |
| | |
| | | @TableField("progress") |
| | | private BigDecimal progress; |
| | | |
| | | @ApiModelProperty("资源类型(PPT,MP4,PDF)") |
| | | @TableField("resource_type") |
| | | private String resourceType; |
| | | |
| | | @ApiModelProperty("创建时间") |
| | | @TableField("create_time") |
| | |
| | | @TableField("name") |
| | | private String name; |
| | | |
| | | @ApiModelProperty("删除标志,0未删除,1删除,默认0") |
| | | @TableField("del_flag") |
| | | private Integer delFlag; |
| | | |
| | | // @ApiModelProperty("类型(1课程,2资源)") |
| | | // @TableField("category_type") |
| | | // private Integer categoryType; |
| | |
| | | import lombok.experimental.Accessors; |
| | | import org.hibernate.validator.constraints.Length; |
| | | |
| | | import javax.validation.constraints.Max; |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | import javax.validation.constraints.Pattern; |
| | |
| | | private String phone; |
| | | |
| | | @ApiModelProperty("删除标志,0未删除,1删除,默认0") |
| | | @TableField("delFlag") |
| | | @TableField("del_flag") |
| | | private Integer delFlag; |
| | | |
| | | @ApiModelProperty("剩余课时(分)") |
| | | @ApiModelProperty("剩余课时(秒)") |
| | | @TableField("remain_period") |
| | | private Integer remainPeriod; |
| | | private Long remainPeriod; |
| | | |
| | | @ApiModelProperty("已用课时(分)") |
| | | @TableField("spend_period") |
| | | private Integer spendPeriod; |
| | | |
| | | @NotNull(message = "总课时不能为空") |
| | | @ApiModelProperty(value = "总课时(分)",required = true) |
| | | @Max(value = 9999999999L,message = "总课时长度不能超过10位") |
| | | @ApiModelProperty(value = "总课时(秒)",required = true) |
| | | @TableField("total_period") |
| | | private Integer totalPeriod; |
| | | private Long totalPeriod; |
| | | |
| | | @Version |
| | | @ApiModelProperty("乐观锁") |
对比新文件 |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.util.List; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) //链式写法 |
| | | @ApiModel(value = "试卷批量绑定学员对象", description = "试卷批量绑定学员对象") |
| | | @JsonInclude(NON_NULL) |
| | | public class BatchPaperStudentVO { |
| | | @ApiModelProperty("批次id列表") |
| | | private List<Long> phaseIds; |
| | | @ApiModelProperty("学员id列表") |
| | | private List<Long> studentIds; |
| | | |
| | | @NotNull(message = "考卷id不能为空") |
| | | @ApiModelProperty(value = "考卷id",required = true) |
| | | private Long paperId; |
| | | } |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) |
| | | @JsonInclude(NON_NULL) |
| | | public class CompanyPaperStudentVO { |
| | | @ApiModelProperty("公司id") |
| | | private Long companyId; |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) |
| | | @JsonInclude(NON_NULL) |
| | | public class CompanyPhaseStudentVO { |
| | | @ApiModelProperty("公司id") |
| | | private Long companyId; |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) |
| | | @ApiModel(value = "CompanyPhaseVO对象", description = "公司批次统计对象") |
| | | @JsonInclude(NON_NULL) |
| | | public class CompanyPhaseVO { |
| | | @ApiModelProperty("公司id") |
| | | private Long companyId; |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) |
| | | @ApiModel(value = "CompanyStatisticVO对象", description = "公司数据统计对象") |
| | | @JsonInclude(NON_NULL) |
| | | public class CompanyStatisticVO { |
| | | @ApiModelProperty("公司id") |
| | | private Long companyId; |
对比新文件 |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.NoArgsConstructor; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | import java.util.List; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) |
| | | @ApiModel(value = "ExPaperStudent对象", description = "学员与考试题目关系表") |
| | | @JsonInclude(NON_NULL) |
| | | public class ExPaperStudentVO{ |
| | | |
| | | @NotNull(message = "学员与试卷关系id") |
| | | @ApiModelProperty(value = "学员与试卷关系id",required = true) |
| | | private Long id; |
| | | |
| | | @NotNull(message = "考卷id不能为空") |
| | | @ApiModelProperty(value = "考卷id",required = true) |
| | | private Long paperId; |
| | | |
| | | @NotNull(message = "学员id不能为空") |
| | | @ApiModelProperty(value = "学员id",required = true) |
| | | private Long studentId; |
| | | |
| | | @NotNull(message = "简答题题目列表不能为空") |
| | | @ApiModelProperty("题目列表") |
| | | private List<QuestionVO> questions; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @NoArgsConstructor |
| | | public static class QuestionVO { |
| | | @NotNull(message = "题目id不能为空") |
| | | @ApiModelProperty(value = "题目id",required = true) |
| | | private Long questionId; |
| | | |
| | | @NotNull(message = "得分不能为空") |
| | | @ApiModelProperty("得分") |
| | | private Integer score; |
| | | |
| | | @NotNull(message = "题目分数不能为空") |
| | | @ApiModelProperty("题目分数") |
| | | private Integer questionScore; |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | |
对比新文件 |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) //链式写法 |
| | | @ApiModel(value = "试卷学员统计信息对象", description = "试卷学员统计信息对象") |
| | | @JsonInclude(NON_NULL) |
| | | public class PaperStudentInfoVO { |
| | | @ApiModelProperty("学员人数") |
| | | @TableField(exist = false) |
| | | private Integer studentCount; |
| | | |
| | | @ApiModelProperty("合格人数") |
| | | @TableField(exist = false) |
| | | private Integer passStudentCount; |
| | | |
| | | @ApiModelProperty("平均分数") |
| | | @TableField(exist = false) |
| | | private String avgScore; |
| | | |
| | | @ApiModelProperty("完成人数") |
| | | @TableField(exist = false) |
| | | private Integer finishCount; |
| | | } |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Getter |
| | | @Setter |
| | | @Accessors(chain = true) |
| | | @ApiModel(description = "课程用户学习日志") |
| | | @JsonInclude(NON_NULL) |
| | | public class StudentStudyPeriodVO { |
| | | @ApiModelProperty(value = "课时id") |
| | | private Long periodId; |
| | |
| | | |
| | | @ApiModelProperty(value = "资源id") |
| | | private Long resourceId; |
| | | |
| | | @ApiModelProperty(value = "资源种类(1:视频2:音频;3:文档)") |
| | | private Integer resourceType; |
| | | |
| | | } |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Setter |
| | | @Getter |
| | | @Accessors(chain = true) |
| | | @ApiModel(description = "课程用户学习日志") |
| | | @JsonInclude(NON_NULL) |
| | | public class StudentStudyVO implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | @ApiModelProperty(value = "章节ID") |
对比新文件 |
| | |
| | | package com.gkhy.exam.system.domain.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; |
| | | |
| | | @Setter |
| | | @Getter |
| | | @Accessors(chain = true) |
| | | @ApiModel(description = "培训记录对象") |
| | | @JsonInclude(NON_NULL) |
| | | public class TrainRecordVO { |
| | | @ApiModelProperty(value = "学员id") |
| | | private Long studentId; |
| | | @ApiModelProperty(value = "培训类型(1批次学习 2考试)") |
| | | private Integer trainType; |
| | | @ApiModelProperty(value = "批次或者考试名称") |
| | | private String name; |
| | | @ApiModelProperty(value = "培训时间") |
| | | private LocalDateTime createTime; |
| | | @ApiModelProperty(value = "公司id") |
| | | private Long companyId; |
| | | @ApiModelProperty(value = "公司名称") |
| | | private String companyName; |
| | | } |
| | |
| | | @ApiModelProperty("文件保存相对路径") |
| | | private String path; |
| | | |
| | | @ApiModelProperty("文件访问链接") |
| | | private String url; |
| | | |
| | | |
| | | @ApiModelProperty("文件原始名称") |
| | | private String originName; |
| | | |
| | |
| | | * @return |
| | | */ |
| | | int deletePeriodByChapterId(Long chapterId); |
| | | |
| | | /** |
| | | * 根据课程id获取课时数量 |
| | | * @param courseId |
| | | * @return |
| | | */ |
| | | int selectCountByCourseId(Long courseId); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.gkhy.exam.system.domain.ExCourse; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | * @param name |
| | | * @return |
| | | */ |
| | | ExCourse checkNameUnique(String name); |
| | | ExCourse checkNameUnique(@Param("name") String name, @Param("companyId") Long companyId); |
| | | |
| | | /** |
| | | * 根据id删除 |
| | |
| | | */ |
| | | int selectCourseState(Long courseId); |
| | | |
| | | /** |
| | | * 根据课程id查询课程绑定数量 |
| | | * @param categoryId |
| | | * @return |
| | | */ |
| | | int selectCountByCategoryId(Long categoryId); |
| | | |
| | | |
| | | |
| | | |
| | |
| | | * @param name |
| | | * @return |
| | | */ |
| | | ExExamPaper checkNameUnique(String name); |
| | | ExExamPaper checkNameUnique(@Param("name") String name,@Param("companyId") Long companyId); |
| | | |
| | | } |
| | |
| | | import com.gkhy.exam.system.domain.ExPaperQuestion; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | /** |
| | | * 删除考卷下试题 |
| | | * @param paperId |
| | | * @param code |
| | | * @param questionType |
| | | */ |
| | | void deletePaperQuestion(Long paperId, Integer code); |
| | | void deletePaperQuestion(@Param("paperId") Long paperId, @Param("questionType") Integer questionType); |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | ExPaperStudent selectByPaperStudentId(ExPaperStudent paperStudent); |
| | | |
| | | /** |
| | | * 根据学员id获取学员分配的考试列表 |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | List<ExPaperStudent> selectByStudentId(Long studentId); |
| | | |
| | | /** |
| | | * 分页获取未完成考试学生列表 |
| | | * @param startIndex |
| | | * @param pageSize |
| | | * @return |
| | | */ |
| | | List<ExPaperStudent> selectNoCompleteStudent(int startIndex,int pageSize); |
| | | |
| | | /** |
| | | * 批量更新完成状态 |
| | | * @param paperStudentIds |
| | | * @param completed |
| | | */ |
| | | void batchUpdateComplete(@Param("paperStudentIds") List<Long> paperStudentIds,@Param("completed") Integer completed); |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | Integer selectCountByPhaseStudentId(@Param("phaseId") Long phaseId, @Param("studentId")Long studentId); |
| | | |
| | | /** |
| | | * 根据学员id获取学员批次分配列表 |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | public List<ExPhaseStudent> selectPhaseStudentByStudentId(Long studentId); |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | ExQuestionBank selectQuestionBankByIdForStudent(@Param("bankId") Long bankId,@Param("studentId") Long studentId); |
| | | |
| | | /** |
| | | * 查询题库题目数量 |
| | | * @param bankId |
| | | * @return |
| | | */ |
| | | int selectCountByBankId(Long bankId); |
| | | |
| | | |
| | | /** |
| | | * 根据课程id查询题库绑定数量 |
| | | * @param categoryId |
| | | * @return |
| | | */ |
| | | int selectCountByCategoryId(Long categoryId); |
| | | |
| | | /** |
| | | * 根据id列表查询题库 |
| | | * @param bankIds |
| | | * @return |
| | | */ |
| | | List<ExQuestionBank> selectQuestionBankByIds(List<Long> bankIds); |
| | | } |
| | |
| | | Integer selectCountByBankId(@Param("companyId") Long companyId,@Param("bankId") Long bankId, @Param("questionType") Integer questionType); |
| | | |
| | | /** |
| | | * 根据id获取题目信息 |
| | | * @param questionId |
| | | * @return |
| | | */ |
| | | ExQuestion selectByQuestionId(Long questionId); |
| | | |
| | | /** |
| | | * 顺序获取指定数量的考题 |
| | | * @param bankId |
| | | * @param questionType |
| | |
| | | /** |
| | | * 获取题库下面所有题目id列表 |
| | | * @param bankId |
| | | * @param exerciseType |
| | | * @return |
| | | */ |
| | | List<Map> getExerciseQuestionList(@Param("bankId") Long bankId, @Param("exerciseType") Integer exerciseType,@Param("studentId") Long StundentId); |
| | | List<Map> getExerciseQuestionList(@Param("bankId") Long bankId,@Param("studentId") Long StundentId); |
| | | |
| | | /** |
| | | * 刷题模式下获取题目 |
| | |
| | | /** |
| | | * 获取考卷下面所有题目id列表 |
| | | * @param paperId |
| | | * @param completed |
| | | * @param userId |
| | | * @param state |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | List<Map> getPaperQuestionList(@Param("paperId") Long paperId, @Param("completed") Integer completed, @Param("userId")Long userId); |
| | | List<Map> getPaperQuestionList(@Param("paperId") Long paperId, @Param("state") Integer state, @Param("studentId")Long studentId, @Param("viewType")Integer viewType); |
| | | |
| | | /** |
| | | * 根据id获取考卷下题目详情 |
| | | * @param questionId |
| | | * @param completed |
| | | * @param userId |
| | | * @param state |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | ExQuestion getPaperQuestionById(@Param("paperId")Long paperId,@Param("questionId")Long questionId, @Param("completed")Integer completed, @Param("userId")Long userId); |
| | | ExQuestion getPaperQuestionById(@Param("paperId")Long paperId,@Param("questionId")Long questionId, @Param("state")Integer state, @Param("studentId")Long studentId); |
| | | |
| | | /** |
| | | * 根据id列表批量获取考卷下题目详情 |
| | | * @param paperId |
| | | * @param questionIds |
| | | * @param completed |
| | | * @param userId |
| | | * @param state |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | List<ExQuestion> getPaperQuestionByIds(@Param("paperId") Long paperId, @Param("questionIds")List<Long> questionIds, @Param("completed")Integer completed, @Param("userId")Long userId); |
| | | List<ExQuestion> getPaperQuestionByIds(@Param("paperId") Long paperId, @Param("questionIds")List<Long> questionIds, @Param("state")Integer state, @Param("studentId")Long studentId); |
| | | |
| | | /** |
| | | * 获取错题题目id |
| | | * @param bankId |
| | | * @param userId |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | List<Long> getExerciseErrorQuestionList(@Param("bankId") Long bankId, @Param("userId") Long userId); |
| | | List<Long> getExerciseErrorQuestionList(@Param("bankId") Long bankId, @Param("studentId") Long studentId); |
| | | |
| | | /** |
| | | * 根据试卷id查询题目列表 |
| | | * @param paperId |
| | | * @return |
| | | */ |
| | | List<ExQuestion> selectQuestionByPaperId(Long paperId); |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | ExResource selectResourceByPeriodId(Long periodId); |
| | | |
| | | /** |
| | | * 查看资源是否被分配 |
| | | * @param resourceId |
| | | * @return |
| | | */ |
| | | int checkResourceAssign(Long resourceId); |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | int deleteByStudentId(Long studentId); |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | SysCategory checkNameUnique(@Param("name") String name, @Param("parentId")Long parentId); |
| | | |
| | | /** |
| | | * 根据课程id查询课程绑定数量 |
| | | * 根据id删除分类 |
| | | * @param categoryId |
| | | * @return |
| | | */ |
| | | int selectCountOfCoure(Long categoryId); |
| | | |
| | | |
| | | /** |
| | | * 根据课程id查询题库绑定数量 |
| | | * @param categoryId |
| | | * @return |
| | | */ |
| | | int selectCountOfBank(Long categoryId); |
| | | int deleteByCategoryId(Long categoryId); |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | SysUser checkPhoneUnique(String phone); |
| | | |
| | | /** |
| | | * 根据部门账号id获取车间级账号id列表 |
| | | * @param departUserId |
| | | * @return |
| | | */ |
| | | List<Long> selectWorkshopUserIds(Long departUserId); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.domain.vo.BatchPaperStudentVO; |
| | | import com.gkhy.exam.system.domain.vo.ExPaperStudentVO; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | /** |
| | | * 批量新增考卷与学员关系 |
| | | * @param paperStudentMap |
| | | * @param batchPaperStudentVO |
| | | * @return |
| | | */ |
| | | public int batchAddPaperStudent(Map<String,Object> paperStudentMap); |
| | | public int batchAddPaperStudent(BatchPaperStudentVO batchPaperStudentVO); |
| | | |
| | | /** |
| | | * 分页获取学员的试卷列表 |
| | |
| | | */ |
| | | public void checkStudentUnique(List<ExPaperStudent> paperStudents); |
| | | |
| | | /** |
| | | * 批改试卷 |
| | | * @param paperStudentVO |
| | | */ |
| | | public void doReview(ExPaperStudentVO paperStudentVO); |
| | | |
| | | /** |
| | | * 计算试卷分数 |
| | | * @param paperStudent |
| | | */ |
| | | public void handlePaperData(ExPaperStudent paperStudent); |
| | | |
| | | } |
| | |
| | | /** |
| | | * 获取题目ID列表 |
| | | * @param bankId |
| | | * @param exerciseType |
| | | * @return |
| | | */ |
| | | List<Map> getExerciseQuestionList(Long bankId, Integer exerciseType); |
| | | List<Map> getExerciseQuestionList(Long bankId); |
| | | |
| | | /** |
| | | * 刷题模式下根据id获取题目 |
| | |
| | | * @return |
| | | */ |
| | | List<Long> getExerciseErrorQuestionList(Long bankId); |
| | | |
| | | /** |
| | | * 根据考卷获取题目列表 |
| | | * @param paperId |
| | | * @return |
| | | */ |
| | | List<ExQuestion> selectQuestionByPaperId(Long paperId); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.system.domain.ExStudent; |
| | | import com.gkhy.exam.system.domain.vo.TrainRecordVO; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | public boolean checkIdNoUnique(ExStudent student); |
| | | |
| | | /** |
| | | * 校验身份证号是否存在,存在则放回公司信息 |
| | | * 校验身份证号是否存在,供前端校验使用 |
| | | * @param idNo |
| | | * @return |
| | | */ |
| | | public ExStudent checkIdNoUnique(String idNo); |
| | | public Map checkIdNoUnique(String idNo); |
| | | |
| | | /** |
| | | * 重置密码 |
| | | * @param student |
| | | */ |
| | | boolean resetUserPwd(ExStudent student); |
| | | |
| | | /** |
| | | * 变更学员所属公司 |
| | | * @param bodyMap |
| | | */ |
| | | void changeStudentCompany(Map<String, Long> bodyMap); |
| | | |
| | | /** |
| | | * 获取学员培训记录 |
| | | * @param studentId |
| | | * @return |
| | | */ |
| | | List<TrainRecordVO> trainRecord(Long studentId); |
| | | } |
| | |
| | | * @param path |
| | | */ |
| | | void removeMinioFile(Long resourceId,String path); |
| | | |
| | | |
| | | void importStudent(); |
| | | } |
| | |
| | | */ |
| | | SysUser checkUserDataScope(Long userId); |
| | | |
| | | |
| | | } |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(courseChapterPeriod.getCompanyId())){ |
| | | if(courseChapterPeriod.getCompanyId()!=null&&!currentUser.getCompanyId().equals(courseChapterPeriod.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业课程"); |
| | | } |
| | | int state=courseMapper.selectCourseState(courseChapterPeriod.getCourseId()); |
| | | if(state== ApproveStatusEnum.APPROVED.getCode()){ |
| | | throw new ApiException("已审批的课程不能再修改"); |
| | | throw new ApiException("已审批的课程不能再操作"); |
| | | } |
| | | if(state== ApproveStatusEnum.APPROVING.getCode()){ |
| | | throw new ApiException("待审批的课程不能再操作"); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.common.config.MinioConfig; |
| | | import com.gkhy.exam.common.constant.UserConstant; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.ApproveStatusEnum; |
| | |
| | | import com.gkhy.exam.common.utils.PageUtils; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.system.domain.ExCourseChapter; |
| | | import com.gkhy.exam.system.domain.ExCourseChapterPeriod; |
| | | import com.gkhy.exam.system.domain.ExResource; |
| | | import com.gkhy.exam.system.mapper.ExCourseChapterMapper; |
| | | import com.gkhy.exam.system.mapper.ExCourseChapterPeriodMapper; |
| | | import com.gkhy.exam.system.mapper.ExCourseMapper; |
| | |
| | | private ExCourseChapterPeriodMapper courseChapterPeriodMapper; |
| | | @Autowired |
| | | private ExCourseMapper courseMapper; |
| | | |
| | | @Autowired |
| | | private MinioConfig minioConfig; |
| | | |
| | | @Override |
| | | public CommonPage selectChapterList(ExCourseChapter chapter) { |
| | |
| | | |
| | | @Override |
| | | public List<ExCourseChapter> selectChapterByCourseId(Long courseId,Integer status) { |
| | | return baseMapper.selectChapterByCourseId(courseId,null); |
| | | List<ExCourseChapter> courseChapterList= baseMapper.selectChapterByCourseId(courseId,null); |
| | | for(ExCourseChapter courseChapter:courseChapterList){ |
| | | if(courseChapter.getChapterPeriods()!=null&& !courseChapter.getChapterPeriods().isEmpty()){ |
| | | List<ExCourseChapterPeriod> courseChapterPeriodList=courseChapter.getChapterPeriods(); |
| | | for(ExCourseChapterPeriod courseChapterPeriod:courseChapterPeriodList){ |
| | | if(courseChapterPeriod.getResource()!=null){ |
| | | ExResource resource=courseChapterPeriod.getResource(); |
| | | resource.setResourcePath(minioConfig.getEndpoint()+minioConfig.getBucketName()+"/"+resource.getResourcePath()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return courseChapterList; |
| | | } |
| | | |
| | | |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(courseChapter.getCompanyId())){ |
| | | if(courseChapter.getCompanyId()!=null&&!currentUser.getCompanyId().equals(courseChapter.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业课程"); |
| | | } |
| | | int state=courseMapper.selectCourseState(courseChapter.getCourseId()); |
| | | if(state==ApproveStatusEnum.APPROVED.getCode()){ |
| | | throw new ApiException("已审批的课程不能再修改"); |
| | | throw new ApiException("已审批的课程不能再操作"); |
| | | } |
| | | if(state==ApproveStatusEnum.APPROVING.getCode()){ |
| | | throw new ApiException("待审批的课程不能再操作"); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.common.constant.UserConstant; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.ApproveStatusEnum; |
| | | import com.gkhy.exam.common.enums.CodeTypeEnum; |
| | | import com.gkhy.exam.common.enums.UserTypeEnum; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.PageUtils; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.system.domain.ExCourse; |
| | | import com.gkhy.exam.system.domain.ExCoursePhase; |
| | | import com.gkhy.exam.system.mapper.ExCourseMapper; |
| | | import com.gkhy.exam.system.mapper.ExCoursePhaseMapper; |
| | | import com.gkhy.exam.system.mapper.ExPhaseStudentMapper; |
| | | import com.gkhy.exam.system.service.ExCoursePhaseService; |
| | |
| | | public class ExCoursePhaseServiceImpl extends ServiceImpl<ExCoursePhaseMapper, ExCoursePhase> implements ExCoursePhaseService { |
| | | @Autowired |
| | | private ExPhaseStudentMapper phaseStudentMapper; |
| | | @Autowired |
| | | private ExCourseMapper courseMapper; |
| | | |
| | | |
| | | |
| | |
| | | @Override |
| | | public int insertCoursePhase(ExCoursePhase coursePhase) { |
| | | checkUserAllowed(coursePhase); |
| | | checkCourseStatus(coursePhase); |
| | | if(!checkNameUnique(coursePhase)){ |
| | | throw new ApiException("批次名称已存在"); |
| | | } |
| | |
| | | @Override |
| | | public int updateCoursePhase(ExCoursePhase coursePhase) { |
| | | checkUserAllowed(coursePhase); |
| | | checkCourseStatus(coursePhase); |
| | | if(!checkNameUnique(coursePhase)){ |
| | | throw new ApiException("批次名称已存在"); |
| | | } |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(coursePhase.getCompanyId())){ |
| | | if(coursePhase.getCompanyId()!=null&&!currentUser.getCompanyId().equals(coursePhase.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业批次"); |
| | | } |
| | | int level=coursePhase.getLevel(); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | private void checkCourseStatus(ExCoursePhase coursePhase){ |
| | | Long courseId=coursePhase.getCourseId(); |
| | | ExCourse course= courseMapper.selectById(courseId); |
| | | if(course.getStatus().equals(UserConstant.DISENABLE)){ |
| | | throw new ApiException("课程已禁用,不能分配"); |
| | | } |
| | | if(!course.getState().equals(ApproveStatusEnum.APPROVED.getCode())){ |
| | | throw new ApiException("课程审批未通过,不能分配"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public int deleteCoursePhaseById(Long phaseId) { |
| | | checkUserAllowed(baseMapper.selectById(phaseId)); |
| | |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.PageUtils; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import com.gkhy.exam.system.domain.ExCourse; |
| | | import com.gkhy.exam.system.mapper.ExCourseChapterMapper; |
| | | import com.gkhy.exam.system.mapper.ExCourseMapper; |
| | |
| | | course.setState(ApproveStatusEnum.APPROVED.getCode()); |
| | | course.setPrivatize(PrivatizeEnum.PUBLIC.getCode()); |
| | | }else{ |
| | | course.setState(ApproveStatusEnum.APPROVING.getCode()); |
| | | course.setState(ApproveStatusEnum.TEMPORARY.getCode()); |
| | | } |
| | | int row =baseMapper.insert(course); |
| | | if(row<1){ |
| | |
| | | throw new ApiException("没有权限操作其他企业课程"); |
| | | } |
| | | if(course.getId()!=null){ |
| | | if(course.getState().equals(ApproveStatusEnum.APPROVING.getCode())){ |
| | | throw new ApiException("课程待审批状态不能再操作"); |
| | | } |
| | | if(course.getState().equals(ApproveStatusEnum.APPROVED.getCode())){ |
| | | throw new ApiException("已审批的课程不能再修改"); |
| | | throw new ApiException("已审批的课程不能再操作"); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | @Override |
| | | public boolean checkNameUnique(ExCourse course) { |
| | | SysUser user=SecurityUtils.getLoginUser().getUser(); |
| | | Long courseId=course.getId()==null?-1L:course.getId(); |
| | | ExCourse cou= baseMapper.checkNameUnique(course.getName()); |
| | | ExCourse cou= baseMapper.checkNameUnique(course.getName(),user.getCompanyId()); |
| | | if(cou!=null&&cou.getId().longValue()!=courseId.longValue()){ |
| | | return UserConstant.NOT_UNIQUE; |
| | | } |
| | |
| | | |
| | | @Override |
| | | public int doApprove(ExCourse course) { |
| | | ExCourse existCourse=baseMapper.selectById(course.getId()); |
| | | checkUserAllowed(existCourse); |
| | | SysUser currentUser= SecurityUtils.getLoginUser().getUser(); |
| | | ExCourse dbCourse=getById(course.getId()); |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(dbCourse.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业课程"); |
| | | } |
| | | if(dbCourse.getState().equals(ApproveStatusEnum.APPROVED.getCode())){ |
| | | throw new ApiException("已审批的课程不能再操作"); |
| | | } |
| | | } |
| | | if(StringUtils.isBlank(course.getMessage())){ |
| | | course.setMessage(""); |
| | | } |
| | | int row=baseMapper.updateById(course); |
| | | if(row<1){ |
| | | throw new ApiException("审批失败"); |
| | |
| | | import com.gkhy.exam.system.domain.ExExamPaper; |
| | | import com.gkhy.exam.system.domain.ExPaperQuestion; |
| | | import com.gkhy.exam.system.domain.ExQuestion; |
| | | import com.gkhy.exam.system.mapper.ExExamPaperMapper; |
| | | import com.gkhy.exam.system.mapper.ExPaperQuestionMapper; |
| | | import com.gkhy.exam.system.mapper.ExPaperStudentMapper; |
| | | import com.gkhy.exam.system.mapper.ExQuestionMapper; |
| | | import com.gkhy.exam.system.domain.ExQuestionBank; |
| | | import com.gkhy.exam.system.mapper.*; |
| | | import com.gkhy.exam.system.service.ExExamPaperService; |
| | | import com.gkhy.exam.system.utils.SequenceUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.Random; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | private ExPaperQuestionMapper paperQuestionMapper; |
| | | @Autowired |
| | | private ExQuestionMapper questionMapper; |
| | | @Autowired |
| | | private ExQuestionBankMapper questionBankMapper; |
| | | |
| | | @Autowired |
| | | private SequenceUtils sequenceUtils; |
| | |
| | | @Override |
| | | public ExExamPaper selectExamPaperById(Long paperId) { |
| | | ExExamPaper examPaper= baseMapper.selectExamPaperById(paperId); |
| | | //获取题库名称 |
| | | List<Long> bankIds=new ArrayList<>(); |
| | | bankIds.add(examPaper.getSingleBankId()); |
| | | bankIds.add(examPaper.getMultiBankId()); |
| | | bankIds.add(examPaper.getJudgeBankId()); |
| | | bankIds.add(examPaper.getEasyBankId()); |
| | | List<ExQuestionBank> questionBanks=questionBankMapper.selectQuestionBankByIds(bankIds); |
| | | questionBanks.forEach(item -> { |
| | | if(Objects.equals(item.getId(), examPaper.getSingleBankId())){ |
| | | examPaper.setSingleBankName(item.getName()); |
| | | } |
| | | if(Objects.equals(item.getId(), examPaper.getMultiBankId())){ |
| | | examPaper.setMultiBankName(item.getName()); |
| | | } |
| | | if(Objects.equals(item.getId(), examPaper.getJudgeBankId())){ |
| | | examPaper.setJudgeBankName(item.getName()); |
| | | } |
| | | if(Objects.equals(item.getId(), examPaper.getEasyBankId())){ |
| | | examPaper.setEasyBankName(item.getName()); |
| | | } |
| | | }); |
| | | SysUser currentUser= SecurityUtils.getLoginUser().getUser(); |
| | | if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | return examPaper; |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = RuntimeException.class) |
| | | public int insertExamPaper(ExExamPaper examPaper) { |
| | | validatedData(examPaper); |
| | | checkUserAllowed(examPaper); |
| | | if(!checkNameUnique(examPaper)){ |
| | | throw new ApiException("试卷名称已存在"); |
| | |
| | | examPaper.setCode(sequenceUtils.getNextSequence(CodeTypeEnum.EXAM_PAPER.getCode())); |
| | | examPaper.setCreateBy(SecurityUtils.getUsername()); |
| | | if(examPaper.getLimitTime()>0){ |
| | | examPaper.setLimit(1); |
| | | examPaper.setLimited(1); |
| | | }else{ |
| | | examPaper.setLimit(0); |
| | | examPaper.setLimited(0); |
| | | } |
| | | int row=baseMapper.insert(examPaper); |
| | | if(row<1){ |
| | | throw new ApiException("新增试卷失败"); |
| | | } |
| | | //分配试题 |
| | | assignSingleQuestion(examPaper); |
| | | assignMultiQuestion(examPaper); |
| | | assignJudgeQuestion(examPaper); |
| | | if(Optional.ofNullable(examPaper.getSingleNum()).orElse(0)>0) { |
| | | assignSingleQuestion(examPaper); |
| | | } |
| | | if(Optional.ofNullable(examPaper.getMultiNum()).orElse(0)>0) { |
| | | assignMultiQuestion(examPaper); |
| | | } |
| | | if(Optional.ofNullable(examPaper.getJudgeNum()).orElse(0)>0) { |
| | | assignJudgeQuestion(examPaper); |
| | | } |
| | | if(Optional.ofNullable(examPaper.getEasyNum()).orElse(0)>0) { |
| | | assignEasyQuestion(examPaper); |
| | | } |
| | | return row; |
| | | } |
| | | |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(examPaper.getCompanyId())){ |
| | | if(examPaper.getCompanyId()!=null&&!currentUser.getCompanyId().equals(examPaper.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业试卷"); |
| | | } |
| | | } |
| | | |
| | | public void validatedData(ExExamPaper examPaper){ |
| | | if(Optional.ofNullable(examPaper.getSingleNum()).orElse(0)<=0 |
| | | &&Optional.ofNullable(examPaper.getMultiNum()).orElse(0)<=0 |
| | | &&Optional.ofNullable(examPaper.getJudgeNum()).orElse(0)<=0 |
| | | &&Optional.ofNullable(examPaper.getEasyNum()).orElse(0)<=0){ |
| | | throw new ApiException("试卷题目数量不能为空"); |
| | | } |
| | | if(Optional.ofNullable(examPaper.getSingleNum()).orElse(0)>0){ |
| | | if(Optional.ofNullable(examPaper.getSingleScore()).orElse(0)<=0 || examPaper.getSingleMethod()==null||examPaper.getSingleBankId()==null){ |
| | | throw new ApiException("单选题参数错误"); |
| | | } |
| | | } |
| | | if(Optional.ofNullable(examPaper.getMultiNum()).orElse(0)>0){ |
| | | if(Optional.ofNullable(examPaper.getMultiScore()).orElse(0)<=0 || examPaper.getMultiMethod()==null||examPaper.getMultiBankId()==null){ |
| | | throw new ApiException("多选题参数错误"); |
| | | } |
| | | } |
| | | if(Optional.ofNullable(examPaper.getJudgeNum()).orElse(0)>0){ |
| | | if(Optional.ofNullable(examPaper.getJudgeScore()).orElse(0)<=0 || examPaper.getJudgeMethod()==null||examPaper.getJudgeBankId()==null){ |
| | | throw new ApiException("判断题参数错误"); |
| | | } |
| | | } |
| | | if(Optional.ofNullable(examPaper.getEasyNum()).orElse(0)>0){ |
| | | if(Optional.ofNullable(examPaper.getEasyScore()).orElse(0)<=0 || examPaper.getEasyMethod()==null||examPaper.getEasyBankId()==null){ |
| | | throw new ApiException("简答题参数错误"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | paperQuestionMapper.batchInsert(paperQuestionList); |
| | | } |
| | | |
| | | //分配简答题 |
| | | public void assignEasyQuestion(ExExamPaper examPaper){ |
| | | List<ExPaperQuestion> paperQuestionList = getPaperQuestions(examPaper.getId(), examPaper.getEasyBankId(), |
| | | examPaper.getEasyMethod(),examPaper.getEasyNum(), examPaper.getEasyScore(),QuestionTypeEnum.EASY); |
| | | paperQuestionMapper.batchInsert(paperQuestionList); |
| | | } |
| | | |
| | | private List<ExPaperQuestion> getPaperQuestions(Long paperId,Long bankId,Integer questionMethod,Integer questionCount,Integer questionScore, QuestionTypeEnum questionTypeEnum) { |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | Integer totalQuestionCount=questionMapper.selectCountByBankId(currentUser.getCompanyId(), bankId, questionTypeEnum.getCode()); |
| | |
| | | if(Objects.equals(questionMethod, QuestionAssignEnum.RANDOM.getCode())){//随机分配 |
| | | questions=questionMapper.selectRandomQuestion(currentUser.getCompanyId(), bankId,questionTypeEnum.getCode(), questionCount); |
| | | }else{//顺序分配 |
| | | int totalPage=questionCount/questionMethod;//不能整除,忽略最后一页 |
| | | int totalPage=totalQuestionCount/questionCount;//不能整除,忽略最后一页 |
| | | Random random=new Random(); |
| | | int startIndex=random.nextInt(totalPage)+1; |
| | | questions=questionMapper.selectQuestionWithLimit(currentUser.getCompanyId(), bankId,questionTypeEnum.getCode(),startIndex, questionCount); |
| | |
| | | |
| | | @Override |
| | | public int updateExamPaper(ExExamPaper examPaper) { |
| | | validatedData(examPaper); |
| | | checkUserAllowed(examPaper); |
| | | if(!checkNameUnique(examPaper)){ |
| | | throw new ApiException("试卷名称已存在"); |
| | |
| | | } |
| | | examPaper.setCode(null);//编号不能修改 |
| | | if(examPaper.getLimitTime()>0){ |
| | | examPaper.setLimit(1); |
| | | examPaper.setLimited(1); |
| | | }else{ |
| | | examPaper.setLimit(0); |
| | | examPaper.setLimited(0); |
| | | examPaper.setLimitTime(0); |
| | | } |
| | | int row=baseMapper.updateById(examPaper); |
| | | if(row<1){ |
| | |
| | | if(examPaper.getJudgeRebuild()==1) { |
| | | deletePaperQuestion(examPaper.getId(),QuestionTypeEnum.JUDGE); |
| | | assignJudgeQuestion(examPaper); |
| | | } |
| | | if(examPaper.getEasyRebuild()==1) { |
| | | deletePaperQuestion(examPaper.getId(),QuestionTypeEnum.EASY); |
| | | assignEasyQuestion(examPaper); |
| | | } |
| | | return row; |
| | | } |
| | |
| | | |
| | | @Override |
| | | public boolean checkNameUnique(ExExamPaper examPaper) { |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | Long paperId=examPaper.getId()==null?-1L:examPaper.getId(); |
| | | ExExamPaper paper= baseMapper.checkNameUnique(examPaper.getName()); |
| | | ExExamPaper paper= baseMapper.checkNameUnique(examPaper.getName(),currentUser.getCompanyId()); |
| | | if(paper!=null&&paper.getId().longValue()!=paperId.longValue()){ |
| | | return UserConstant.NOT_UNIQUE; |
| | | } |
| | |
| | | @Override |
| | | public int insertExamRecord(ExExamRecord examRecord) { |
| | | checkUserAllowed(examRecord); |
| | | examRecord.setCompanyId(SecurityUtils.getLoginUser().getUser().getCompanyId()); |
| | | examRecord.setCreateBy(SecurityUtils.getUsername()); |
| | | int row=baseMapper.insert(examRecord); |
| | | if(row<1){ |
| | | throw new ApiException("新增登记记录失败"); |
| | |
| | | @Override |
| | | public int updateExamRecord(ExExamRecord examRecord) { |
| | | checkUserAllowed(examRecord); |
| | | examRecord.setUpdateBy(SecurityUtils.getUsername()); |
| | | int row=baseMapper.updateById(examRecord); |
| | | if(row<1){ |
| | | throw new ApiException("更新登记记录失败"); |
| | |
| | | public void checkUserAllowed(ExExamRecord examRecord) { |
| | | SysUser currentUser= SecurityUtils.getLoginUser().getUser(); |
| | | if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | return; |
| | | throw new ApiException("管理员没有权限操作"); |
| | | } |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(examRecord.getCompanyId())){ |
| | | if(examRecord.getCompanyId()!=null&&!currentUser.getCompanyId().equals(examRecord.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业登记记录"); |
| | | } |
| | | } |
| | |
| | | package com.gkhy.exam.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.gkhy.exam.common.enums.StudentAnswerPassEnum; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.system.domain.ExExerciseAnswer; |
| | | import com.gkhy.exam.system.domain.ExQuestion; |
| | | import com.gkhy.exam.system.domain.ExStudentAnswer; |
| | |
| | | @Override |
| | | public ExExerciseAnswer addExerciseAnswer(ExExerciseAnswer exerciseAnswer) { |
| | | int row=0; |
| | | exerciseAnswer.setStudentId(SecurityUtils.getUserId()); |
| | | ExQuestion question=questionMapper.selectById(exerciseAnswer.getQuestionId()); |
| | | if(exerciseAnswer.getAnswer().equals(question.getAnswer())){ |
| | | exerciseAnswer.setPassed(1); |
| | | exerciseAnswer.setPassed(StudentAnswerPassEnum.CORRECT.getCode()); |
| | | }else{ |
| | | exerciseAnswer.setPassed(0); |
| | | exerciseAnswer.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | } |
| | | ExExerciseAnswer existAnswer= baseMapper.getExerciseAnswer(exerciseAnswer); |
| | | if(existAnswer!=null){ |
| | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.common.constant.Constant; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.PaperStudentStateEnum; |
| | | import com.gkhy.exam.common.enums.QuestionTypeEnum; |
| | | import com.gkhy.exam.common.enums.StudentAnswerPassEnum; |
| | | import com.gkhy.exam.common.enums.UserTypeEnum; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.PageUtils; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.system.domain.ExExamPaper; |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.domain.ExPhaseStudent; |
| | | import com.gkhy.exam.system.domain.ExStudent; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import com.gkhy.exam.system.domain.*; |
| | | import com.gkhy.exam.system.domain.vo.BatchPaperStudentVO; |
| | | import com.gkhy.exam.system.domain.vo.ExPaperStudentVO; |
| | | import com.gkhy.exam.system.mapper.*; |
| | | import com.gkhy.exam.system.service.ExPaperStudentService; |
| | | import com.gkhy.exam.system.service.ExStudentAnswerService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | @Autowired |
| | | private ExExamPaperMapper examPaperMapper; |
| | | @Autowired |
| | | private ExStudentAnswerService studentAnswerService; |
| | | @Autowired |
| | | private ExStudentAnswerMapper studentAnswerMapper; |
| | | @Autowired |
| | | private ExStudentMapper studentMapper; |
| | | @Autowired |
| | | private ExPhaseStudentMapper phaseStudentMapper; |
| | | @Autowired |
| | | private ExQuestionMapper questionMapper; |
| | | |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public int batchAddPaperStudent(Map<String,Object> paperStudentMap) { |
| | | List<Long> phaseIds= (List<Long>) paperStudentMap.get("phaseIds"); |
| | | List<Long> studentIds= (List<Long>) paperStudentMap.get("studentIds"); |
| | | public int batchAddPaperStudent(BatchPaperStudentVO batchPaperStudentVO) { |
| | | List<Long> phaseIds= batchPaperStudentVO.getPhaseIds(); |
| | | List<Long> studentIds= batchPaperStudentVO.getStudentIds(); |
| | | Long paperId=batchPaperStudentVO.getPaperId(); |
| | | if(ObjectUtil.isEmpty(phaseIds) && ObjectUtil.isEmpty(studentIds)){ |
| | | throw new ApiException("批次id与学员id不能同时为空"); |
| | | } |
| | | Long paperId= (Long) paperStudentMap.get("paperId"); |
| | | if(paperId==null){ |
| | | throw new ApiException("考卷id不能为空"); |
| | | } |
| | | List<Long> allStudentIds=new ArrayList<>(); |
| | | //按批次绑定用户 |
| | | if(phaseIds.size()>0){ |
| | | if(phaseIds!=null&&!phaseIds.isEmpty()){ |
| | | List<ExPhaseStudent> phaseStudentList=phaseStudentMapper.selectList( Wrappers.<ExPhaseStudent>lambdaQuery() |
| | | .in(ExPhaseStudent::getPhaseId, phaseIds)); |
| | | studentIds=phaseStudentList.stream().map(item -> item.getStudentId()).distinct().collect(Collectors.toList()); |
| | | allStudentIds=phaseStudentList.stream().map(item -> item.getStudentId()).distinct().collect(Collectors.toList()); |
| | | } |
| | | List<ExPaperStudent> paperStudents=studentIds.stream().map(item -> { |
| | | return new ExPaperStudent().setPaperId(paperId).setStudentId(item); |
| | | if(studentIds!=null&&!studentIds.isEmpty()){ |
| | | allStudentIds.addAll(studentIds); |
| | | } |
| | | List<ExPaperStudent> paperStudentList=baseMapper.selectList( Wrappers.<ExPaperStudent>lambdaQuery() |
| | | .eq(true,ExPaperStudent::getPaperId, paperId) |
| | | .in(true,ExPaperStudent::getStudentId,allStudentIds)); |
| | | if(paperStudentList.size()>0) { |
| | | List<Long> existStudentIds = paperStudentList.stream().map(item -> item.getStudentId()).distinct().collect(Collectors.toList()); |
| | | allStudentIds.removeAll(existStudentIds); |
| | | } |
| | | if(allStudentIds.isEmpty()){ |
| | | throw new ApiException("未匹配到学员"); |
| | | } |
| | | allStudentIds= allStudentIds.stream().distinct().collect(Collectors.toList()); |
| | | List<ExPaperStudent> paperStudents=allStudentIds.stream().map(item -> { |
| | | return new ExPaperStudent().setPaperId(paperId).setStudentId(item).setCreateId(SecurityUtils.getUserId()); |
| | | }).collect(Collectors.toList()); |
| | | checkStudentUnique(paperStudents); |
| | | // checkStudentUnique(paperStudents); |
| | | int row=baseMapper.batchInsert(paperStudents); |
| | | if(row<1){ |
| | | throw new ApiException("批量分配学员失败"); |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = RuntimeException.class) |
| | | public void doReview(ExPaperStudentVO paperStudentVO) { |
| | | checkUserAllowed(new ExPaperStudent().setPaperId(paperStudentVO.getPaperId())); |
| | | ExPaperStudent paperStudent=baseMapper.selectById(paperStudentVO.getId()); |
| | | ExExamPaper examPaper=examPaperMapper.selectById(paperStudent.getPaperId()); |
| | | if(paperStudent.getState().equals(PaperStudentStateEnum.WAIT_EXAM.getCode())){ |
| | | throw new ApiException("待考试状态的试卷不能批改!"); |
| | | } |
| | | List<ExStudentAnswer> studentAnswerList=studentAnswerMapper.selectList(Wrappers.<ExStudentAnswer>lambdaQuery() |
| | | .eq(true,ExStudentAnswer::getStudentId,paperStudent.getStudentId()) |
| | | .eq(true,ExStudentAnswer::getPaperId,paperStudent.getPaperId())); |
| | | Map<Long, ExStudentAnswer> collectMap = studentAnswerList.stream().collect(Collectors.toMap(ExStudentAnswer::getQuestionId, k -> k)); |
| | | List<ExPaperStudentVO.QuestionVO> questionVOList=paperStudentVO.getQuestions(); |
| | | List<ExStudentAnswer> updateStudentAnswerList=new ArrayList<>(); |
| | | for (ExPaperStudentVO.QuestionVO questionVO:questionVOList){ |
| | | ExStudentAnswer sa=collectMap.get(questionVO.getQuestionId()); |
| | | if(sa!=null){ |
| | | int score=questionVO.getScore(); |
| | | sa.setScore(score); |
| | | if(score>examPaper.getEasyScore()){ |
| | | throw new ApiException("得分不能超过题目的最高分!"); |
| | | }else if(score==examPaper.getEasyScore()){ |
| | | sa.setPassed(StudentAnswerPassEnum.CORRECT.getCode()); |
| | | }else{ |
| | | sa.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | } |
| | | updateStudentAnswerList.add(sa); |
| | | } |
| | | } |
| | | int totalScore=0; |
| | | for(ExStudentAnswer studentAnswer:studentAnswerList){ |
| | | if(studentAnswer.getScore()!=null) { |
| | | totalScore = totalScore + studentAnswer.getScore(); |
| | | } |
| | | } |
| | | paperStudent.setState(PaperStudentStateEnum.DONE_REVIEW.getCode()); |
| | | paperStudent.setScore(totalScore); |
| | | if(totalScore<examPaper.getPassScore()){ |
| | | paperStudent.setPassed(Constant.EXAM_UNPASS); |
| | | }else{ |
| | | paperStudent.setPassed(Constant.EXAM_PASS); |
| | | } |
| | | paperStudent.setUpdateBy(SecurityUtils.getUsername()); |
| | | baseMapper.updateById(paperStudent); |
| | | if(!updateStudentAnswerList.isEmpty()){ |
| | | studentAnswerService.updateBatchById(updateStudentAnswerList); |
| | | } |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public CommonPage selectPaperStudentList(ExPaperStudent paperStudent) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void endExam(ExPaperStudent paperStudent) { |
| | | public void endExam(ExPaperStudent pStudent) { |
| | | if(pStudent.getId()==null){ |
| | | throw new ApiException("学员与试卷关系id不能为空"); |
| | | } |
| | | ExPaperStudent existPs=baseMapper.selectById(pStudent.getId()); |
| | | if(existPs==null){ |
| | | throw new ApiException("学员与试卷关系不存在"); |
| | | } |
| | | Long endTime=System.currentTimeMillis(); |
| | | //异步计算 |
| | | existPs.setEndTime(endTime); |
| | | handlePaperData(existPs); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = RuntimeException.class) |
| | | public void handlePaperData(ExPaperStudent paperStudent){ |
| | | //计算考试成绩 |
| | | ExExamPaper paper=examPaperMapper.selectById(paperStudent.getPaperId()); |
| | | int singleCount=studentAnswerMapper.selectPassCount(paperStudent.getPaperId(),paperStudent.getStudentId(), QuestionTypeEnum.SINGLE.getCode()); |
| | | int multiCount=studentAnswerMapper.selectPassCount(paperStudent.getPaperId(),paperStudent.getStudentId(), QuestionTypeEnum.MULTI.getCode()); |
| | | int judgeCount=studentAnswerMapper.selectPassCount(paperStudent.getPaperId(),paperStudent.getStudentId(), QuestionTypeEnum.JUDGE.getCode()); |
| | | int score=singleCount*paper.getSingleScore()+multiCount*paper.getMultiScore()+judgeCount*paper.getJudgeScore(); |
| | | ExPaperStudent exPaperStudent = new ExPaperStudent() |
| | | .setPaperId(paperStudent.getPaperId()) |
| | | .setStudentId(paperStudent.getStudentId()) |
| | | .setCompleted(1) |
| | | .setEndTime(endTime) |
| | | .setScore(score); |
| | | if(score>=paper.getPassScore()){ |
| | | exPaperStudent.setPassed(1); |
| | | }else{ |
| | | exPaperStudent.setPassed(0); |
| | | paperStudent.setState(PaperStudentStateEnum.WAIT_REVIEW.getCode()); |
| | | List<ExStudentAnswer> studentAnswerList=studentAnswerMapper.selectList(Wrappers.<ExStudentAnswer>lambdaQuery() |
| | | .eq(true,ExStudentAnswer::getStudentId,paperStudent.getStudentId()) |
| | | .eq(true,ExStudentAnswer::getPaperId,paperStudent.getPaperId())); |
| | | List<ExQuestion> questionList=questionMapper.selectQuestionByPaperId(paperStudent.getPaperId()); |
| | | Map<Long, ExStudentAnswer> collectMap = studentAnswerList.stream().collect(Collectors.toMap(ExStudentAnswer::getQuestionId, k -> k)); |
| | | List<ExStudentAnswer> updateStudentAnswers=new ArrayList<>(); |
| | | int totalScore=0; |
| | | boolean easyViewFlag=false; |
| | | for(ExQuestion question:questionList){ |
| | | ExStudentAnswer sa=collectMap.get(question.getId()); |
| | | if(sa!=null){ |
| | | if(question.getQuestionType().equals(QuestionTypeEnum.EASY.getCode())) { |
| | | if(StringUtils.isBlank(sa.getAnswer())){ |
| | | sa.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | sa.setScore(0); |
| | | }else{ |
| | | sa.setPassed(StudentAnswerPassEnum.WAIT_REVIEW.getCode()); |
| | | easyViewFlag=true; |
| | | } |
| | | }else{ |
| | | if (sa.getAnswer().equals(question.getAnswer())) { |
| | | sa.setPassed(StudentAnswerPassEnum.CORRECT.getCode()); |
| | | sa.setScore(getScore(paper, question.getQuestionType())); |
| | | totalScore = totalScore + sa.getScore(); |
| | | }else { |
| | | sa.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | sa.setScore(0); |
| | | } |
| | | } |
| | | }else{ |
| | | sa=new ExStudentAnswer(); |
| | | sa.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | sa.setScore(0); |
| | | sa.setStudentId(paperStudent.getStudentId()); |
| | | sa.setPaperId(paperStudent.getPaperId()); |
| | | sa.setQuestionId(question.getId()); |
| | | } |
| | | updateStudentAnswers.add(sa); |
| | | } |
| | | int row=baseMapper.updateById(exPaperStudent); |
| | | |
| | | studentAnswerService.saveOrUpdateBatch(updateStudentAnswers); |
| | | paperStudent.setScore(totalScore); |
| | | if(!easyViewFlag){ |
| | | //没有简答题,直接批改试卷 |
| | | paperStudent.setState(PaperStudentStateEnum.DONE_REVIEW.getCode()); |
| | | if(paper.getPassScore()>totalScore){ |
| | | paperStudent.setPassed(Constant.EXAM_UNPASS); |
| | | }else{ |
| | | paperStudent.setPassed(Constant.EXAM_PASS); |
| | | } |
| | | } |
| | | int row=baseMapper.updateById(paperStudent); |
| | | if(row<1){ |
| | | throw new ApiException("提交考试失败"); |
| | | } |
| | | } |
| | | |
| | | private Integer getScore(ExExamPaper examPaper,Integer questionType){ |
| | | if(questionType.equals(QuestionTypeEnum.SINGLE.getCode())){ |
| | | return examPaper.getSingleScore(); |
| | | }else if(questionType.equals(QuestionTypeEnum.MULTI.getCode())){ |
| | | return examPaper.getMultiScore(); |
| | | }else if(questionType.equals(QuestionTypeEnum.JUDGE.getCode())){ |
| | | return examPaper.getJudgeScore(); |
| | | }else if(questionType.equals(QuestionTypeEnum.EASY.getCode())){ |
| | | return examPaper.getEasyScore(); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.system.domain.*; |
| | | import com.gkhy.exam.system.domain.vo.StudentStudyVO; |
| | | import com.gkhy.exam.system.mapper.ExCoursePhaseMapper; |
| | | import com.gkhy.exam.system.mapper.ExPhaseStudentMapper; |
| | | import com.gkhy.exam.system.mapper.ExStudentMapper; |
| | | import com.gkhy.exam.system.mapper.ExStudentStudyMapper; |
| | | import com.gkhy.exam.system.mapper.*; |
| | | import com.gkhy.exam.system.service.ExCompanyPeriodService; |
| | | import com.gkhy.exam.system.service.ExPhaseStudentService; |
| | | import com.gkhy.exam.system.service.ExStudentStudyService; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | |
| | | private SysCompanyService companyService; |
| | | @Autowired |
| | | private ExCompanyPeriodService companyPeriodService; |
| | | @Autowired |
| | | private ExCourseChapterPeriodMapper courseChapterPeriodMapper; |
| | | |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = RuntimeException.class) |
| | | public int batchAddPhaseStudent(List<ExPhaseStudent> phaseStudents) { |
| | | if(phaseStudents==null|| phaseStudents.isEmpty()){ |
| | | throw new ApiException("学员数据不能为空"); |
| | | } |
| | | checkUserAllowed(phaseStudents.get(0)); |
| | | checkStudentUnique(phaseStudents); |
| | | for(ExPhaseStudent phaseStudent:phaseStudents){ |
| | |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | ExCoursePhase coursePhase=coursePhaseMapper.selectById(phaseStudent.getPhaseId()); |
| | | if(!currentUser.getCompanyId().equals(coursePhase.getCompanyId())){ |
| | | if(!coursePhase.getCompanyId().equals(currentUser.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业批次"); |
| | | } |
| | | |
| | |
| | | } |
| | | PageUtils.startPage(); |
| | | List<ExPhaseStudent> phaseStudentList=baseMapper.selectPhaseStudentList(phaseStudent); |
| | | if(phaseStudentList.size()>0) { |
| | | //获取课程所有课时数量 |
| | | int count = courseChapterPeriodMapper.selectCountByCourseId(phaseStudentList.get(0).getCourse().getId()); |
| | | if(count>0) { |
| | | for (ExPhaseStudent ps : phaseStudentList) { |
| | | if (ps.getTotalProgress() != null) { |
| | | ps.setTotalProgress(ps.getTotalProgress().divide(BigDecimal.valueOf(count), BigDecimal.ROUND_UP)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return CommonPage.restPage(phaseStudentList); |
| | | } |
| | | |
| | |
| | | public int deletePhaseStudent(Long phaseStudentId) { |
| | | ExPhaseStudent phaseStudent=baseMapper.selectPhaseStudentById(phaseStudentId); |
| | | if(ObjectUtil.isNull(phaseStudent)){ |
| | | throw new ApiException(String.format("该批次下不存在该学员<>",phaseStudent.getStudentName())); |
| | | throw new ApiException("该批次下不存在该学员id"); |
| | | } |
| | | checkUserAllowed(phaseStudent); |
| | | int studentStudyCount=studentStudyMapper.countByPhaseId(phaseStudent.getPhaseId(),phaseStudent.getStudentId()); |
| | |
| | | ExCoursePhase coursePhase= coursePhaseMapper.selectCoursePhaseById(phaseId); |
| | | ExCompanyPeriod companyPeriod=new ExCompanyPeriod(); |
| | | companyPeriod.setPhaseId(phaseId); |
| | | companyPeriod.setModifyPeriod(-1*studentCount*coursePhase.getCoursePeriod()); |
| | | companyPeriod.setModifyPeriod(-1L*studentCount*coursePhase.getCoursePeriod()); |
| | | companyPeriod.setOrigin("\""+coursePhase.getName()+"\"新增学员消耗"); |
| | | SysCompany company=companyService.getById(coursePhase.getCompanyId()); |
| | | int remainPeriod=company.getTotalPeriod()+companyPeriod.getModifyPeriod(); |
| | | Long remainPeriod=company.getRemainPeriod()+companyPeriod.getModifyPeriod(); |
| | | if(remainPeriod<0){ |
| | | throw new ApiException("企业剩余课时不足"); |
| | | } |
| | | companyPeriod.setCompanyId(company.getId()); |
| | | companyPeriod.setRemainPeriod(remainPeriod); |
| | | companyPeriodService.save(companyPeriod); |
| | | company.setRemainPeriod(companyPeriod.getRemainPeriod()); |
| | |
| | | questionBank.setPrivatize(PrivatizeEnum.PUBLIC.getCode()); |
| | | }else{ |
| | | questionBank.setCompanyId(user.getCompanyId()); |
| | | questionBank.setPrivatize(PrivatizeEnum.PRIVATE.getCode()); |
| | | } |
| | | int row =baseMapper.insert(questionBank); |
| | | if(row<1){ |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(questionBank.getCompanyId())){ |
| | | if(questionBank.getCompanyId()!=null&&!currentUser.getCompanyId().equals(questionBank.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业课程"); |
| | | } |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.PaperStudentStateEnum; |
| | | import com.gkhy.exam.common.enums.PrivatizeEnum; |
| | | import com.gkhy.exam.common.enums.QuestionTypeEnum; |
| | | import com.gkhy.exam.common.enums.UserTypeEnum; |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneOffset; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | @Override |
| | | public CommonPage selectQuestionList(ExQuestion question) { |
| | | if(question.getBankId()==null){ |
| | | throw new ApiException("题库id不能为空"); |
| | | } |
| | | ExQuestionBank questionBank=questionBankMapper.selectById(question.getBankId()); |
| | | if(!questionBank.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | if(!question.getCompanyId().equals(currentUser.getCompanyId())){ |
| | | throw new ApiException("无权限查看其它企业题目"); |
| | | } |
| | | } |
| | | // if(question.getBankId()==null){ |
| | | // throw new ApiException("题库id不能为空"); |
| | | // } |
| | | // ExQuestionBank questionBank=questionBankMapper.selectById(question.getBankId()); |
| | | // if(!questionBank.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | // SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | // if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | // if(!question.getCompanyId().equals(currentUser.getCompanyId())){ |
| | | // throw new ApiException("无权限查看其它企业题目"); |
| | | // } |
| | | // } |
| | | // } |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | question.setCompanyId(currentUser.getCompanyId()); |
| | | } |
| | | PageUtils.startPage(); |
| | | List<ExQuestion> questionList=baseMapper.selectQuestionList(question); |
| | |
| | | |
| | | @Override |
| | | public ExQuestion selectQuestionById(Long questionId) { |
| | | ExQuestion question= baseMapper.selectById(questionId); |
| | | ExQuestion question= baseMapper.selectByQuestionId(questionId); |
| | | if(question.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | return question; |
| | | } |
| | |
| | | public int insertQuestion(ExQuestion question) { |
| | | checkUserAllowed(question); |
| | | SysUser user= SecurityUtils.getLoginUser().getUser(); |
| | | int totalCount=questionBankMapper.selectCountByBankId(question.getBankId()); |
| | | if(totalCount>1000){ |
| | | throw new ApiException("题库题目数量超过1000,不能再新增"); |
| | | } |
| | | //公开的题库新增题目,题目也是公开 |
| | | ExQuestionBank questionBank=questionBankMapper.selectById(question.getBankId()); |
| | | if(user.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())||questionBank.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | if(user.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())&&questionBank.getPrivatize().equals(PrivatizeEnum.PRIVATE.getCode())){ |
| | | throw new ApiException("管理员不允许在私有题库创建题目"); |
| | | }else if (user.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())&&questionBank.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | question.setPrivatize(PrivatizeEnum.PUBLIC.getCode()); |
| | | }else{ |
| | | question.setCompanyId(user.getCompanyId()); |
| | | question.setPrivatize(PrivatizeEnum.PRIVATE.getCode()); |
| | | } |
| | | validData(question); |
| | | question.setCreateBy(user.getUsername()); |
| | | int row=baseMapper.insert(question); |
| | | if(row<1){ |
| | | throw new ApiException("新增题目失败"); |
| | |
| | | public int updateQuestion(ExQuestion question) { |
| | | validData(question); |
| | | checkUserAllowed(question); |
| | | question.setUpdateBy(SecurityUtils.getUsername()); |
| | | int row=baseMapper.updateById(question); |
| | | if(row<1){ |
| | | throw new ApiException("编辑题目失败"); |
| | |
| | | } |
| | | |
| | | public void validData(ExQuestion question){ |
| | | if(!question.getQuestionType().equals(QuestionTypeEnum.JUDGE.getCode())){ |
| | | if(!question.getQuestionType().equals(QuestionTypeEnum.JUDGE.getCode())&&!question.getQuestionType().equals(QuestionTypeEnum.EASY.getCode())){ |
| | | if(StringUtils.isBlank(question.getContent())){ |
| | | throw new ApiException("题目内容不能为空"); |
| | | } |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(question.getCompanyId())){ |
| | | if(question.getCompanyId()!=null&&!currentUser.getCompanyId().equals(question.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业题目"); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<Map> getExerciseQuestionList(Long bankId, Integer exerciseType) { |
| | | return baseMapper.getExerciseQuestionList(bankId,exerciseType,SecurityUtils.getUserId()); |
| | | public List<Map> getExerciseQuestionList(Long bankId) { |
| | | return baseMapper.getExerciseQuestionList(bankId,SecurityUtils.getUserId()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public List<ExQuestion> getExerciseQuestionByIds(List<Long> questionIds) { |
| | | if(questionIds==null|| questionIds.isEmpty()){ |
| | | throw new ApiException("题目id列表不能为空"); |
| | | } |
| | | if(questionIds.size()>30){ |
| | | throw new ApiException("批量id数量超过阀值"); |
| | | } |
| | | return baseMapper.getExeriseQuestionByIds(questionIds,SecurityUtils.getUserId()); |
| | | } |
| | | |
| | |
| | | if(paperStudent==null){ |
| | | throw new ApiException("您分配的试卷未查询到"); |
| | | } |
| | | Long currentDateTime=System.currentTimeMillis(); |
| | | if(viewType==1){//更新考试开始时间 |
| | | Long startTime=System.currentTimeMillis(); |
| | | if(paperStudent.getCompleted()==1){ |
| | | if(paperStudent.getState()!= PaperStudentStateEnum.WAIT_EXAM.getCode()){ |
| | | throw new ApiException("考试已完成,不能重复考试"); |
| | | } |
| | | if(paperStudent.getStartTime()!=null) {//判断考卷是否已完成 |
| | | ExExamPaper examPaper = examPaperMapper.selectById(paperStudent.getPaperId()); |
| | | if(examPaper.getLimit()==1) { |
| | | Long currentDateTime = System.currentTimeMillis(); |
| | | if (currentDateTime-paperStudent.getStartTime()>=examPaper.getLimitTime()*60*1000){ |
| | | paperStudent.setCompleted(1); |
| | | paperStudentMapper.updateById(paperStudent); |
| | | throw new ApiException("考试已超时,不能再考试"); |
| | | } |
| | | ExExamPaper examPaper = examPaperMapper.selectById(paperStudent.getPaperId()); |
| | | if(examPaper.getLimited()==1){ |
| | | if(paperStudent.getStartTime()!=null && (currentDateTime-paperStudent.getStartTime()>=examPaper.getLimitTime()*60*1000)){ |
| | | // paperStudent.setCompleted(1); |
| | | // paperStudentMapper.updateById(paperStudent); |
| | | throw new ApiException("考试已超时,不能再考试"); |
| | | } |
| | | LocalDateTime deadline = examPaper.getDeadline(); |
| | | if(currentDateTime-deadline.toInstant(ZoneOffset.of("+8")).toEpochMilli()>0){ |
| | | // paperStudent.setCompleted(1); |
| | | // paperStudentMapper.updateById(paperStudent); |
| | | throw new ApiException("已过考试截止时间,不能再考试"); |
| | | } |
| | | } |
| | | int row=paperStudentMapper.updateById(new ExPaperStudent().setPaperId(paperStudent.getPaperId()).setStudentId(paperStudent.getStudentId()).setStartTime(startTime)); |
| | | if(row<1){ |
| | | throw new ApiException("设置考试开始时间失败"); |
| | | if(paperStudent.getStartTime()==null) { |
| | | int row = paperStudentMapper.updateById(new ExPaperStudent().setId(paperStudent.getId()).setPaperId(paperStudent.getPaperId()).setStudentId(paperStudent.getStudentId()).setStartTime(currentDateTime)); |
| | | if (row < 1) { |
| | | throw new ApiException("设置考试开始时间失败"); |
| | | } |
| | | } |
| | | }else{ |
| | | if(!Objects.equals(paperStudent.getState(), PaperStudentStateEnum.DONE_REVIEW.getCode())){ |
| | | // if(paperStudent.getStartTime()!=null) {//判断考卷是否已完成 |
| | | // ExExamPaper examPaper = examPaperMapper.selectById(paperStudent.getPaperId()); |
| | | // if(examPaper.getLimited()==1) { |
| | | // if (currentDateTime-paperStudent.getStartTime()>=examPaper.getLimitTime()*60*1000){ |
| | | // paperStudent.setCompleted(1); |
| | | // paperStudentMapper.updateById(paperStudent); |
| | | // } |
| | | // } |
| | | // } |
| | | throw new ApiException("试卷未审批完,无法查看"); |
| | | } |
| | | } |
| | | return baseMapper.getPaperQuestionList(paperId,paperStudent.getCompleted(),SecurityUtils.getUserId()); |
| | | return baseMapper.getPaperQuestionList(paperId,paperStudent.getState(),SecurityUtils.getUserId(),viewType); |
| | | } |
| | | |
| | | @Override |
| | |
| | | if(paperStudent==null){ |
| | | throw new ApiException("您分配的试卷未查询到"); |
| | | } |
| | | return baseMapper.getPaperQuestionById(paperId,questionId,paperStudent.getCompleted(),SecurityUtils.getUserId()); |
| | | return baseMapper.getPaperQuestionById(paperId,questionId,paperStudent.getState(),SecurityUtils.getUserId()); |
| | | } |
| | | |
| | | @Override |
| | | public List<ExQuestion> getPaperQuestionByIds(Long paperId, List<Long> questionIds) { |
| | | if(questionIds.size()>30){ |
| | | throw new ApiException("批量id数量超过阀值"); |
| | | } |
| | | LambdaQueryWrapper<ExPaperStudent> lambdaQueryWrapper = Wrappers.<ExPaperStudent>lambdaQuery() |
| | | .eq(ExPaperStudent::getPaperId, paperId) |
| | | .eq(ExPaperStudent::getStudentId, SecurityUtils.getUserId()); |
| | |
| | | if(paperStudent==null){ |
| | | throw new ApiException("您分配的试卷未查询到"); |
| | | } |
| | | return baseMapper.getPaperQuestionByIds(paperId,questionIds,paperStudent.getCompleted(),SecurityUtils.getUserId()); |
| | | return baseMapper.getPaperQuestionByIds(paperId,questionIds,paperStudent.getState(),SecurityUtils.getUserId()); |
| | | } |
| | | |
| | | @Override |
| | | public List<Long> getExerciseErrorQuestionList(Long bankId) { |
| | | return baseMapper.getExerciseErrorQuestionList(bankId,SecurityUtils.getUserId()); |
| | | } |
| | | |
| | | @Override |
| | | public List<ExQuestion> selectQuestionByPaperId(Long paperId) { |
| | | return baseMapper.selectQuestionByPaperId(paperId); |
| | | } |
| | | } |
| | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.gkhy.exam.common.api.CommonPage; |
| | | import com.gkhy.exam.common.config.MinioConfig; |
| | | import com.gkhy.exam.common.constant.UserConstant; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.PrivatizeEnum; |
| | |
| | | public class ExResourceServiceImpl extends ServiceImpl<ExResourceMapper, ExResource> implements ExResourceService { |
| | | @Autowired |
| | | private SysCommonService commonService; |
| | | |
| | | @Autowired |
| | | private MinioConfig minioConfig; |
| | | |
| | | |
| | | |
| | | @Override |
| | | public CommonPage selectResourseList(ExResource resource) { |
| | | SysUser currentUser = SecurityUtils.getLoginUser().getUser(); |
| | |
| | | } |
| | | PageUtils.startPage(); |
| | | List<ExResource> resourceList=baseMapper.selectResourceList(resource); |
| | | resourceList.forEach(item -> { |
| | | item.setResourcePath(minioConfig.getEndpoint()+minioConfig.getBucketName()+"/"+item.getResourcePath()); |
| | | }); |
| | | return CommonPage.restPage(resourceList); |
| | | } |
| | | |
| | |
| | | if(resource==null){ |
| | | return resource; |
| | | } |
| | | resource.setResourcePath(minioConfig.getEndpoint()+minioConfig.getBucketName()+"/"+resource.getResourcePath()); |
| | | if(resource.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | return resource; |
| | | } |
| | |
| | | if(!resource.getCompanyId().equals(currentUser.getCompanyId())){ |
| | | throw new ApiException("无权限查看其它企业资源"); |
| | | } |
| | | |
| | | return resource; |
| | | } |
| | | |
| | |
| | | if(resource==null){ |
| | | return resource; |
| | | } |
| | | resource.setResourcePath(minioConfig.getEndpoint()+minioConfig.getBucketName()+"/"+resource.getResourcePath()); |
| | | if(resource.getPrivatize().equals(PrivatizeEnum.PUBLIC.getCode())){ |
| | | return resource; |
| | | } |
| | |
| | | if(!checkNameUnique(resource)){ |
| | | throw new ApiException("资源名称已存在"); |
| | | } |
| | | String resourcePath=resource.getResourcePath(); |
| | | if(resourcePath.startsWith(minioConfig.getEndpoint()+minioConfig.getBucketName()+"/")) { |
| | | resourcePath = resourcePath.replace(minioConfig.getEndpoint()+minioConfig.getBucketName() + "/", ""); |
| | | resource.setResourcePath(resourcePath); |
| | | } |
| | | int row=baseMapper.updateById(resource); |
| | | if(row<1){ |
| | | throw new ApiException("更新资源失败"); |
| | |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(resource.getCompanyId())){ |
| | | if(resource.getCompanyId()!=null&&!currentUser.getCompanyId().equals(resource.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业资源"); |
| | | } |
| | | } |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = RuntimeException.class) |
| | | public int deleteResourceById(Long resourceId) { |
| | | //校验资源是否绑定 |
| | | checkUserAllowed(baseMapper.selectById(resourceId)); |
| | | //校验资源是否绑定 |
| | | int count= baseMapper.checkResourceAssign(resourceId); |
| | | if(count>0){ |
| | | throw new ApiException("资源已跟课时关联,不能删除"); |
| | | } |
| | | ExResource resource=getById(resourceId); |
| | | int row=baseMapper.deleteById(resourceId); |
| | | if(row<1){ |
| | |
| | | if(!user.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | companyId=user.getCompanyId(); |
| | | } |
| | | if(startTime==null && endTime==null){ |
| | | endTime=new Date(); |
| | | startTime=DateUtil.offsetDay(endTime,-7); |
| | | }else if(startTime!=null&&endTime==null){ |
| | | endTime=DateUtil.offsetDay(startTime,7); |
| | | }else if(startTime==null&&endTime!=null){ |
| | | startTime=DateUtil.offsetDay(endTime,-7); |
| | | } |
| | | PageUtils.startPage(); |
| | | List<SysCompany> companyList=companyMapper.selectCompanyList(new SysCompany().setId(companyId)); |
| | | CommonPage commonPage= CommonPage.restPage(companyList); |
| | | List<CompanyStatisticVO>companyStatisticVOList=staticData(companyList, DateUtil.formatDateTime(DateUtil.beginOfDay(startTime)),DateUtil.formatDateTime(DateUtil.endOfDay(endTime)),type); |
| | | commonPage.setList(companyStatisticVOList); |
| | | if(companyList.size()>0) { |
| | | List<CompanyStatisticVO> companyStatisticVOList = staticData(companyList, DateUtil.formatDateTime(DateUtil.beginOfDay(startTime)), DateUtil.formatDateTime(DateUtil.endOfDay(endTime)), type); |
| | | commonPage.setList(companyStatisticVOList); |
| | | } |
| | | return commonPage; |
| | | } |
| | | |
| | | public List<CompanyStatisticVO> staticData(List<SysCompany> companyList,String startTime,String endTime,Integer type){ |
| | | List<Long> companyIds=companyList.stream().map(item -> item.getId()).collect(Collectors.toList()); |
| | | |
| | | //统计公司批次数据 |
| | | List<CompanyPhaseVO> companyPhaseVOList=null; |
| | | if(type==1) { |
| | | companyPhaseVOList=companyMapper.getOnlineCompanyPhaseCount(companyIds, startTime, endTime); |
| | |
| | | companyPhaseVOList=companyMapper.getOfflineCompanyPhaseCount(companyIds, startTime, endTime); |
| | | } |
| | | Map<Long,List<CompanyPhaseVO>> companyPhaseVOMap=companyPhaseVOList.stream().collect(Collectors.groupingBy(CompanyPhaseVO::getCompanyId, LinkedHashMap::new,Collectors.toList())); |
| | | |
| | | List<CompanyPhaseStudentVO> companyPhaseStudentVOList=null; |
| | | if(type==1) { |
| | | companyPhaseStudentVOList=companyMapper.getOnlineCompanyPhaseStudentCount(companyIds, startTime, endTime); |
| | | }else{ |
| | | companyPhaseStudentVOList=companyMapper.getOfflineCompanyPhaseStudentCount(companyIds, startTime, endTime); |
| | | } |
| | | Map<Long,List<CompanyPhaseStudentVO>> companyPhaseStudentVOMap=companyPhaseStudentVOList.stream().collect(Collectors.groupingBy(CompanyPhaseStudentVO::getCompanyId,LinkedHashMap::new,Collectors.toList())); |
| | | |
| | | Map<Long,List<CompanyPhaseStudentVO>> companyPhaseStudentVOMap=companyPhaseStudentVOList.stream().collect(Collectors.groupingBy(CompanyPhaseStudentVO::getCompanyId,LinkedHashMap::new,Collectors.toList())); |
| | | List<CompanyPaperStudentVO> companyPaperStudentVOList=null; |
| | | if(type==1) { |
| | | companyPaperStudentVOList=companyMapper.getOnlineCompanyPaperStudentCount(companyIds, startTime, endTime); |
| | |
| | | List<CompanyPhaseVO> companyPhaseVOs=companyPhaseVOMap.get(item.getId()); |
| | | if(companyPhaseVOs!=null&&companyPhaseVOs.size()>0){ |
| | | companyPhaseVOs.forEach(cp -> { |
| | | if(cp.getLevel().equals(PhaseLevelEnum.COMPANY)){ |
| | | if(cp.getLevel().equals(PhaseLevelEnum.COMPANY.getCode())){ |
| | | companyStatisticVO.setLevel1PhaseCount(cp.getPhaseCount()); |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.DEPART)){ |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.DEPART.getCode())){ |
| | | companyStatisticVO.setLevel2PhaseCount(cp.getPhaseCount()); |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.WORkSHOP)) { |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.WORkSHOP.getCode())) { |
| | | companyStatisticVO.setLevel3PhaseCount(cp.getPhaseCount()); |
| | | } |
| | | }); |
| | |
| | | List<CompanyPhaseStudentVO> companyPhaseStudentVOs=companyPhaseStudentVOMap.get(item.getId()); |
| | | if(companyPhaseStudentVOs!=null&&companyPhaseStudentVOs.size()>0){ |
| | | companyPhaseStudentVOs.forEach(cp -> { |
| | | if(cp.getLevel().equals(PhaseLevelEnum.COMPANY)){ |
| | | if(cp.getLevel().equals(PhaseLevelEnum.COMPANY.getCode())){ |
| | | companyStatisticVO.setLevel1StudentCount(cp.getPhaseStudentCount()); |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.DEPART)){ |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.DEPART.getCode())){ |
| | | companyStatisticVO.setLevel2StudentCount(cp.getPhaseStudentCount()); |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.WORkSHOP)) { |
| | | }else if(cp.getLevel().equals(PhaseLevelEnum.WORkSHOP.getCode())) { |
| | | companyStatisticVO.setLevel3StudentCount(cp.getPhaseStudentCount()); |
| | | } |
| | | }); |
| | |
| | | package com.gkhy.exam.system.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.gkhy.exam.common.enums.PaperStudentStateEnum; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.domain.ExQuestion; |
| | | import com.gkhy.exam.system.domain.ExStudentAnswer; |
| | | import com.gkhy.exam.system.mapper.ExPaperStudentMapper; |
| | | import com.gkhy.exam.system.mapper.ExQuestionMapper; |
| | |
| | | import com.gkhy.exam.system.service.ExStudentAnswerService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | public int addStudentAnswer(ExStudentAnswer studentAnswer) { |
| | | int row=0; |
| | | validData(studentAnswer); |
| | | ExQuestion question=questionMapper.selectById(studentAnswer.getQuestionId()); |
| | | if(studentAnswer.getAnswer().equals(question.getAnswer())){ |
| | | studentAnswer.setPassed(1); |
| | | }else{ |
| | | studentAnswer.setPassed(0); |
| | | } |
| | | // ExQuestion question=questionMapper.selectById(studentAnswer.getQuestionId()); |
| | | // if(question.getQuestionType().equals(QuestionTypeEnum.EASY.getCode())){ |
| | | // studentAnswer.setPassed(StudentAnswerPassEnum.WAIT_REVIEW.getCode()); |
| | | // }else{ |
| | | // if(studentAnswer.getAnswer().equals(question.getAnswer())){ |
| | | // studentAnswer.setPassed(StudentAnswerPassEnum.CORRECT.getCode()); |
| | | // studentAnswer.setScore(); |
| | | // }else{ |
| | | // studentAnswer.setPassed(StudentAnswerPassEnum.ERROR.getCode()); |
| | | // studentAnswer.setScore(0); |
| | | // } |
| | | // } |
| | | ExStudentAnswer existAnswer= baseMapper.getStudentAnswer(studentAnswer); |
| | | if(existAnswer!=null){ |
| | | studentAnswer.setId(existAnswer.getId()); |
| | |
| | | |
| | | public void validData(ExStudentAnswer studentAnswer){ |
| | | ExPaperStudent paperStudent=paperStudentMapper.selectByPaperStudentId(new ExPaperStudent().setPaperId(studentAnswer.getPaperId()).setStudentId(studentAnswer.getStudentId())); |
| | | if(paperStudent.getCompleted()==1){ |
| | | if(!Objects.equals(paperStudent.getState(), PaperStudentStateEnum.WAIT_EXAM.getCode())){ |
| | | throw new ApiException("考试已完成,不能再作答"); |
| | | } |
| | | |
| | |
| | | import com.gkhy.exam.common.utils.PageUtils; |
| | | import com.gkhy.exam.common.utils.RedisUtils; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import com.gkhy.exam.system.domain.ExPaperStudent; |
| | | import com.gkhy.exam.system.domain.ExPhaseStudent; |
| | | import com.gkhy.exam.system.domain.ExStudent; |
| | | import com.gkhy.exam.system.domain.SysCompany; |
| | | import com.gkhy.exam.system.domain.vo.TrainRecordVO; |
| | | import com.gkhy.exam.system.mapper.ExPaperStudentMapper; |
| | | import com.gkhy.exam.system.mapper.ExPhaseStudentMapper; |
| | | import com.gkhy.exam.system.mapper.ExStudentMapper; |
| | | import com.gkhy.exam.system.mapper.SysUserMapper; |
| | | import com.gkhy.exam.system.service.ExStudentService; |
| | | import com.gkhy.exam.system.service.SysCompanyService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | private SysCompanyService companyService; |
| | | @Autowired |
| | | private RedisUtils redisUtils; |
| | | @Autowired |
| | | private ExPhaseStudentMapper phaseStudentMapper; |
| | | @Autowired |
| | | private ExPaperStudentMapper paperStudentMapper; |
| | | @Autowired |
| | | private SysUserMapper userMapper; |
| | | |
| | | @Override |
| | | public CommonPage selectStudentList(ExStudent student) { |
| | | SysUser currentUser= SecurityUtils.getLoginUser().getUser(); |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | student.setCompanyId(currentUser.getCompanyId()); |
| | | Map<String,Object> paramsMap=new HashMap<>(); |
| | | if(currentUser.getUserType().equals(UserTypeEnum.DEPART_USER.getCode())) {//部门级用户 |
| | | List<Long> workshopUserIds=userMapper.selectWorkshopUserIds(currentUser.getId()); |
| | | if(workshopUserIds==null){ |
| | | workshopUserIds=new ArrayList<>(); |
| | | } |
| | | workshopUserIds.add(currentUser.getId()); |
| | | paramsMap.put("createIds",workshopUserIds); |
| | | student.setParams(paramsMap); |
| | | }else if(currentUser.getUserType().equals(UserTypeEnum.WORKSHOP_USER.getCode())){//车间级用户 |
| | | List<Long> workshopUserIds=new ArrayList<>(); |
| | | workshopUserIds.add(currentUser.getId()); |
| | | workshopUserIds.add(currentUser.getParentId()); |
| | | paramsMap.put("createIds",workshopUserIds); |
| | | student.setParams(paramsMap); |
| | | } |
| | | } |
| | | PageUtils.startPage(); |
| | | List<ExStudent> studentList=baseMapper.selectStudentList(student); |
| | |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | return student; |
| | | }else if (currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | if(!Objects.equals(studentId, currentUser.getId())){ |
| | | throw new ApiException("无权查看其它学员信息"); |
| | | } |
| | | } |
| | | if(!student.getCompanyId().equals(currentUser.getCompanyId())){ |
| | | throw new ApiException("无权限查看其它企业学员"); |
| | |
| | | @Override |
| | | public int insertStudent(ExStudent student) { |
| | | SysUser currentUser= SecurityUtils.getLoginUser().getUser(); |
| | | student.setCompanyId(currentUser.getCompanyId()); |
| | | checkUserAllowed(student); |
| | | if(!checkPhoneUnique(student)){ |
| | | throw new ApiException("手机号已存在"); |
| | |
| | | if(!checkIdNoUnique(student)){ |
| | | throw new ApiException("身份证号已存在"); |
| | | } |
| | | student.setCreateId(currentUser.getId()); |
| | | if(currentUser.getUserType().equals(UserTypeEnum.COMPANY_USER.getCode())){ |
| | | if(student.getCreateId()==null){ |
| | | throw new ApiException("部门id为空"); |
| | | } |
| | | }else if(currentUser.getUserType().equals(UserTypeEnum.DEPART_USER.getCode())){ |
| | | student.setCreateId(currentUser.getId()); |
| | | }else{//当前用户为车间级用户 |
| | | if(currentUser.getParentId()==null){ |
| | | throw new ApiException("当前用户部门id为空"); |
| | | } |
| | | student.setCreateId(currentUser.getParentId()); |
| | | } |
| | | student.setPassword(SecurityUtils.encryptPassword(Base64.decodeStr(student.getPassword()))); |
| | | int row=baseMapper.insert(student); |
| | | if(row<0){ |
| | | throw new ApiException("新增学员失败"); |
| | |
| | | throw new ApiException("身份证号已存在"); |
| | | } |
| | | ExStudent existStudent=checkUserDataScope(student.getId()); |
| | | student.setPassword(null); |
| | | int row=baseMapper.updateById(student); |
| | | if(row<0){ |
| | | throw new ApiException("更新学员失败"); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public ExStudent checkIdNoUnique(String idNo) { |
| | | ExStudent stu= baseMapper.checkIdNoUnique(idNo); |
| | | if(stu!=null){ |
| | | SysCompany company=companyService.selectCompanyById(stu.getCompanyId()); |
| | | stu.setCompany(company); |
| | | public Map checkIdNoUnique(String idNo) { |
| | | if(StringUtils.isBlank(idNo)){ |
| | | throw new ApiException("身份证号不能为空"); |
| | | } |
| | | return stu; |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | ExStudent stu= baseMapper.checkIdNoUnique(idNo); |
| | | Map<String,Object> resMap=new HashMap<>(); |
| | | Integer status=0;//默认不存在 |
| | | if(stu!=null){ |
| | | status=1; //存在,且同一个公司 |
| | | resMap.put("studentId",stu.getId()); |
| | | resMap.put("studentName",stu.getName()); |
| | | if(stu.getCompanyId()!=currentUser.getCompanyId()){ |
| | | status=2; //存在,不同公司 |
| | | SysCompany company=companyService.selectCompanyById(stu.getCompanyId()); |
| | | if(company==null){ |
| | | throw new ApiException("学员公司不存在"); |
| | | } |
| | | resMap.put("companyId",company.getId()); |
| | | resMap.put("companyName",company.getName()); |
| | | } |
| | | } |
| | | resMap.put("status",status); |
| | | return resMap; |
| | | } |
| | | |
| | | @Override |
| | |
| | | su.setUpdateBy(SecurityUtils.getUsername()); |
| | | delCacheByPhone(existStudent.getPhone()); |
| | | return updateById(su); |
| | | } |
| | | |
| | | @Override |
| | | public void changeStudentCompany(Map<String, Long> bodyMap) { |
| | | Long studentId=bodyMap.get("studentId"); |
| | | Long companyId=bodyMap.get("companyId"); |
| | | if(studentId==null||companyId==null){ |
| | | throw new ApiException("学员id或者公司id不能为空"); |
| | | } |
| | | ExStudent student = baseMapper.selectById(studentId); |
| | | if(student==null){ |
| | | throw new ApiException("学员不存在"); |
| | | } |
| | | SysCompany company=companyService.selectCompanyById(companyId); |
| | | if(company==null){ |
| | | throw new ApiException("公司不存在"); |
| | | } |
| | | ExStudent stu=new ExStudent().setId(studentId).setCompanyId(companyId); |
| | | stu.setUpdateBy(SecurityUtils.getUsername()); |
| | | baseMapper.updateById(stu); |
| | | } |
| | | |
| | | @Override |
| | | public List<TrainRecordVO> trainRecord(Long studentId) { |
| | | List<TrainRecordVO> trainRecordVOList=new ArrayList<>(); |
| | | //查询培训记录 |
| | | List<ExPhaseStudent> phaseStudentList=phaseStudentMapper.selectPhaseStudentByStudentId(studentId); |
| | | if(phaseStudentList.size()>0){ |
| | | trainRecordVOList.addAll(phaseStudentList.stream().map(item -> { |
| | | TrainRecordVO trainRecordVO=new TrainRecordVO(); |
| | | trainRecordVO.setStudentId(item.getStudentId()); |
| | | trainRecordVO.setTrainType(1); |
| | | trainRecordVO.setName(item.getPhaseName()); |
| | | trainRecordVO.setCreateTime(item.getCreateTime()); |
| | | trainRecordVO.setCompanyId(item.getCompanyId()); |
| | | trainRecordVO.setCompanyName(item.getCompanyName()); |
| | | return trainRecordVO; |
| | | }).collect(Collectors.toList())); |
| | | } |
| | | //查询考试记录 |
| | | List<ExPaperStudent> paperStudentList=paperStudentMapper.selectByStudentId(studentId); |
| | | if(paperStudentList.size()>0){ |
| | | trainRecordVOList.addAll(paperStudentList.stream().map(item -> { |
| | | TrainRecordVO trainRecordVO=new TrainRecordVO(); |
| | | trainRecordVO.setStudentId(item.getStudentId()); |
| | | trainRecordVO.setTrainType(2); |
| | | trainRecordVO.setName(item.getExamPaper().getName()); |
| | | trainRecordVO.setCreateTime(item.getCreateTime()); |
| | | trainRecordVO.setCompanyId(item.getCompanyId()); |
| | | trainRecordVO.setCompanyName(item.getCompanyName()); |
| | | return trainRecordVO; |
| | | }).collect(Collectors.toList())); |
| | | } |
| | | //排序 |
| | | trainRecordVOList=trainRecordVOList.stream().sorted(Comparator.comparing(TrainRecordVO::getCreateTime)).collect(Collectors.toList());; |
| | | return trainRecordVOList; |
| | | } |
| | | |
| | | public ExStudent checkUserDataScope(Long studentId) { |
| | |
| | | |
| | | public void checkUserAllowed(ExStudent student) { |
| | | SysUser currentUser= SecurityUtils.getLoginUser().getUser(); |
| | | if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | throw new ApiException("系统管理员没有权限操作"); |
| | | if(student.getId()!=null){ |
| | | if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | return; |
| | | } |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode()) ){ |
| | | if(!Objects.equals(currentUser.getId(), student.getId())){ |
| | | throw new ApiException("没有权限操作"); |
| | | }else{ |
| | | return; |
| | | } |
| | | } |
| | | }else{ |
| | | if(currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | throw new ApiException("系统管理员没有权限操作"); |
| | | } |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | } |
| | | if(currentUser.getUserType().equals(UserTypeEnum.STUDENT.getCode())){ |
| | | throw new ApiException("没有权限操作"); |
| | | } |
| | | if(!currentUser.getCompanyId().equals(student.getCompanyId())){ |
| | | |
| | | if(student.getCompanyId()!=null&&!currentUser.getCompanyId().equals(student.getCompanyId())){ |
| | | throw new ApiException("没有权限操作其他企业学员"); |
| | | } |
| | | } |
| | |
| | | row=baseMapper.updateById(existStudentStudy); |
| | | }else{ |
| | | row=baseMapper.insert(studentStudy); |
| | | if(row<1){ |
| | | throw new ApiException("新增学习记录失败"); |
| | | } |
| | | } |
| | | if(row<1){ |
| | | throw new ApiException("新增学习记录失败"); |
| | | } |
| | | System.out.println("student_study id:"+studentStudy.getId()); |
| | | return studentStudy.getId(); |
| | | } |
| | | |
| | |
| | | studentStudyPeriodVO.setPeriodId(courseChapterPeriod.getId()); |
| | | studentStudyPeriodVO.setPeriod(courseChapterPeriod.getPeriod()); |
| | | studentStudyPeriodVO.setResourceId(courseChapterPeriod.getResourceId()); |
| | | studentStudyPeriodVO.setResourceType(courseChapterPeriod.getResource()!=null?courseChapterPeriod.getResource().getResourceType():null); |
| | | ExStudentStudy exStudentStudy=studentStudyMap.get(courseChapterPeriod.getId()); |
| | | if(exStudentStudy!=null){ |
| | | studentStudyPeriodVO.setProgress(exStudentStudy.getProgress()); |
| | |
| | | |
| | | @Override |
| | | public void progress(ExStudentStudy studentStudy) { |
| | | if(studentStudy.getPhaseId()==null||studentStudy.getPeriodId()==null||studentStudy.getStudentId()==null||studentStudy.getResourceId()==null){ |
| | | if(studentStudy.getId()==null||studentStudy.getPhaseId()==null||studentStudy.getPeriodId()==null||studentStudy.getStudentId()==null||studentStudy.getResourceId()==null){ |
| | | throw new ApiException("参数传参错误"); |
| | | } |
| | | ExResource resource=resourceMapper.selectById(studentStudy.getResourceId()); |
| | |
| | | } |
| | | } else if (ResourceTypeEnum.DOC.getCode().equals(resource.getResourceType())) { |
| | | // 文档类型处理 |
| | | if (studentStudy.getCurrentPage().compareTo(resource.getDocPage()) >= 0) { |
| | | // 学习完成 |
| | | completeStudy(studentStudy); |
| | | } |
| | | // if (studentStudy.getCurrentPage().compareTo(resource.getDocPage()) >= 0) { |
| | | // // 学习完成 |
| | | // completeStudy(studentStudy); |
| | | // } |
| | | // 学习完成 |
| | | completeStudy(studentStudy); |
| | | } |
| | | redisUtils.set(CacheConstant.STUDY_PROCESS_KEY + studentStudy.getId(), studentStudy, 1, TimeUnit.DAYS); |
| | | } |
| | |
| | | |
| | | @Override |
| | | public CommonPage selectCarouselList(SysCarousel carousel) { |
| | | PageUtils.startPage(); |
| | | List<SysCarousel> carousels=baseMapper.selectCarouselList(carousel); |
| | | return CommonPage.restPage(carousels); |
| | | PageUtils.startPage(); |
| | | List<SysCarousel> carousels = baseMapper.selectCarouselList(carousel); |
| | | return CommonPage.restPage(carousels); |
| | | } |
| | | |
| | | @Override |
| | |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.system.domain.SysCategory; |
| | | import com.gkhy.exam.system.mapper.ExCourseMapper; |
| | | import com.gkhy.exam.system.mapper.ExQuestionBankMapper; |
| | | import com.gkhy.exam.system.mapper.SysCategoryMapper; |
| | | import com.gkhy.exam.system.service.SysCategoryService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Comparator; |
| | |
| | | */ |
| | | @Service |
| | | public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCategory> implements SysCategoryService { |
| | | @Autowired |
| | | private ExCourseMapper courseMapper; |
| | | @Autowired |
| | | private ExQuestionBankMapper questionBankMapper; |
| | | |
| | | @Override |
| | | public List<SysCategory> selectCategoryList(SysCategory category) { |
| | |
| | | public int deleteCategoryById(Long categoryId) { |
| | | //校验课程分类是否存在课程或者题目 |
| | | checkUserAllowed(); |
| | | int courseCount=baseMapper.selectCountOfCoure(categoryId); |
| | | int courseCount=courseMapper.selectCountByCategoryId(categoryId); |
| | | if(courseCount>0){ |
| | | throw new ApiException("已绑定课程,无法删除"); |
| | | } |
| | | int bankCount=baseMapper.selectCountOfBank(categoryId); |
| | | int bankCount=questionBankMapper.selectCountByCategoryId(categoryId); |
| | | if(bankCount>0){ |
| | | throw new ApiException("已绑定题库,无法删除"); |
| | | } |
| | | int row=baseMapper.deleteById(categoryId); |
| | | int row=baseMapper.deleteByCategoryId(categoryId); |
| | | if(row<1){ |
| | | throw new ApiException("删除课程分类失败"); |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.io.FileUtil; |
| | | import com.alibaba.excel.EasyExcel; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.gkhy.exam.common.config.FilePathConfig; |
| | | import com.gkhy.exam.common.config.MinioConfig; |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.ResourceTypeEnum; |
| | | import com.gkhy.exam.common.enums.UserTypeEnum; |
| | | import com.gkhy.exam.common.excel.StudentExcelData; |
| | | import com.gkhy.exam.common.excel.StudentExcelDataListener; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.*; |
| | | import com.gkhy.exam.system.domain.ExResource; |
| | | import com.gkhy.exam.system.domain.ExStudent; |
| | | import com.gkhy.exam.system.domain.SysCompany; |
| | | import com.gkhy.exam.system.domain.vo.UploadObjectVO; |
| | | import com.gkhy.exam.system.mapper.ExResourceMapper; |
| | | import com.gkhy.exam.system.service.ExStudentService; |
| | | import com.gkhy.exam.system.service.SysCommonService; |
| | | import com.gkhy.exam.system.service.SysCompanyService; |
| | | import com.gkhy.exam.system.service.SysUserService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.io.FileUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import sun.misc.BASE64Decoder; |
| | |
| | | @Slf4j |
| | | public class SysCommonServiceImpl implements SysCommonService { |
| | | |
| | | @Autowired |
| | | private MinioConfig minioConfig; |
| | | |
| | | @Value("${image.upload_image}") |
| | | private String uploadPath; |
| | | @Autowired |
| | |
| | | private ExResourceMapper resourceMapper; |
| | | @Resource |
| | | private FilePathConfig filePathConfig; |
| | | @Autowired |
| | | private SysCompanyService companyService; |
| | | @Autowired |
| | | private ExStudentService studentService; |
| | | @Autowired |
| | | private SysUserService userService; |
| | | |
| | | // 使用HashSet存储允许的文件格式,提高查找效率 |
| | | private final HashSet<String> FORMATSET = new HashSet<>(Arrays.asList(".mp4", ".mp3", ".xls", ".xlsx", ".doc", ".docx", ".ppt", ".pptx", ".pdf")); |
| | | private final HashSet<String> FORMATSET = new HashSet<>(Arrays.asList(".mp4",".doc", ".docx", ".ppt", ".pptx", ".pdf")); |
| | | |
| | | |
| | | @Resource(name = "threadPoolTaskExecutor") |
| | |
| | | log.warn("临时目录 {}已删除", new File(localPath).getParent()); |
| | | }); |
| | | uploadObjectVO.setPath(minioPath); |
| | | uploadObjectVO.setUrl(minioConfig.getEndpoint()+minioConfig.getBucketName()+"/"+minioPath); |
| | | return uploadObjectVO; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = RuntimeException.class) |
| | | public void importStudent() { |
| | | String path="/home/java/train_exam/back/安全教育学员模板.xlsx"; |
| | | // String path="F:/kzy/乱七八糟/安全教育学员模板.xlsx"; |
| | | List<StudentExcelData> studentExcelDataList=EasyExcel.read(path, StudentExcelData.class,new StudentExcelDataListener()).sheet().doReadSync(); |
| | | List<ExStudent> students=new ArrayList<>(); |
| | | List<StudentExcelData> errorStudents=new ArrayList<>(); |
| | | SysCompany company=companyService.getOne(Wrappers.<SysCompany>lambdaQuery().eq(SysCompany::getName,studentExcelDataList.get(0).getCompanyName()) |
| | | .eq(SysCompany::getDelFlag,0)); |
| | | if(company==null){ |
| | | throw new ApiException("公司不存在"); |
| | | } |
| | | for(StudentExcelData studentExcelData:studentExcelDataList){ |
| | | String errorMessage=validateData(studentExcelData); |
| | | if(StringUtils.isNotBlank(errorMessage)){ |
| | | studentExcelData.setRemark(errorMessage); |
| | | errorStudents.add(studentExcelData); |
| | | continue; |
| | | } |
| | | ExStudent dbStudent=studentService.getOne(Wrappers.<ExStudent>lambdaQuery().eq(ExStudent::getPhone,studentExcelData.getPhone())); |
| | | if(dbStudent!=null){ |
| | | if(!dbStudent.getName().equals(studentExcelData.getName())){ |
| | | studentExcelData.setRemark("序号"+studentExcelData.getIndex()+"学员用户已存在"); |
| | | errorStudents.add(studentExcelData); |
| | | } |
| | | continue; |
| | | } |
| | | ExStudent student=new ExStudent(); |
| | | BeanUtils.copyProperties(studentExcelData,student,new String[]{"sex"}); |
| | | if("男".equals(studentExcelData.getSex())){ |
| | | student.setSex(0); |
| | | }else{ |
| | | student.setSex(1); |
| | | } |
| | | String departName=studentExcelData.getDeptName(); |
| | | |
| | | List<SysUser> users=userService.list(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getName,departName).eq(SysUser::getUserType, UserTypeEnum.DEPART_USER.getCode()).eq(SysUser::getDelFlag,0).last(" limit 1")); |
| | | if(users.isEmpty()){ |
| | | studentExcelData.setRemark("序号"+studentExcelData.getIndex()+"未找到相应的部门账号"); |
| | | errorStudents.add(studentExcelData); |
| | | continue; |
| | | } |
| | | |
| | | student.setPassword(SecurityUtils.encryptPassword("123456@a")); |
| | | student.setCompanyId(company.getId()); |
| | | student.setCreateId(users.get(0).getId()); |
| | | students.add(student); |
| | | } |
| | | if(!errorStudents.isEmpty()){ |
| | | EasyExcel.write("error.xlsx").head(StudentExcelData.class) |
| | | .sheet("异常用户列表") |
| | | .doWrite(errorStudents); |
| | | } |
| | | studentService.saveBatch(students); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | public String validateData(StudentExcelData studentExcelData){ |
| | | if(StringUtils.isBlank(studentExcelData.getName())){ |
| | | return "序号"+studentExcelData.getIndex()+"姓名为空"; |
| | | } |
| | | if(StringUtils.isBlank(studentExcelData.getSex())){ |
| | | return "序号"+studentExcelData.getIndex()+"性别为空"; |
| | | } |
| | | if(StringUtils.isBlank(studentExcelData.getIdNo())||studentExcelData.getIdNo().length()!=18){ |
| | | return "序号"+studentExcelData.getIndex()+"身份证为空或者长度不正确"; |
| | | } |
| | | if(StringUtils.isBlank(studentExcelData.getPhone())||studentExcelData.getPhone().length()!=11){ |
| | | return "序号"+studentExcelData.getIndex()+"手机号为空或者长度不正确"; |
| | | } |
| | | |
| | | if(StringUtils.isBlank(studentExcelData.getDeptName())){ |
| | | return "序号"+studentExcelData.getIndex()+"部门为空"; |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | public UploadObjectVO mergeFile(String fileMd5,String fileName){ |
| | | String subfix = fileName.substring(fileName.lastIndexOf(".")); |
| | | String systemDir=System.getProperty("user.dir"); |
| | |
| | | throw new ApiException("公司名称已存在"); |
| | | } |
| | | company.setCreateBy(SecurityUtils.getUsername()); |
| | | company.setRemainPeriod(company.getTotalPeriod()); |
| | | int row= baseMapper.insert(company); |
| | | if(row<1){ |
| | | throw new ApiException("新增公司失败"); |
| | |
| | | import com.gkhy.exam.common.domain.entity.SysUser; |
| | | import com.gkhy.exam.common.enums.UserTypeEnum; |
| | | import com.gkhy.exam.common.exception.ApiException; |
| | | import com.gkhy.exam.common.utils.*; |
| | | import com.gkhy.exam.common.utils.PageUtils; |
| | | import com.gkhy.exam.common.utils.RedisUtils; |
| | | import com.gkhy.exam.common.utils.SecurityUtils; |
| | | import com.gkhy.exam.common.utils.StringUtils; |
| | | import com.gkhy.exam.system.mapper.SysUserMapper; |
| | | import com.gkhy.exam.system.service.SysConfigService; |
| | | import com.gkhy.exam.system.service.SysUserService; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.validation.Validator; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | @Override |
| | | public CommonPage<SysUser> selectUserList(SysUser user) { |
| | | SysUser currentUser=SecurityUtils.getLoginUser().getUser(); |
| | | Map<String,Object> paramsMap=new HashMap<>(); |
| | | paramsMap.put("userType",currentUser.getUserType()); |
| | | user.setParams(paramsMap); |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | user.setCompanyId(currentUser.getCompanyId()); |
| | | List<SysUser> users=new ArrayList<>(); |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.WORKSHOP_USER.getCode())){ |
| | | if(!currentUser.getUserType().equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | user.setCompanyId(currentUser.getCompanyId()); |
| | | Map<String,Object> paramsMap=new HashMap<>(); |
| | | paramsMap.put("userType",currentUser.getUserType()); |
| | | user.setParams(paramsMap); |
| | | } |
| | | PageUtils.startPage(); |
| | | users=baseMapper.userList(user); |
| | | } |
| | | PageUtils.startPage(); |
| | | List<SysUser> users=baseMapper.userList(user); |
| | | return CommonPage.restPage(users); |
| | | } |
| | | |
| | |
| | | checkRequestData(user); |
| | | checkUserAllowed(user); |
| | | user.setUpdateBy(SecurityUtils.getUsername()); |
| | | user.setPassword(null); |
| | | int row=baseMapper.updateById(user); |
| | | if(row<1){ |
| | | throw new ApiException("更新用户信息失败"); |
| | |
| | | Integer currentUserType=currentUser.getUserType(); |
| | | Integer userType=user.getUserType(); |
| | | //校验权限,规则:上一级用户可以增加下一级用户类型的用户 |
| | | if(!currentUserType.equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | if(currentUserType.equals(UserTypeEnum.SYSTEM_USER.getCode())){ |
| | | if( !userType.equals(UserTypeEnum.SYSTEM_USER.getCode())&&!userType.equals(UserTypeEnum.OTHER_USER.getCode()) &&!userType.equals(UserTypeEnum.COMPANY_USER.getCode())){ |
| | | throw new ApiException("管理员只能操作管理员、企业级和其他类型的用户"); |
| | | } |
| | | }else{ |
| | | if(userType.equals(UserTypeEnum.OTHER_USER.getCode())){ |
| | | throw new ApiException("没有权限操作或者更新上级用户类型的用户"); |
| | | } |
| | |
| | | <result property="id" column="resource_id" /> |
| | | <result property="name" column="resource_name" /> |
| | | <result property="resourcePath" column="resource_path" /> |
| | | <result property="resourceType" column="resource_type" /> |
| | | <result property="resourceLength" column="period" /> |
| | | <result property="docPage" column="doc_page" /> |
| | | </resultMap> |
| | | |
| | | <sql id="selectChapterVo"> |
| | |
| | | </select> |
| | | |
| | | <select id="getChapterPeriodByChapterId" resultMap="ExPeriodResult"> |
| | | select a.id,a.name,a.course_id,a.chapter_id,a.status,a.company_id,a.resource_id, |
| | | b.resource_length as period,b.name as resource_name,b.resource_path from ex_course_chapter_period a |
| | | select a.id,a.name,a.course_id,a.chapter_id,a.status,a.company_id,a.resource_id,a.sort, |
| | | b.resource_length as period,b.name as resource_name,b.resource_path,b.doc_page,b.resource_type from ex_course_chapter_period a |
| | | left join ex_resource b on b.id=a.resource_id |
| | | where a.chapter_id=#{chapterId} |
| | | <if test="status!=null"> |
| | |
| | | select * from ex_course_chapter_period where chapter_id=#{chapterId} |
| | | </select> |
| | | |
| | | <select id="selectCountByCourseId" resultType="java.lang.Integer" parameterType="java.lang.Long"> |
| | | select count(1) from ex_course_chapter_period where course_id=#{courseId} and status=0 |
| | | </select> |
| | | |
| | | |
| | | </mapper> |
| | |
| | | <result property="delFlag" column="del_flag" /> |
| | | <result property="companyId" column="company_id" /> |
| | | <result property="privatize" column="privatize" /> |
| | | <result property="period" column="period" /> |
| | | <result property="message" column="message" /> |
| | | <result property="version" column="version" /> |
| | | <result property="createBy" column="create_by" /> |
| | | <result property="createTime" column="create_time" /> |
| | |
| | | <result property="remark" column="remark" /> |
| | | <result property="companyName" column="company_name" /> |
| | | <result property="categoryName" column="category_name" /> |
| | | <association property="period" javaType="java.lang.Long" select="getCoursePeriod" column="{courseId=id}"/> |
| | | </resultMap> |
| | | |
| | | <sql id="selectCourseVo"> |
| | | select a.id, a.name, a.category_id, a.status, a.logo,a.sort,a.introduce,a.state,a.company_id, |
| | | a.privatize,a.period,a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as company_name,c.name as category_name |
| | | select a.id, a.name, a.category_id, a.status, a.logo,a.sort,a.introduce,a.state,a.company_id,a.message, |
| | | a.privatize,a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as company_name,c.name as category_name |
| | | from ex_course a |
| | | left join sys_company b on b.id=a.company_id |
| | | left join sys_category c on c.id=a.category_id |
| | |
| | | </select> |
| | | |
| | | <select id="checkNameUnique" resultType="com.gkhy.exam.system.domain.ExCourse"> |
| | | select id,name from ex_course where name=#{name} and company_id=#{companyId} and del_flag=0 limit 1 |
| | | select id,name from ex_course where name=#{name} and del_flag=0 |
| | | <if test="companyId!=null"> |
| | | and company_id=#{companyId} |
| | | </if> |
| | | limit 1 |
| | | </select> |
| | | |
| | | <select id="selectCourseState" resultType="java.lang.Integer"> |
| | | select state from ex_course where id=#{courseId} |
| | | </select> |
| | | |
| | | <select id="selectCountByCategoryId" resultType="java.lang.Integer"> |
| | | select count(1) from ex_course where category_id=#{categoryId} and del_flag=0 |
| | | </select> |
| | | |
| | | <select id="getCoursePeriod" resultType="java.lang.Long"> |
| | | select sum(b.resource_length) from ex_course_chapter_period a |
| | | inner join ex_resource b on a.resource_id=b.id |
| | | where a.course_id=#{courseId} |
| | | </select> |
| | | </mapper> |
| | |
| | | <result property="updateBy" column="update_by" /> |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="remark" column="remark" /> |
| | | <result property="coursePeriod" column="course_period" /> |
| | | <result property="courseName" column="course_name" /> |
| | | <result property="companyName" column="company_name" /> |
| | | <result property="studentCount" column="student_count" /> |
| | | <result property="finishCount" column="finish_count" /> |
| | | <association property="coursePeriod" javaType="java.lang.Long" select="getCoursePeriod" column="{courseId=course_id}"/> |
| | | <association property="finishCount" javaType="java.lang.Integer" select="getFinishStudentCount" column="{courseId=course_id,phaseId=id}"/> |
| | | </resultMap> |
| | | |
| | | <sql id="selectCoursePhaseVo"> |
| | | select a.id, a.name, a.code, a.company_id, a.course_id,a.level,a.del_flag,a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.period as course_period |
| | | select a.id, a.name, a.code, a.company_id, a.course_id,a.level,a.del_flag,a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as course_name |
| | | from ex_course_phase a |
| | | left join ex_course b on b.id=a.course_id |
| | | </sql> |
| | |
| | | </update> |
| | | |
| | | <select id="selectCoursePhaseList" resultMap="ExCoursePhaseResult"> |
| | | <include refid="selectCoursePhaseVo"/> |
| | | select a.id, a.name, a.code, a.company_id, a.course_id,a.level,a.del_flag,a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark, |
| | | b.name as course_name,c.name as company_name, |
| | | (select count(1) from ex_phase_student where phase_id=a.id) as student_count |
| | | from ex_course_phase a |
| | | left join ex_course b on b.id=a.course_id |
| | | left join sys_company c on c.id=a.company_id |
| | | <where> |
| | | and a.del_flag=0 |
| | | <if test="name != null and name != ''"> |
| | |
| | | </if> |
| | | <if test="courseId != null and courseId != ''"> |
| | | AND a.course_id =#{courseId} |
| | | </if> |
| | | <if test="level != null"> |
| | | AND a.level =#{level} |
| | | </if> |
| | | </where> |
| | | order by a.create_time desc |
| | |
| | | select count(1) from ex_course_phase where del_flag=0 and courde_id=#{courseId} |
| | | </select> |
| | | |
| | | <select id="getCoursePeriod" resultType="java.lang.Long"> |
| | | select sum(b.resource_length) from ex_course_chapter_period a |
| | | inner join ex_resource b on a.resource_id=b.id |
| | | where a.course_id=#{courseId} |
| | | </select> |
| | | |
| | | <select id="getFinishStudentCount" resultType="java.lang.Integer"> |
| | | select count(1) from (select student_id,count(1) as study_count from ex_student_study where phase_id=#{phaseId} group by student_id) as a |
| | | where a.study_count=(select count(1) as period_count from ex_course_chapter_period where course_id=#{courseId}) |
| | | </select> |
| | | </mapper> |
| | |
| | | <result property="companyId" column="company_id" /> |
| | | <result property="categoryId" column="category_id" /> |
| | | <result property="limitTime" column="limit_time" /> |
| | | <result property="limit" column="limit" /> |
| | | <result property="limited" column="limited" /> |
| | | <result property="singleNum" column="single_num" /> |
| | | <result property="singleScore" column="single_score" /> |
| | | <result property="singleBankId" column="single_bank_id" /> |
| | |
| | | <result property="judgeScore" column="judge_score" /> |
| | | <result property="judgeBankId" column="judge_bank_id" /> |
| | | <result property="judgeMethod" column="judge_method" /> |
| | | <result property="easyNum" column="easy_num" /> |
| | | <result property="easyScore" column="easy_score" /> |
| | | <result property="easyBankId" column="easy_bank_id" /> |
| | | <result property="easyMethod" column="easy_method" /> |
| | | <result property="passScore" column="pass_score" /> |
| | | <result property="version" column="version" /> |
| | | <result property="delFlag" column="del_flag" /> |
| | | <result property="createBy" column="create_by" /> |
| | | <result property="deadline" column="deadline" /> |
| | | <result property="createTime" column="create_time" /> |
| | | <result property="updateBy" column="update_by" /> |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="remark" column="remark" /> |
| | | <result property="companyName" column="company_name" /> |
| | | <collection property="singleQuestions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=id,questionType=1}"/> |
| | | <collection property="multiQuestions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=id,questionType=2}"/> |
| | | <collection property="judgeQuestions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=id,questionType=3}"/> |
| | | <result property="categoryName" column="category_name" /> |
| | | <association property="paperStudentInfoVO" javaType="com.gkhy.exam.system.domain.vo.PaperStudentInfoVO" select="getPaperStudentInfoByPaperId" column="{paperId=id}"/> |
| | | </resultMap> |
| | | <resultMap type="com.gkhy.exam.system.domain.ExExamPaper" id="ExamPaperResult2" extends="ExamPaperResult"> |
| | | <collection property="questions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=id}"/> |
| | | </resultMap> |
| | | |
| | | |
| | | |
| | | <sql id="selectExamPaperVo"> |
| | | select a.id, a.name, a.code, a.status, a.company_id,a.category_id,a.limit_time,a.limit,a.single_num,a.single_score,a.single_bank_id, |
| | | select a.id, a.name, a.code, a.status, a.company_id,a.category_id,a.deadline,a.limit_time,a.limited,a.single_num,a.single_score,a.single_bank_id, |
| | | a.single_method,a.multi_num,a.multi_score, |
| | | a.multi_bank_id,a.multi_method,a.judge_num,a.judge_score,a.judge_bank_id,a.judge_method,a.pass_score, |
| | | a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as company_name |
| | | a.easy_num,a.easy_score,a.easy_bank_id,a.easy_method, |
| | | a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as company_name,c.name as category_name |
| | | from ex_exam_paper a |
| | | left join sys_company b on b.id=a.company_id |
| | | left join sys_category c on c.id=a.category_id |
| | | </sql> |
| | | |
| | | <update id="deletePaperById"> |
| | |
| | | <if test="companyId != null and companyId != ''"> |
| | | AND a.company_id= #{companyId} |
| | | </if> |
| | | <if test="categoryId != null and categoryId != ''"> |
| | | AND a.category_id= #{categoryId} |
| | | </if> |
| | | </where> |
| | | order by a.id desc |
| | | </select> |
| | | |
| | | <select id="selectExamPaperById" resultMap="ExamPaperResult"> |
| | | <select id="selectExamPaperById" resultMap="ExamPaperResult2"> |
| | | <include refid="selectExamPaperVo"/> |
| | | where a.id=#{paperId} |
| | | </select> |
| | |
| | | </select> |
| | | |
| | | <select id="checkNameUnique" resultType="com.gkhy.exam.system.domain.ExExamPaper"> |
| | | select id ,name from ex_exam_paper where name=#{name} limit 1 |
| | | select id ,name from ex_exam_paper where name=#{name} and del_flag=0 |
| | | <if test="companyId!=null"> |
| | | and company_id=#{companyId} |
| | | </if> |
| | | limit 1 |
| | | </select> |
| | | |
| | | <select id="getQuestionByPaperId" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | select a.* from ex_question a |
| | | inner join ex_paper_question b on a.id=b.question_id |
| | | where b.paper_id=#{paperId} and a.question_type=#{questionType} |
| | | order by a.id asc |
| | | where b.paper_id=#{paperId} |
| | | order by a.question_type asc,a.id asc |
| | | </select> |
| | | |
| | | <select id="getPaperStudentInfoByPaperId" resultType="com.gkhy.exam.system.domain.vo.PaperStudentInfoVO"> |
| | | select count(1) as student_count,ifnull(sum(passed),0) pass_student_count,ROUND(ifnull(avg(score),0),2) as avg_score, |
| | | (select count(1) from ex_paper_student where paper_id=#{paperId} and state!=0) as finish_count |
| | | from ex_paper_student where paper_id=#{paperId} |
| | | </select> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="remark" column="remark" /> |
| | | <result property="companyName" column="company_name" /> |
| | | <association property="student" javaType="com.gkhy.exam.system.domain.ExStudent" resultMap="exStudentResult" /> |
| | | </resultMap> |
| | | |
| | | <resultMap id="exStudentResult" type="com.gkhy.exam.system.domain.ExStudent"> |
| | | <result property="id" column="student_id" /> |
| | | <result property="name" column="student_name" /> |
| | | <result property="phone" column="student_phone" /> |
| | | <result property="idNo" column="student_idno" /> |
| | | </resultMap> |
| | | |
| | | <sql id="selectExamRecordVo"> |
| | | select a.id, a.company_id, a.student_id, a.plan_name, a.course_name,a.level,a.period,a.actual_period,a.score, |
| | | a.company_id,a.passed, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as company_name |
| | | a.company_id,a.passed, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as company_name, |
| | | c.name as student_name,c.id_no as student_idno,c.phone as student_phone |
| | | from ex_exam_record a |
| | | left join sys_company b on b.id=a.company_id |
| | | left join ex_student c on c.id=a.student_id |
| | | </sql> |
| | | |
| | | <select id="selectExamRecordList" resultMap="ExamRecordResult"> |
| | |
| | | </delete> |
| | | |
| | | <select id="getExerciseAnswer" resultType="com.gkhy.exam.system.domain.ExExerciseAnswer"> |
| | | select * from ex_exercise_answer where bank_id=#{bankId} and qustion_id=#{questionId} and student_id=#{studentId} limit 1 |
| | | select * from ex_exercise_answer where bank_id=#{bankId} and question_id=#{questionId} and student_id=#{studentId} limit 1 |
| | | </select> |
| | | </mapper> |
| | |
| | | </delete> |
| | | |
| | | <delete id="deletePaperQuestion"> |
| | | delete from ex_paper_question |
| | | delete a from ex_paper_question as a |
| | | inner join ex_question as b on b.id=a.question_id |
| | | <where> |
| | | and paper_id=#{paperId} |
| | | and a.paper_id=#{paperId} |
| | | <if test="questionType!=null"> |
| | | and question_type=#{questionType} |
| | | and b.question_type=#{questionType} |
| | | </if> |
| | | </where> |
| | | </delete> |
| | |
| | | <result property="score" column="score" /> |
| | | <result property="passed" column="passed" /> |
| | | <result property="useTime" column="use_time" /> |
| | | <result property="completed" column="completed" /> |
| | | <result property="state" column="state" /> |
| | | <result property="version" column="version" /> |
| | | <result property="createBy" column="create_by" /> |
| | | <result property="createTime" column="create_time" /> |
| | |
| | | <result property="createName" column="create_name" /> |
| | | <association property="student" javaType="com.gkhy.exam.system.domain.ExStudent" resultMap="exStudentResult" /> |
| | | <association property="examPaper" javaType="com.gkhy.exam.system.domain.ExExamPaper" resultMap="exExamPaperResult" /> |
| | | <collection property="singleQuestions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=paper_id,studentId=student_id,completed=completed,questionType=1}"/> |
| | | <collection property="multiQuestions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=paper_id,studentId=student_id,completed=completed,questionType=2}"/> |
| | | <collection property="judgeQuestions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=paper_id,studentId=student_id,completed=completed,questionType=3}"/> |
| | | </resultMap> |
| | | <collection property="questions" ofType="com.gkhy.exam.system.domain.ExQuestion" select="getQuestionByPaperId" column="{paperId=paper_id,studentId=student_id,state=state}"/> |
| | | </resultMap> |
| | | |
| | | |
| | | <resultMap type="com.gkhy.exam.system.domain.ExPaperStudent" id="SimplePaperStudentResult"> |
| | |
| | | <result property="score" column="score" /> |
| | | <result property="passed" column="passed" /> |
| | | <result property="useTime" column="use_time" /> |
| | | <result property="completed" column="completed" /> |
| | | <result property="startTime" column="start_time" /> |
| | | <result property="state" column="state" /> |
| | | <result property="version" column="version" /> |
| | | <result property="createBy" column="create_by" /> |
| | | <result property="createTime" column="create_time" /> |
| | |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="remark" column="remark" /> |
| | | <result property="createName" column="create_name" /> |
| | | <result property="companyId" column="company_id" /> |
| | | <result property="companyName" column="company_name" /> |
| | | <association property="student" javaType="com.gkhy.exam.system.domain.ExStudent" resultMap="exStudentResult" /> |
| | | <association property="examPaper" javaType="com.gkhy.exam.system.domain.ExExamPaper" resultMap="exExamPaperResult" /> |
| | | </resultMap> |
| | | |
| | | <resultMap type="com.gkhy.exam.system.domain.ExQuestion" id="ExQuestionResult"> |
| | | <result property="id" column="id" /> |
| | | <result property="questionType" column="question_type" /> |
| | | <result property="bankId" column="bank_id" /> |
| | | <result property="status" column="status" /> |
| | | <result property="companyId" column="company_id" /> |
| | | <result property="status" column="status" /> |
| | | <result property="answer" column="answer" /> |
| | | <result property="title" column="title" /> |
| | | <result property="privatize" column="privatize" /> |
| | | <result property="content" column="content" /> |
| | | <association property="studentAnswer" javaType="com.gkhy.exam.system.domain.ExStudentAnswer" resultMap="studentAnswerResult" /> |
| | | </resultMap> |
| | | |
| | |
| | | <result property="questionId" column="answer_question_id" /> |
| | | <result property="answer" column="answer_answer" /> |
| | | <result property="passed" column="answer_passed" /> |
| | | <result property="score" column="answer_score" /> |
| | | </resultMap> |
| | | |
| | | <resultMap id="exExamPaperResult" type="com.gkhy.exam.system.domain.ExExamPaper"> |
| | |
| | | <result property="code" column="paper_code" /> |
| | | <result property="name" column="paper_name" /> |
| | | <result property="categoryName" column="category_name" /> |
| | | <result property="limited" column="limited" /> |
| | | <result property="limitTime" column="limit_time" /> |
| | | <result property="deadline" column="deadline" /> |
| | | <result property="singleNum" column="single_num" /> |
| | | <result property="multiNum" column="multi_num" /> |
| | | <result property="judgeNum" column="judge_num" /> |
| | | <result property="easyNum" column="easy_num" /> |
| | | <result property="singleScore" column="single_score" /> |
| | | <result property="multiScore" column="multi_score" /> |
| | | <result property="judgeScore" column="judge_score" /> |
| | | <result property="easyScore" column="easy_score" /> |
| | | </resultMap> |
| | | |
| | | <resultMap id="exStudentResult" type="com.gkhy.exam.system.domain.ExStudent"> |
| | |
| | | </resultMap> |
| | | |
| | | <insert id="batchInsert"> |
| | | insert into ex_paper_student(paper_id,student_id) values |
| | | insert into ex_paper_student(paper_id,student_id,create_id) values |
| | | <foreach collection="list" item="item" index="index" separator=","> |
| | | (#{item.paperId},#{item.studentId}) |
| | | (#{item.paperId},#{item.studentId},#{item.createId}) |
| | | </foreach> |
| | | </insert> |
| | | |
| | | <update id="batchUpdateComplete"> |
| | | update ex_paper_student set completed=#{completed} |
| | | where id in |
| | | <foreach collection="paperStudentIds" item="item" open="(" separator="," close=")"> |
| | | #{item} |
| | | </foreach> |
| | | </update> |
| | | |
| | | <select id="countByPaperId" resultType="java.lang.Integer"> |
| | | select count(1) from ex_paper_student where paper_id=#{paperId} |
| | |
| | | </select> |
| | | |
| | | <select id="selectPaperStudentList" resultMap="SimplePaperStudentResult"> |
| | | select a.*,e.name as create_name,b.phone as student_phone,b.name as student_name,c.name as paper_name,c.id as paper_id,c.code as paper_code,d.name as category_name from ex_paper_student a |
| | | select a.*,e.name as create_name,b.phone as student_phone,b.name as student_name,c.name as paper_name,c.code as paper_code,c.limited,c.limit_time,c.deadline,d.name as category_name |
| | | <if test="studentId!=null"> |
| | | ,(select question_id from ex_student_answer where paper_id=a.paper_id and student_id=#{studentId} order by id desc limit 1) as question_id |
| | | </if> |
| | | from ex_paper_student a |
| | | left join ex_student b on a.student_id=b.id |
| | | left join ex_exam_paper c on c.id=a.paper_id |
| | | left join sys_category d on d.id=c.category_id |
| | |
| | | <if test="studentId!=null"> |
| | | and a.student_id = #{studentId} |
| | | </if> |
| | | <if test="state!=null"> |
| | | and a.state = #{state} |
| | | </if> |
| | | </where> |
| | | order by a.id desc |
| | | order by a.passed desc,a.id desc |
| | | </select> |
| | | |
| | | <select id="selectPaperStudentById" resultMap="ExPaperStudentResult"> |
| | | select a.*,b.id as student_id,b.phone as student_phone,b.name as student_name,c.name as paper_name from ex_paper_student a |
| | | select a.*,b.id as student_id,b.phone as student_phone,b.name as student_name,c.name as paper_name,c.single_num,c.multi_num,c.judge_num,c.easy_num,c.single_score,c.multi_score,c.judge_score,c.easy_score from ex_paper_student a |
| | | left join ex_student b on a.student_id=b.id |
| | | left join ex_exam_paper c on c.id=a.paper_id |
| | | where a.id=#{paperStudentId} |
| | |
| | | where a.paper_id=#{paperId} and a.student_id=#{studentId} |
| | | </select> |
| | | |
| | | <select id="getQuestionByPaperId" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | <select id="getQuestionByPaperId" resultMap="ExQuestionResult"> |
| | | select a.id,a.question_type,a.bank_id,a.company_id,a.status, |
| | | <if test="completed!=null and completed=1"> |
| | | a.answer, |
| | | <if test="state!=null and state!=0"> |
| | | a.answer,c.passed as answer_passed,c.score as answer_score, |
| | | </if> |
| | | a.title,a.privatize,a.content, |
| | | c.id as answer_id,c.paper_id as answer_paper_id,c.student_id as answer_student_id,c.question_id as answer_question_id,c.answer as answer_answer, |
| | | <if test="completed!=null and completed=1"> |
| | | c.passed as answer_passed |
| | | </if> |
| | | c.id as answer_id,c.paper_id as answer_paper_id,c.student_id as answer_student_id,c.question_id as answer_question_id,c.answer as answer_answer |
| | | |
| | | from ex_question a |
| | | inner join ex_paper_question b on a.id=b.question_id |
| | | left join ex_student_answer c on c.question_id=a.id and c.student_id=#{studentId} and c.paper_id=#{paperId} |
| | | where b.paper_id=#{paperId} and a.question_type=#{questionType} |
| | | where b.paper_id=#{paperId} |
| | | order by a.question_type asc,a.id desc |
| | | </select> |
| | | |
| | | <select id="selectByStudentId" resultMap="SimplePaperStudentResult"> |
| | | select a.*,b.name as paper_name,c.id as company_id,c.name as company_name from ex_paper_student a |
| | | left join ex_exam_paper b on b.id=a.paper_id |
| | | left join sys_company c on c.id=b.company_id |
| | | </select> |
| | | |
| | | <select id="selectNoCompleteStudent" resultMap="SimplePaperStudentResult"> |
| | | select a.*, b.name as paper_name,b.limited,b.limit_time,b.deadline,b.single_num,b.multi_num,b.judge_num,b.easy_num |
| | | from ex_paper_student a |
| | | inner join ex_exam_paper b on b.id=a.paper_id |
| | | where a.state=0 limit #{startIndex},#{pageSize} |
| | | </select> |
| | | </mapper> |
| | |
| | | <result property="studentPhone" column="student_phone" /> |
| | | <result property="phaseName" column="phase_name" /> |
| | | <result property="createName" column="create_name" /> |
| | | <result property="period" column="period" /> |
| | | <association property="course" javaType="com.gkhy.exam.system.domain.ExCourse" resultMap="courseResult" /> |
| | | <collection property="totalProgress" ofType="java.math.BigDecimal" select="getTotalProgress" column="{phaseId=phase_id,studentId=student_id}"/> |
| | | <collection property="startTime" ofType="java.time.LocalDateTime" select="getStartTime" column="{phaseId=phase_id,studentId=student_id}"/> |
| | |
| | | <id property="id" column="course_id" /> |
| | | <result property="name" column="course_name" /> |
| | | <result property="logo" column="course_logo" /> |
| | | <association property="period" javaType="java.lang.Long" select="getCoursePeriod" column="{courseId=course_id}"/> |
| | | </resultMap> |
| | | |
| | | <insert id="batchInsert" parameterType="java.util.List"> |
| | | insert into ex_phase_student(phase_id,student_id) values |
| | | insert into ex_phase_student(phase_id,student_id,create_id) values |
| | | <foreach collection="list" item="item" index="index" separator=","> |
| | | (#{item.phaseId},#{item.studentId}) |
| | | (#{item.phaseId},#{item.studentId},#{item.createId}) |
| | | </foreach> |
| | | </insert> |
| | | |
| | | <select id="countByPhaseId" resultType="java.lang.Integer"> |
| | | select count(1) from ex_phase_student where phase_id#{phaseId} |
| | | select count(1) from ex_phase_student where phase_id=#{phaseId} |
| | | </select> |
| | | |
| | | <select id="selectPhaseStudentById" resultMap="ExPhaseStudentResult"> |
| | | <select id="selectPhaseStudentById" resultType="com.gkhy.exam.system.domain.ExPhaseStudent"> |
| | | select a.*,b.phone as student_phone,b.name as student_name from ex_phase_student a |
| | | left join ex_student b on a.student_id=b.id |
| | | where a.id=#{phaseStudentId} |
| | |
| | | </select> |
| | | |
| | | <select id="selectPhaseStudentList" resultMap="ExPhaseStudentResult"> |
| | | select a.*,b.phone as student_phone,b.name as student_name,c.name as phase_name,d.period,e.name as create_name,d.id as course_id,d.logo as course_logo,d.name as course_name from ex_phase_student a |
| | | select a.*,b.phone as student_phone,b.name as student_name,c.name as phase_name,e.name as create_name,d.id as course_id,d.logo as course_logo,d.name as course_name from ex_phase_student a |
| | | left join ex_student b on a.student_id=b.id |
| | | left join ex_course_phase c on c.id=a.phase_id |
| | | left join ex_course d on d.id=c.course_id |
| | |
| | | </select> |
| | | |
| | | |
| | | <select id="getCoursePeriod" resultType="java.lang.Long"> |
| | | select sum(b.resource_length) from ex_course_chapter_period a |
| | | inner join ex_resource b on a.resource_id=b.id |
| | | where a.course_id=#{courseId} |
| | | </select> |
| | | |
| | | <select id="selectPhaseStudentByStudentId" resultType="com.gkhy.exam.system.domain.ExPhaseStudent" |
| | | parameterType="java.lang.Long"> |
| | | select a.*,b.name as phase_name,c.id as company_id,c.name as company_name from ex_phase_student a |
| | | left join ex_course_phase b on b.id=a.phase_id |
| | | left join sys_company c on c.id=b.company_id |
| | | where a.student_id=#{studentId} |
| | | </select> |
| | | |
| | | |
| | | </mapper> |
| | |
| | | <result property="updateBy" column="update_by" /> |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="remark" column="remark" /> |
| | | <result property="singleCount" column="single_count" /> |
| | | <result property="multiCount" column="multi_count" /> |
| | | <result property="judgeCount" column="judge_count" /> |
| | | <result property="totalCount" column="total_count" /> |
| | | <result property="exerciseCount" column="exercise_count" /> |
| | | <result property="categoryName" column="category_name" /> |
| | | <result property="questionId" column="question_id" /> |
| | | </resultMap> |
| | | |
| | | <sql id="selectQuestionBankVo"> |
| | | select id, name, category_id, status, del_flag,company_id,privatize,version, create_by, create_time, update_by, update_time, remark, |
| | | (select count(1) from ex_question where bank_id=a.id) as total_count |
| | | from ex_question_bank |
| | | select a.id, a.name, a.category_id, a.status, a.del_flag,a.company_id,a.privatize,a.version, |
| | | a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as category_name, |
| | | (select count(1) from ex_question where bank_id=a.id and question_type=1) as single_count, |
| | | (select count(1) from ex_question where bank_id=a.id and question_type=2) as multi_count, |
| | | (select count(1) from ex_question where bank_id=a.id and question_type=3) as judge_count |
| | | from ex_question_bank a |
| | | left join sys_category b on b.id=a.category_id |
| | | </sql> |
| | | |
| | | <update id="deleteByBankId"> |
| | |
| | | <select id="selectQuestionBankList" resultMap="ExQuestionBankResult"> |
| | | <include refid="selectQuestionBankVo"/> |
| | | <where> |
| | | and del_flag=0 |
| | | and a.del_flag=0 |
| | | <if test="name != null and name != ''"> |
| | | AND name like concat('%', #{name}, '%') |
| | | AND a.name like concat('%', #{name}, '%') |
| | | </if> |
| | | <if test="categoryId != null "> |
| | | AND categoryId =#{categoryId} |
| | | AND a.category_id =#{categoryId} |
| | | </if> |
| | | <if test="status != null "> |
| | | AND status =#{status} |
| | | AND a.status =#{status} |
| | | </if> |
| | | <if test="companyId != null "> |
| | | AND (company_id =#{companyId} or privatize=1) |
| | | </if> |
| | | </where> |
| | | order by id desc |
| | | </select> |
| | | |
| | | <select id="selectQuestionBankListForStudent" resultType="com.gkhy.exam.system.domain.ExQuestionBank"> |
| | | select a.*, |
| | | (select count(1) from ex_question where bank_id=a.id) as total_count, |
| | | b.exe_count as exercise_count |
| | | from ex_question_bank a |
| | | left join (select bank_id,count(*) as exe_count from ex_exercise_answer where student_id=#{studentId} group by bank_id) b on b.bank_id=a.id |
| | | <where> |
| | | and (a.company_id=#{companyId} or a.privatize=1) and a.del_flag=0 |
| | | <if test="name!=null and name!=''"> |
| | | a.name like concat('%',#{name},'%') |
| | | AND (a.company_id =#{companyId} or a.privatize=1) |
| | | </if> |
| | | </where> |
| | | order by a.id desc |
| | | </select> |
| | | |
| | | <select id="selectQuestionBankListForStudent" resultType="com.gkhy.exam.system.domain.ExQuestionBank"> |
| | | select a.*, |
| | | (select count(1) from ex_question where bank_id=a.id ) as total_count, |
| | | (select count(1) from ex_exercise_answer where bank_id=a.id and student_id=#{studentId}) as exercise_count, |
| | | (select question_id from ex_exercise_answer where bank_id=a.id and student_id=#{studentId} order by id desc limit 1) as question_id |
| | | from ex_question_bank a |
| | | where a.del_flag=0 and (a.company_id=#{companyId} or a.privatize=1) |
| | | order by a.id desc |
| | | </select> |
| | | |
| | | <select id="selectQuestionBankByIdForStudent" resultType="com.gkhy.exam.system.domain.ExQuestionBank"> |
| | | select a.*, |
| | | (select count(1) from ex_question where bank_id=a.id) as total_count, |
| | | (select count(1) from ex_question where bank_id=a.id and question_type=1) as single_count, |
| | | (select count(1) from ex_question where bank_id=a.id and question_type=2) as multi_count, |
| | | (select count(1) from ex_question where bank_id=a.id and question_type=3) as judge_count, |
| | | (select count(1) from ex_exercise_answer where bank_id=#{bankId} and student_id=#{studentId}) as exercise_count |
| | | from ex_question_bank a |
| | | where a.bank_id=#{bankId} |
| | | </select> |
| | | |
| | | <select id="selectCountByBankId" resultType="java.lang.Integer" parameterType="java.lang.Long"> |
| | | select count(1) from ex_question_bank where del_flag=0 and id=#{bankId} |
| | | </select> |
| | | |
| | | <select id="selectCountByCategoryId" resultType="java.lang.Integer"> |
| | | select count(1) from ex_question_bank where category_id=#{categoryId} and del_flag=0 |
| | | </select> |
| | | |
| | | <select id="selectQuestionBankByIds" resultType="com.gkhy.exam.system.domain.ExQuestionBank"> |
| | | select * from ex_question_bank where del_flag=0 and id in |
| | | <foreach collection="bankIds" item="bankId" index="index" separator="," open="(" close=")"> |
| | | #{bankId} |
| | | </foreach> |
| | | </select> |
| | | </mapper> |
| | |
| | | <result property="updateBy" column="update_by" /> |
| | | <result property="updateTime" column="update_time" /> |
| | | <result property="remark" column="remark" /> |
| | | <result property="bankName" column="bank_name" /> |
| | | <association property="exExerciseAnswer" javaType="com.gkhy.exam.system.domain.ExExerciseAnswer" resultMap="ExerciseAnswerResult" /> |
| | | <association property="studentAnswer" javaType="com.gkhy.exam.system.domain.ExStudentAnswer" resultMap="StudentAnswerResult" /> |
| | | </resultMap> |
| | |
| | | </select> |
| | | |
| | | <select id="selectQuestionWithLimit" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | select id,title from ex_question where bank_id=#{bankId} and question_type=#{questionType} and (company_id=#{companyId} or privatize=1) limit #{startIndex},{questionCount} |
| | | select id,title from ex_question where bank_id=#{bankId} and question_type=#{questionType} and (company_id=#{companyId} or privatize=1) limit #{startIndex},#{questionCount} |
| | | </select> |
| | | |
| | | <select id="selectRandomQuestion" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | select id,title from ex_question where bank_id=#{bankId} and question_type=#{questionType} and (company_id=#{companyId} or privatize=1) order by RAND() |
| | | limit {questionCount} |
| | | limit #{questionCount} |
| | | </select> |
| | | |
| | | <select id="selectQuestionList" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | select id,question_type, bank_id, status, company_id,answer,title,privatize from ex_question |
| | | select a.id,a.question_type, a.bank_id, a.status, a.company_id,a.title,a.privatize,b.name as bank_name from ex_question a |
| | | left join ex_question_bank b on b.id=a.bank_id |
| | | <where> |
| | | <if test="title!=null and title!=''"> |
| | | title like concat(#{title},"%") |
| | | and a.title like concat(#{title},"%") |
| | | </if> |
| | | <if test="bankId!=null"> |
| | | bank_id=#{bankId} |
| | | and a.bank_id=#{bankId} |
| | | </if> |
| | | <if test="companyId!=null"> |
| | | company_id=#{companyId} |
| | | and (a.company_id=#{companyId} or a.privatize=1) |
| | | </if> |
| | | <if test="questionType!=null"> |
| | | question_type=#{questionType} |
| | | and a.question_type=#{questionType} |
| | | </if> |
| | | <if test="privatize!=null"> |
| | | privatize=#{privatize} |
| | | </if> |
| | | <!-- <if test="privatize!=null">--> |
| | | <!-- and privatize=#{privatize}--> |
| | | <!-- </if>--> |
| | | </where> |
| | | order by id desc |
| | | </select> |
| | |
| | | select a.id,b.passed from ex_question a |
| | | left join ex_exercise_answer b on b.question_id=a.id and b.student_id=#{studentId} |
| | | where a.bank_id=#{bankId} |
| | | <if test="exerciseType=2"> |
| | | order by a.question_type asc,a.id asc |
| | | </if> |
| | | <if test="exerciseType=1"> |
| | | order by a.id asc |
| | | </if> |
| | | order by a.question_type asc,a.id asc |
| | | </select> |
| | | |
| | | <select id="getExeriseQuestionById" resultMap="ExQuestionResult"> |
| | |
| | | <foreach collection="questionIds" item="questionId" open="(" separator="," close=")"> |
| | | #{questionId} |
| | | </foreach> |
| | | ORDER BY FIELD(a.id, <foreach collection="questionIds" item="questionId" separator=",">#{questionId}</foreach>) |
| | | </select> |
| | | |
| | | <select id="getPaperQuestionList" resultType="java.util.Map"> |
| | | select a.id |
| | | <if test="completed=1"> |
| | | ,c.passed |
| | | <if test="viewType==1"> |
| | | , |
| | | case when c.answer is null then 0 |
| | | else 1 |
| | | end as state |
| | | </if> |
| | | <if test="viewType==2"> |
| | | <if test="state!=0"> |
| | | ,c.passed |
| | | </if> |
| | | </if> |
| | | from ex_question a |
| | | inner join ex_paper_question b on b.question_id=a.id |
| | | <if test="completed=1"> |
| | | left join ex_student_answer c on c.question_id=a.id and c.student_id=#{studentId} and c.paper_id=#{paperId} |
| | | </if> |
| | | where b.paper_id=#{paperId} |
| | | order by a.question_type asc,a.id asc |
| | | </select> |
| | |
| | | <select id="getPaperQuestionById" resultMap="ExQuestionResult"> |
| | | select a.id,a.question_type,a.bank_id,a.company_id,a.title,a.content,a.privatize, |
| | | b.id as student_answer_id, b.answer as student_answer,b.question_id,b.student_id |
| | | <if test="completed=1"> |
| | | <if test="state!=0"> |
| | | ,a.answer,b.passed as student_passed |
| | | </if> |
| | | from ex_question a |
| | |
| | | where a.id=#{questionId} |
| | | </select> |
| | | |
| | | <select id="getPaperQuestionByIds" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | <select id="getPaperQuestionByIds" resultMap="ExQuestionResult"> |
| | | select a.id,a.question_type,a.bank_id,a.company_id,a.title,a.content,a.privatize, |
| | | b.id as student_answer_id, b.answer as student_answer,b.question_id,b.student_id |
| | | <if test="completed=1"> |
| | | <if test="state!=0"> |
| | | ,a.answer,b.passed as student_passed |
| | | </if> |
| | | from ex_question a |
| | |
| | | <foreach collection="questionIds" item="questionId" open="(" separator="," close=")"> |
| | | #{questionId} |
| | | </foreach> |
| | | ORDER BY FIELD(a.id, <foreach collection="questionIds" item="questionId" separator=",">#{questionId}</foreach>) |
| | | </select> |
| | | |
| | | <select id="getExerciseErrorQuestionList" resultType="java.lang.Long"> |
| | | select a.id from ex_question a |
| | | inner join ex_exercise_answer b on b.question_id=a.id |
| | | where a.bank_id=#{bankId} and b.student_id=#{studentId} |
| | | where a.bank_id=#{bankId} and b.student_id=#{studentId} and b.passed=0 |
| | | order by a.question_type asc,a.id asc |
| | | </select> |
| | | |
| | | <select id="selectByQuestionId" resultType="com.gkhy.exam.system.domain.ExQuestion"> |
| | | select a.*,b.name as bank_name from ex_question a |
| | | left join ex_question_bank b on b.id=a.bank_id |
| | | where a.id=#{questionId} |
| | | </select> |
| | | |
| | | <select id="selectQuestionByPaperId" resultType="com.gkhy.exam.system.domain.ExQuestion" |
| | | parameterType="java.lang.Long"> |
| | | select a.* from ex_question a |
| | | inner join ex_paper_question b on b.question_id=a.id |
| | | where b.paper_id=#{paperId} |
| | | </select> |
| | | |
| | | |
| | | </mapper> |
| | |
| | | where b.id=#{periodId} |
| | | </select> |
| | | |
| | | <select id="checkResourceAssign" resultType="java.lang.Integer" parameterType="java.lang.Long"> |
| | | select count(1) from ex_course_chapter_period a |
| | | where a.resource_id=#{resourceId} |
| | | </select> |
| | | |
| | | |
| | | </mapper> |
| | |
| | | <select id="selectPassCount" resultType="java.lang.Integer"> |
| | | select count(1) from ex_student_answer a |
| | | inner join ex_question b on b.id=a.question_id |
| | | where a.paper_id=#{paperId} and a.student_id=#{studentId} and b.questionType=#{questionType} and a.passed=1 |
| | | where a.paper_id=#{paperId} and a.student_id=#{studentId} and b.question_type=#{questionType} and a.passed=1 |
| | | </select> |
| | | |
| | | <select id="getStudentAnswer" resultType="com.gkhy.exam.system.domain.ExStudentAnswer"> |
| | |
| | | <result property="remark" column="remark" /> |
| | | |
| | | <association property="company" javaType="com.gkhy.exam.system.domain.SysCompany" resultMap="companyResult" /> |
| | | <association property="createUser" javaType="com.gkhy.exam.common.domain.entity.SysUser" resultMap="userResult" /> |
| | | </resultMap> |
| | | <resultMap id="companyResult" type="com.gkhy.exam.system.domain.SysCompany"> |
| | | <id property="id" column="company_id" /> |
| | | <result property="name" column="company_name" /> |
| | | </resultMap> |
| | | |
| | | <resultMap id="userResult" type="com.gkhy.exam.common.domain.entity.SysUser"> |
| | | <id property="id" column="create_id" /> |
| | | <result property="name" column="create_name" /> |
| | | </resultMap> |
| | | |
| | | <sql id="selectStudentVo"> |
| | | select s.id, s.name, s.company_id, s.empno, s.phone,s.password,s.status,s.sex,s.id_no,s.post,s.duty, |
| | | select s.id, s.name, s.company_id, s.empno, s.phone,s.status,s.sex,s.id_no,s.post,s.duty, |
| | | s.create_id,s.del_flag,s.version, s.create_by, s.create_time, s.update_by, s.update_time, s.remark, |
| | | c.id as company_id,c.name as company_name |
| | | c.id as company_id,c.name as company_name,d.name as create_name |
| | | from ex_student s |
| | | left join sys_company c on c.id=s.company_id |
| | | left join sys_user d on d.id=s.create_id |
| | | </sql> |
| | | |
| | | <update id="deleteByStudentId"> |
| | |
| | | <if test="idNo != null and idNo != ''"> |
| | | AND s.id_no like concat('%', #{idNo}, '%') |
| | | </if> |
| | | <if test="createId != null"> |
| | | AND s.create_id =#{createId} |
| | | </if> |
| | | <if test="params.createIds != null and params.createIds != ''"> |
| | | AND s.create_id in |
| | | <foreach collection="params.createIds" item="createId" open="(" separator="," close=")"> |
| | | #{createId} |
| | | </foreach> |
| | | </if> |
| | | </where> |
| | | order by s.id desc |
| | | </select> |
| | |
| | | </select> |
| | | |
| | | <select id="selectStudentByPhone" resultType="com.gkhy.exam.system.domain.ExStudent"> |
| | | select * from ex_student where phone=#{phone} limit 1 |
| | | select * from ex_student where phone=#{phone} and del_flag=0 limit 1 |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <result property="currentDuration" column="current_duration" /> |
| | | <result property="currentPage" column="current_page" /> |
| | | <result property="progress" column="progress" /> |
| | | <result property="resourceType" column="resource_type" /> |
| | | <result property="createBy" column="create_by" /> |
| | | <result property="createTime" column="create_time" /> |
| | | <result property="updateBy" column="update_by" /> |
| | |
| | | </resultMap> |
| | | |
| | | <sql id="selectStudentStudyVo"> |
| | | select a.id, a.phase_id, a.course_id, a.chapter_id, a.period_id,a.student_id,a.current_duration,a.current_page,a.progress,a.resource_type, |
| | | select a.id, a.phase_id, a.course_id, a.chapter_id, a.period_id,a.student_id,a.current_duration,a.current_page,a.progress, |
| | | a.version, a.create_by, a.create_time, a.update_by, a.update_time, a.remark,b.name as course_name,d.name as chapter_mame,c.name as period_name |
| | | from ex_student_study a |
| | | left join ex_course b on b.id=a.course_id |
| | |
| | | </select> |
| | | |
| | | <select id="selectStudyByObject" resultType="com.gkhy.exam.system.domain.ExStudentStudy"> |
| | | select * from ex_student_study where paper_id=#{paperId} and period_id=#{periodId} and student_id=#{studentId} |
| | | select * from ex_student_study where phase_id=#{phaseId} and period_id=#{periodId} and student_id=#{studentId} limit 1 |
| | | </select> |
| | | </mapper> |
| | |
| | | AND status =#{status} |
| | | </if> |
| | | </where> |
| | | order by create_time desc |
| | | order by id desc |
| | | </select> |
| | | |
| | | <select id="selectCarouselById" resultMap="SysCarouselResult"> |
| | |
| | | <result property="parentId" column="parent_id" /> |
| | | <result property="status" column="status" /> |
| | | <result property="sort" column="sort" /> |
| | | <result property="delFlag" column="del_flag" /> |
| | | <result property="version" column="version" /> |
| | | <result property="createBy" column="create_by" /> |
| | | <result property="createTime" column="create_time" /> |
| | |
| | | </resultMap> |
| | | |
| | | <sql id="selectCategoryVo"> |
| | | select id, name, parent_id, category_type, status,sort,version, create_by, create_time, update_by, update_time, remark |
| | | select id, name, parent_id, category_type, status,sort,del_flag,version, create_by, create_time, update_by, update_time, remark |
| | | from sys_category |
| | | </sql> |
| | | |
| | | <update id="deleteByCategoryId" parameterType="java.lang.Long"> |
| | | update sys_category set del_flag=1 where id=#{categoryId} |
| | | </update> |
| | | |
| | | <select id="selectCategoryList" resultMap="SysCategoryResult"> |
| | | <include refid="selectCategoryVo"/> |
| | | <where> |
| | | and del_flag=0 |
| | | <if test="name != null and name != ''"> |
| | | AND name like concat('%', #{name}, '%') |
| | | </if> |
| | |
| | | </select> |
| | | |
| | | <select id="checkNameUnique" resultType="com.gkhy.exam.system.domain.SysCategory"> |
| | | select id,name,parent_id from sys_category where name=#{name} and parent_id=#{parentId} limit 1 |
| | | </select> |
| | | |
| | | <select id="selectCountOfCoure" resultType="java.lang.Integer"> |
| | | select count(1) from ex_course where category_id=#{categoryId} and del_flag=0 |
| | | </select> |
| | | |
| | | <select id="selectCountOfBank" resultType="java.lang.Integer"> |
| | | select count(1) from ex_question_bank where category_id=#{categoryId} and del_flag=0 |
| | | select id,name,parent_id from sys_category where name=#{name} and parent_id=#{parentId} and del_flag=0 limit 1 |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <result property="phone" column="phone" /> |
| | | <result property="delFlag" column="del_flag" /> |
| | | <result property="remainPeriod" column="remain_period" /> |
| | | <result property="spendPeriod" column="spend_period" /> |
| | | <result property="totalPeriod" column="total_period" /> |
| | | <result property="version" column="version" /> |
| | | <result property="createBy" column="create_by" /> |
| | |
| | | </resultMap> |
| | | |
| | | <sql id="selectCompanyVo"> |
| | | select id, name, credit_code, major, phone,remain_period,spend_period,total_period,version, create_by, create_time, update_by, update_time, remark |
| | | select id, name, credit_code, major, phone,remain_period,total_period,version, create_by, create_time, update_by, update_time, remark |
| | | from sys_company |
| | | </sql> |
| | | |
| | |
| | | <result property="remark" column="remark" /> |
| | | <result property="version" column="version" /> |
| | | <result property="companyName" column="company_name" /> |
| | | <result property="remainPeriod" column="remain_period" /> |
| | | <result property="parentName" column="parent_name" /> |
| | | </resultMap> |
| | | |
| | |
| | | |
| | | |
| | | <select id="getUserByUsername" resultMap="SysUserResult"> |
| | | select id,username,name,password,user_type,company_id,status,del_flag from sys_user |
| | | where username=#{username} limit 1 |
| | | select id,username,name,password,user_type,company_id,status,del_flag,parent_id from sys_user |
| | | where username=#{username} and del_flag=0 limit 1 |
| | | </select> |
| | | |
| | | <select id="userList" resultMap="SysUserResult"> |
| | | select u.id,u.username,u.name,u.user_type,u.phone,u.parent_id,u.company_id,u.sex,u.status,u.del_flag, |
| | | select u.id,u.username,u.name,u.user_type,u.phone,u.parent_id,u.company_id,u.sex,u.status,u.del_flag,u.version, |
| | | u.login_ip,u.login_date,u.create_by,u.create_time,u.remark,c.name as company_name,su.name as parent_name |
| | | from sys_user u |
| | | left join sys_company c on c.id=u.company_id |
| | |
| | | and u.del_flag = 0 |
| | | <if test="username != null and username != ''"> |
| | | AND u.username like concat('%', #{username}, '%') |
| | | </if> |
| | | <if test="name != null and name != ''"> |
| | | AND u.name like concat('%', #{name}, '%') |
| | | </if> |
| | | <if test="status != null and status != ''"> |
| | | AND u.status = #{status} |
| | |
| | | <if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 --> |
| | | AND date_format(u.create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d') |
| | | </if> |
| | | <if test="params.userType != null"> |
| | | AND u.user_type >#{params.userType} |
| | | <if test="params.userType != null and (params.userType==4 or params.userType==1)"> |
| | | AND u.user_type in (2,3) |
| | | </if> |
| | | <if test="params.userType != null and params.userType==2"> |
| | | AND u.user_type in (3) |
| | | </if> |
| | | <if test="params.userType != null and params.userType==0"> |
| | | AND u.user_type in (1,2,3,4) |
| | | </if> |
| | | </where> |
| | | order by u.id desc |
| | | </select> |
| | | |
| | | |
| | |
| | | </select> |
| | | |
| | | <select id="getUserById" resultMap="SysUserResult"> |
| | | select u.id,u.username,u.user_type,u.name,u.phone,u.parent_id,u.company_id,u.status,u.sex,u.del_flag,c.name as company_name,su.name as parent_name |
| | | select u.id,u.username,u.user_type,u.name,u.phone,u.parent_id,u.company_id,u.status,u.sex,u.del_flag,u.version,c.name as company_name,c.remain_period,su.name as parent_name |
| | | from sys_user u |
| | | left join sys_company c on c.id=u.company_id |
| | | left join sys_user su on su.id=u.parent_id and u.parent_id!=0 |
| | |
| | | select id,phone from sys_user where phone=#{phone} and del_flag=0 limit 1 |
| | | </select> |
| | | |
| | | <select id="selectWorkshopUserIds" resultType="java.lang.Long" parameterType="java.lang.Long"> |
| | | select id from sys_user where parent_id=#{departUserId} and del_flag=0 and user_type=3 |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <mybatis-plus.version>3.5.1</mybatis-plus.version> |
| | | <mysql-connector.version>8.0.29</mysql-connector.version> |
| | | <jwt.version>0.9.1</jwt.version> |
| | | <fastjson.version>2.0.48</fastjson.version> |
| | | <fastjson.version>2.0.52</fastjson.version> |
| | | <caffeine.version>2.9.3</caffeine.version> |
| | | <minio.version>8.4.5</minio.version> |
| | | <kaptcha.version>2.3.3</kaptcha.version> |
| | |
| | | <poi.version>5.2.3</poi.version> |
| | | <pdfbox.version>2.0.27</pdfbox.version> |
| | | <jaudiotagger.version>2.0.1</jaudiotagger.version> |
| | | <easyexcel.version>4.0.2</easyexcel.version> |
| | | |
| | | </properties> |
| | | <dependencyManagement> |
| | | <dependencies> |
| | |
| | | <version>${fastjson.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alibaba.fastjson2</groupId> |
| | | <artifactId>fastjson2-extension</artifactId> |
| | | <version>${fastjson.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.alibaba.fastjson2</groupId> |
| | | <artifactId>fastjson2-extension-spring5</artifactId> |
| | | <version>${fastjson.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.github.ben-manes.caffeine</groupId> |
| | | <artifactId>caffeine</artifactId> |
| | | <version>${caffeine.version}</version> |
| | |
| | | <version>${jaudiotagger.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>easyexcel</artifactId> |
| | | <version>${easyexcel.version}</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </dependencyManagement> |
| | | |