From 4c36a29ee72cffd62460b99872188339e67feb8f Mon Sep 17 00:00:00 2001 From: yang <1175@qq.com> Date: Sat, 22 Jun 2024 11:29:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=90=E9=95=BF=E8=B7=AF=E5=BE=84,=E4=BB=BB?= =?UTF-8?q?=E8=81=8C=E8=B5=84=E6=A0=BC=E7=AD=89=E7=BA=A7=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 成长路径图,解除绑定接口去除 成长路径图,内部考试引用关系,以及导入bug修复 成长路径图,考试添加关联字段 成长路径图,考试导入完成状态去除 成长路径图,考试同步,限制事务范围 成长路径图,考试同步 成长路径图,考试次数 成长路径图,去除导入同步 成长路径图,导入添加同步信息 成长路径图,bug修复 成长路径图,导入考试去除属性 成长路径图,考试计数 成长路径图,考试实时同步,去除异常 成长路径图,考试实时同步 成长路径图,考试 成长路径图,考试绑定 成长路径图,保存考试信息 --- .../src/main/java/com/xboe/api/ThirdApi.java | 53 ++++++- .../com/xboe/api/vo/CheckExamBandingBean.java | 36 +++++ .../xboe/api/vo/GetUserIdByWorkNumResult.java | 40 +++++ .../xboe/api/vo/LocalDateTimeSerializer.java | 19 +++ .../com/xboe/api/vo/SyncExamScoreBean.java | 31 ++++ .../module/course/api/CourseManageApi.java | 13 +- .../module/course/service/ICourseService.java | 9 +- .../service/impl/CourseServiceImpl.java | 11 ++ .../xboe/module/exam/api/AloneExamApi.java | 29 ++-- .../com/xboe/module/exam/api/ExamTestApi.java | 39 ++++- .../module/exam/dto/SaveExamScoreDto.java | 122 +++++++++++++++ .../xboe/module/exam/entity/AloneExam.java | 1 + .../com/xboe/module/exam/entity/ExamTest.java | 10 ++ .../exam/service/IAloneExamService.java | 18 ++- .../module/exam/service/IExamTestService.java | 3 + .../service/impl/AloneExamServiceImpl.java | 140 ++++++++++++++++-- .../service/impl/ExamTestServiceImpl.java | 6 + .../src/main/resources/application.properties | 5 +- 18 files changed, 538 insertions(+), 47 deletions(-) create mode 100644 servers/boe-server-all/src/main/java/com/xboe/api/vo/CheckExamBandingBean.java create mode 100644 servers/boe-server-all/src/main/java/com/xboe/api/vo/GetUserIdByWorkNumResult.java create mode 100644 servers/boe-server-all/src/main/java/com/xboe/api/vo/LocalDateTimeSerializer.java create mode 100644 servers/boe-server-all/src/main/java/com/xboe/api/vo/SyncExamScoreBean.java create mode 100644 servers/boe-server-all/src/main/java/com/xboe/module/exam/dto/SaveExamScoreDto.java diff --git a/servers/boe-server-all/src/main/java/com/xboe/api/ThirdApi.java b/servers/boe-server-all/src/main/java/com/xboe/api/ThirdApi.java index b9b6155e..c765166e 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/api/ThirdApi.java +++ b/servers/boe-server-all/src/main/java/com/xboe/api/ThirdApi.java @@ -4,24 +4,25 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.lang.Opt; import cn.hutool.http.HttpRequest; import cn.hutool.json.JSONUtil; +import com.alibaba.nacos.shaded.com.google.gson.*; import com.xboe.api.vo.*; import com.xboe.module.course.vo.StudyCourseVo; import com.xboe.module.course.vo.TeacherInfoVo; import com.xboe.module.course.vo.TeacherVo; import com.xboe.module.dict.entity.DictDto; +import com.xboe.module.exam.entity.AloneExam; import com.xboe.module.exam.entity.ExamTest; import com.xboe.school.study.entity.StudyCourse; import com.xboe.system.user.dao.UserDao; import com.xboe.system.user.entity.User; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; +import java.time.LocalDateTime; +import java.util.*; import java.util.concurrent.ForkJoinPool; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -66,6 +67,13 @@ public class ThirdApi { @Value("${manageApi.editExam}") private String editExam; + + @Value("${userBasic.getUserIdByWorkNum}") + private String getUserIdByWorkNum; + + @Value("${coursesuilt.syncExamScoreToCourseSuite}") + private String syncExamScoreToCourseSuite; + //获取例外人员的id public List getUserId(){ String responseBody = Optional.ofNullable(HttpRequest.get(infarasApiUrl+"?pid=316&type=1").execute() //prod 316 @@ -229,10 +237,41 @@ public class ThirdApi { List list = a.getResult().getList(); System.out.println(" list = " +list.size()); System.out.println(" list = " +list); - - - } + public HashMap getUserIdByWorkNum(String token, List workNumList) { + // 将workNum列表转换为逗号分隔的字符串 + String workNums = workNumList.stream() + .collect(Collectors.joining(",")); + // 构建请求URL + String url = getUserIdByWorkNum+"?workNums=" + workNums; + String respStr = Optional.ofNullable( + HttpRequest.get(url) + .header("token", token) + .execute().body() + ).orElseThrow(() -> new RuntimeException("Token校验失败")); + // 解析JSON字符串为HashMap + GetUserIdByWorkNumResult getUserIdByWorkNumResult = JSONUtil.parseObj(respStr).toBean(GetUserIdByWorkNumResult.class); + HashMap result = getUserIdByWorkNumResult.getResult(); + return result; + } + + public void syncExamScoreToCourseSuite(AloneExam aloneExam,String token) { + Gson gson = new GsonBuilder() + .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()) + .create(); + + String json = gson.toJson(aloneExam); + String resp = HttpRequest.post(syncExamScoreToCourseSuite) + .body(json) + .header("token", token) + .execute() + .body(); + + if (StringUtils.isBlank(resp)){ + return; + } + JSONUtil.toBean(resp, SyncExamScoreBean.class).success(); + } } diff --git a/servers/boe-server-all/src/main/java/com/xboe/api/vo/CheckExamBandingBean.java b/servers/boe-server-all/src/main/java/com/xboe/api/vo/CheckExamBandingBean.java new file mode 100644 index 00000000..d31f6398 --- /dev/null +++ b/servers/boe-server-all/src/main/java/com/xboe/api/vo/CheckExamBandingBean.java @@ -0,0 +1,36 @@ +package com.xboe.api.vo; + +import cn.hutool.json.JSONUtil; +import com.xboe.school.study.entity.StudyCourse; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; + +@Data +@Slf4j +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CheckExamBandingBean { + + private boolean show; + private String version; + private int code; + private String msg; + private Object data; + private boolean success; + + public CheckExamBandingBean success() { + if (this.code!=200) { + log.error("获取绑定关系失败----{}", JSONUtil.toJsonPrettyStr(this)); + return null; + } + return this; + } +} diff --git a/servers/boe-server-all/src/main/java/com/xboe/api/vo/GetUserIdByWorkNumResult.java b/servers/boe-server-all/src/main/java/com/xboe/api/vo/GetUserIdByWorkNumResult.java new file mode 100644 index 00000000..f8038f4e --- /dev/null +++ b/servers/boe-server-all/src/main/java/com/xboe/api/vo/GetUserIdByWorkNumResult.java @@ -0,0 +1,40 @@ +package com.xboe.api.vo; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.Date; +import java.util.HashMap; + +/** + * Auto-generated: 2022-12-10 14:3:18 + * + * @author bejson.com (i@bejson.com) + * @website http://www.bejson.com/java2pojo/ + */ +@Data +@Slf4j +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GetUserIdByWorkNumResult { + + private String error; + private String message; + private String permissions; + private HashMap result; + private int status; + private Date timestamp; + + public GetUserIdByWorkNumResult success() { + if (this.status != 200) { + log.error("获取用户ID列表失败----{}", JSONUtil.toJsonPrettyStr(this)); + return null; + } + return this; + } +} \ No newline at end of file diff --git a/servers/boe-server-all/src/main/java/com/xboe/api/vo/LocalDateTimeSerializer.java b/servers/boe-server-all/src/main/java/com/xboe/api/vo/LocalDateTimeSerializer.java new file mode 100644 index 00000000..5f9fe399 --- /dev/null +++ b/servers/boe-server-all/src/main/java/com/xboe/api/vo/LocalDateTimeSerializer.java @@ -0,0 +1,19 @@ +package com.xboe.api.vo; + +import com.alibaba.nacos.shaded.com.google.gson.JsonElement; +import com.alibaba.nacos.shaded.com.google.gson.JsonPrimitive; +import com.alibaba.nacos.shaded.com.google.gson.JsonSerializationContext; +import com.alibaba.nacos.shaded.com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class LocalDateTimeSerializer implements JsonSerializer { + private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(formatter.format(src)); + } +} \ No newline at end of file diff --git a/servers/boe-server-all/src/main/java/com/xboe/api/vo/SyncExamScoreBean.java b/servers/boe-server-all/src/main/java/com/xboe/api/vo/SyncExamScoreBean.java new file mode 100644 index 00000000..3389dd04 --- /dev/null +++ b/servers/boe-server-all/src/main/java/com/xboe/api/vo/SyncExamScoreBean.java @@ -0,0 +1,31 @@ +package com.xboe.api.vo; + +import cn.hutool.json.JSONUtil; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Data +@Slf4j +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SyncExamScoreBean { + + private boolean show; + private String version; + private int code; + private String msg; + private Object data; + private boolean success; + + public SyncExamScoreBean success() { + if (this.code!=200) { + log.error("同步考试到boe库失败----{}", JSONUtil.toJsonPrettyStr(this)); + return null; + } + return this; + } +} diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java index c3a31e73..d681258d 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/api/CourseManageApi.java @@ -9,12 +9,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.xboe.common.PageList; import com.xboe.common.Pagination; @@ -1164,5 +1159,11 @@ public class CourseManageApi extends ApiBaseController{ return success(courses); } + @GetMapping("/getCourseCoverUrl") + public JsonResponse> getCourseCoverUrl(@RequestParam String courseIds){ + Map courseUrlMap = courseService.getCourseCoverUrl(courseIds); + return success(courseUrlMap); + } + } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseService.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseService.java index 76e0d693..759db86c 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseService.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/ICourseService.java @@ -340,9 +340,8 @@ public interface ICourseService { * */ List mobiledelList(Integer num,CourseQueryDto courseQueryDto); - - - - - + /** + * 获取课程封面 + * */ + Map getCourseCoverUrl(String courseIds); } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java index 873bcc5d..3d8f7139 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/course/service/impl/CourseServiceImpl.java @@ -1979,5 +1979,16 @@ public class CourseServiceImpl implements ICourseService { return courseDao.findListByHql("Select new Course(id,studys,score) from Course where id in(?1)", ids); } + @Override + public Map getCourseCoverUrl(String courseIds) { + List courseIdList = Arrays.asList(courseIds.split(",")); + List courseList = courseDao.findList(FieldFilters.in("id", courseIdList)); + Map coverUrlMap = courseList.stream() + .filter(course -> StringUtils.isNotBlank(course.getCoverImg())) + .collect(Collectors.toMap(Course::getId, Course::getCoverImg)); + + return coverUrlMap; + } + } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/AloneExamApi.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/AloneExamApi.java index 5f81455e..0cdcf9e2 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/AloneExamApi.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/AloneExamApi.java @@ -1,5 +1,6 @@ package com.xboe.module.exam.api; +import java.io.IOException; import java.io.OutputStream; import java.time.LocalDateTime; import java.util.ArrayList; @@ -14,15 +15,12 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import com.xboe.module.exam.dto.SaveExamScoreDto; +import com.xboe.module.exam.entity.*; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.dao.DuplicateKeyException; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -41,9 +39,6 @@ import com.xboe.core.cache.IXaskCache; import com.xboe.core.cache.XaskCacheProvider; import com.xboe.core.exception.XaskException; import com.xboe.module.exam.dto.AloneExamExportDto; -import com.xboe.module.exam.entity.AloneExam; -import com.xboe.module.exam.entity.AloneExamAnswer; -import com.xboe.module.exam.entity.ExamTest; import com.xboe.module.exam.service.IAloneExamService; import com.xboe.module.exam.service.IExamPaperService; import com.xboe.module.exam.service.IExamTestService; @@ -553,6 +548,7 @@ public class AloneExamApi extends ApiBaseController { //转化成百分数 //answer.setScore(this.calculateScore(detail)); service.submit(answer,scoreType); + service.syncExamScoreToCourseSuite(answer, request); return success(map); } catch (Exception e) { log.error("提交答卷错误", e); @@ -707,4 +703,19 @@ public class AloneExamApi extends ApiBaseController { } } + + + /** + * + * @param request + * @param saveExamScoreDtoList + * @return + * @throws IOException + */ + @PostMapping("/examScoreBatchAdd") + public JsonResponse examScoreBatchAdd(HttpServletRequest request, @RequestBody List saveExamScoreDtoList){ + service.examScoreBatchAdd(request, saveExamScoreDtoList); + return success("导入成功"); + } + } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/ExamTestApi.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/ExamTestApi.java index 00b8220b..a9decf83 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/ExamTestApi.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/api/ExamTestApi.java @@ -3,14 +3,12 @@ package com.xboe.module.exam.api; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import cn.hutool.core.collection.CollectionUtil; import com.xboe.api.ThirdApi; import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; import org.hibernate.exception.ConstraintViolationException; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; + import com.xboe.common.PageList; import com.xboe.common.Pagination; @@ -23,6 +21,8 @@ import com.xboe.module.exam.service.IExamTestService; import lombok.extern.slf4j.Slf4j; +import java.util.List; + /** * 考试 * */ @@ -33,8 +33,10 @@ public class ExamTestApi extends ApiBaseController { @Resource private IExamTestService examTestService; + @Resource - ThirdApi thirdApi; + private ThirdApi thirdApi; + /** *查询考试,分页,搜索,资源归属,状态 **/ @@ -133,10 +135,16 @@ public class ExamTestApi extends ApiBaseController { * */ @GetMapping("/delete") @AutoLog(module = "考试",action = "删除考试",info = "删除考试") - public JsonResponse delete(String id){ + public JsonResponse delete(String id, HttpServletRequest request){ if(StringUtil.isBlank(id)){ return badRequest("缺少必要参数"); } + + String token = request.getHeader("Xboe-Access-Token"); + if (StringUtil.isEmpty(token)) { + token = request.getHeader("token"); + } + try { examTestService.delete(id); return success(true); @@ -183,4 +191,21 @@ public class ExamTestApi extends ApiBaseController { return error("上下级失败",e.getMessage()); } } + + /** + * 引用关系移除 + * */ + @PostMapping("/removeRel") + public JsonResponse removeRel(@RequestParam List ids){ + if(CollectionUtil.isEmpty(ids)){ + return badRequest("参数异常"); + } + try { + examTestService.removeRel(ids); + return success(true); + } catch (Exception e) { + log.error("引用关系移除异常",e); + return error("引用关系移除异常",e.getMessage()); + } + } } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/dto/SaveExamScoreDto.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/dto/SaveExamScoreDto.java new file mode 100644 index 00000000..85f06823 --- /dev/null +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/dto/SaveExamScoreDto.java @@ -0,0 +1,122 @@ +package com.xboe.module.exam.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import javax.persistence.Column; +import java.time.LocalDateTime; + +/** + * 单独的考虑答卷信息 + */ +@Data +public class SaveExamScoreDto { + /** + * 用户姓名 + */ + private String userId; + + + /** + * 用户姓名 + */ + private String userName; + + /** + * 考试id + */ + private String testId; + +// /** +// * 考试名称 +// */ +// private String testName; + +// /** +// * 考试时长 分钟 +// */ +// private Integer testDuration; + + /** + * 试题排列 1试题乱序,2选项乱序,3全部乱序 + */ + private Integer arrange; + +// /** +// * 及格线 +// */ +// private Integer passLine; + + /** + * 账户的代码,用于区别于同姓名的用户 + */ + private String workNum; + + + /** + * 独立考试任务的id + */ + private String aloneId; + + /** + * 试卷总分 + */ + @Column(name = "total_score") + private Float totalScore; + + +// /** +// * 答卷内容 +// */ +// @Column(name = "answer_json", columnDefinition = "mediumtext") +// private String answerJson; + + // todo by yyk 2024-05-17 14:10:32 确定分数 + /** + * 用户的实际得分 + */ + private Float realScore; + +// /** +// * 用时秒 +// */ +// private Integer useMinute; + + + /** + * 最终成绩,如果是百分制,用户的实际得分会换算为百分制 + */ + private Float score; + + /** + * 开始时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime startTime; + + /** + * 结束时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime endTime; + + +// /** +// * 完成状态 +// */ +// private Integer status; + +// /** +// * 考试次数 +// */ +// private Integer times; + + +// /** +// * 记录最后的操作时间 +// */ +// @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") +// private LocalDateTime lastTime; + + +} diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/AloneExam.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/AloneExam.java index 2f2a5c6a..33909cc7 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/AloneExam.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/AloneExam.java @@ -65,6 +65,7 @@ public class AloneExam extends IdBaseEntity { private String ucode; /**关联类型*/ + /**关联类型 新增关联类型14,代表成长路径图*/ @Column(name = "ref_type", length = 30) private String refType; diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/ExamTest.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/ExamTest.java index a4f313bb..e141d52d 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/ExamTest.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/entity/ExamTest.java @@ -178,4 +178,14 @@ public class ExamTest extends BaseEntity { @Transient private String paperName; + + /** 关联类型,1、项目 2、学习路径图 3、面授课 14、成长路径图 */ + @Column(name = "ref_type") + private Integer refType; + + @Column(name = "ref_id") + private String refId; + + @Column(name = "ref_status") + private Integer refStatus; } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IAloneExamService.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IAloneExamService.java index 0d37f7d5..9f2c9b09 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IAloneExamService.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IAloneExamService.java @@ -5,11 +5,13 @@ import java.util.Map; import com.xboe.common.OrderCondition; import com.xboe.common.PageList; +import com.xboe.module.exam.dto.SaveExamScoreDto; import com.xboe.module.exam.dto.TestUserDto; import com.xboe.module.exam.dto.TestUserQuery; import com.xboe.module.exam.entity.AloneExam; import com.xboe.module.exam.entity.AloneExamAnswer; import com.xboe.module.exam.vo.AloneExamQuery; +import javax.servlet.http.HttpServletRequest; /** * 独立考试的处理。此信息无删除操作,更新也只是更新answerJson字段 @@ -92,10 +94,18 @@ public interface IAloneExamService { /** * 提交考试 + * * @param aea */ - void submit(AloneExamAnswer aea,Integer scoreType); - + void submit(AloneExamAnswer aea, Integer scoreType); + + /** + * 同步考试成绩 + * @param aea + * @param request + */ + void syncExamScoreToCourseSuite(AloneExamAnswer aea, HttpServletRequest request); + /** * 更新答案 * @param id @@ -156,5 +166,7 @@ public interface IAloneExamService { * @throws Exception */ PageList findTestUserAnswers(TestUserQuery params) throws Exception; - + + void examScoreBatchAdd(HttpServletRequest request, List saveExamScoreDtoList); + } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IExamTestService.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IExamTestService.java index c4fe9114..7659985a 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IExamTestService.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/IExamTestService.java @@ -3,6 +3,8 @@ package com.xboe.module.exam.service; import com.xboe.common.PageList; import com.xboe.module.exam.entity.ExamTest; +import java.util.List; + public interface IExamTestService { /** * 分页查,状态,搜索,资源归属 @@ -51,4 +53,5 @@ public interface IExamTestService { * */ void enabled(String id,Boolean enabled); + void removeRel(List ids); } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/AloneExamServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/AloneExamServiceImpl.java index 263f836f..ce7b612f 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/AloneExamServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/AloneExamServiceImpl.java @@ -1,15 +1,25 @@ package com.xboe.module.exam.service.impl; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import com.xboe.api.ThirdApi; +import com.xboe.module.exam.dao.ExamTestDao; +import com.xboe.module.exam.dto.*; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.xboe.common.OrderCondition; @@ -20,31 +30,40 @@ import com.xboe.core.orm.QueryBuilder; import com.xboe.core.orm.UpdateBuilder; import com.xboe.module.exam.dao.AloneExamAnswerDao; import com.xboe.module.exam.dao.AloneExamDao; -import com.xboe.module.exam.dto.TestUserAnswerDto; -import com.xboe.module.exam.dto.TestUserDto; -import com.xboe.module.exam.dto.TestUserQuery; import com.xboe.module.exam.entity.AloneExam; import com.xboe.module.exam.entity.AloneExamAnswer; import com.xboe.module.exam.entity.ExamTest; import com.xboe.module.exam.service.IAloneExamService; import com.xboe.module.exam.vo.AloneExamQuery; +import org.springframework.transaction.support.DefaultTransactionDefinition; @Service public class AloneExamServiceImpl implements IAloneExamService{ + private static final Logger log = LoggerFactory.getLogger(AloneExamServiceImpl.class); @Resource AloneExamAnswerDao dao; @Resource AloneExamDao aeDao; + + @Autowired + private ExamTestDao examTestDao; + + @Autowired + private ThirdApi thirdApi; + @Override @Transactional public void save(AloneExamAnswer aea){ dao.save(aea); + AloneExam ae=aeDao.findOne(FieldFilters.eq("aid", aea.getAid()),FieldFilters.eq("testId", aea.getTestId())); + int currentTimes = ae.getTimes() != null ? ae.getTimes() : 0; //更新状态 aeDao.update(UpdateBuilder.from(AloneExam.class) .addUpdateField("status", AloneExam.STATUS_NORMAL) + .addUpdateField("times", currentTimes+1) .addFilter(FieldFilters.eq("aid", aea.getAid())) .addFilter(FieldFilters.eq("testId", aea.getTestId())) .addFilter(FieldFilters.eq("status",AloneExam.STATUS_NONE)) @@ -53,8 +72,8 @@ public class AloneExamServiceImpl implements IAloneExamService{ } @Override - @Transactional - public void submit(AloneExamAnswer aea,Integer scoreType){ + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void submit(AloneExamAnswer aea, Integer scoreType){ //dao.update(aea); aea.setStatus(AloneExamAnswer.STATUS_FINISH); LocalDateTime now=LocalDateTime.now(); @@ -102,6 +121,27 @@ public class AloneExamServiceImpl implements IAloneExamService{ // } } } + @Override + public void syncExamScoreToCourseSuite(AloneExamAnswer aea, HttpServletRequest request) { + String token = request.getHeader("Xboe-Access-Token"); + if (StringUtils.isEmpty(token)) { + token = request.getHeader("token"); + } + + String finalToken = token; + CompletableFuture.supplyAsync(() -> { + AloneExam aloneExam = aeDao.findOne(FieldFilters.eq("aid", aea.getAid()), FieldFilters.eq("testId", aea.getTestId())); + if (aloneExam.getRefType().equals("14")){ + thirdApi.syncExamScoreToCourseSuite(aloneExam, finalToken); + } + return "完成结果"; + }).exceptionally(ex -> { + log.error("异步操作中发生错误: " + ex.getMessage(), ex); + return "发生错误"; + }).thenAccept(result -> { + log.info("同步考试成绩到课程项目完成:" + result); + }); + } @Override @Transactional @@ -427,4 +467,86 @@ public class AloneExamServiceImpl implements IAloneExamService{ rs.setPageSize(params.getPageSize()); return rs; } + + + @Autowired + private PlatformTransactionManager transactionManager; + + + @Override + public void examScoreBatchAdd(HttpServletRequest request, List saveExamScoreDtoList) { + List workNumList = saveExamScoreDtoList.stream().map(SaveExamScoreDto::getWorkNum).collect(Collectors.toList()); + + String token = request.getHeader("Xboe-Access-Token"); + if (StringUtils.isEmpty(token)) { + token = request.getHeader("token"); + } + HashMap userIdAndWorkNumMap = thirdApi.getUserIdByWorkNum(token, workNumList); + + saveExamScoreDtoList.forEach(examScoreDto -> { + TransactionStatus status = null; // 事务状态 + + try { + // 获取事务定义 + DefaultTransactionDefinition def = new DefaultTransactionDefinition(); + // 设置事务隔离级别 + def.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_COMMITTED); + // 设置事务传播行为 + def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED); + // 获取事务状态 + status = transactionManager.getTransaction(def); + + AloneExamAnswer aloneExamAnswer = new AloneExamAnswer(); + BeanUtils.copyProperties(examScoreDto, aloneExamAnswer); + + String userId = userIdAndWorkNumMap.get(examScoreDto.getWorkNum()); + aloneExamAnswer.setAid(userId); + aloneExamAnswer.setName(examScoreDto.getUserName()); + aloneExamAnswer.setUcode(examScoreDto.getWorkNum()); + aloneExamAnswer.setStatus(AloneExamAnswer.STATUS_FINISH); +// aloneExamAnswer.setUseSecond(examScoreDto.getUseMinute()*60); + + ExamTest examTest = examTestDao.get(examScoreDto.getTestId()); + aloneExamAnswer.setPassLine(examTest.getPassLine()); + aloneExamAnswer.setArrange(examTest.getArrange()); + aloneExamAnswer.setTestDuration(examTest.getTestDuration()); + + // 获取考试任务ID + AloneExam aloneExam=aeDao.findOne(FieldFilters.eq("aid", userId),FieldFilters.eq("testId", examScoreDto.getTestId())); + aloneExamAnswer.setAloneId(aloneExam.getId()); + // 添加答卷 + dao.save(aloneExamAnswer); + + // 更新状态,状态是未完成的,这里会有问题 + int currentTimes = aloneExam.getTimes() != null ? aloneExam.getTimes() : 0; + if(examTest.getScoringType()!=null && examTest.getScoringType()==2) { + //最后一次的分数为准 + aeDao.update(UpdateBuilder.from(AloneExam.class) + .addUpdateField("status", AloneExam.STATUS_FINISH) + .addUpdateField("score", examScoreDto.getScore()) + .addUpdateField("times", currentTimes+1) + .addFilter(FieldFilters.eq("aid", userId)) + .addFilter(FieldFilters.eq("testId", examScoreDto.getTestId())) + .builder()); + } else { + if (aloneExam.getStatus() == AloneExam.STATUS_FINISH) { + if (aloneExam.getScore() < examScoreDto.getScore()) { + aeDao.updateMultiFieldById(aloneExam.getId(), UpdateBuilder.create("score", examScoreDto.getScore()), UpdateBuilder.create("times", currentTimes+1)); + } + } else { + aeDao.updateMultiFieldById(aloneExam.getId(), UpdateBuilder.create("status", AloneExam.STATUS_FINISH), UpdateBuilder.create("score", examScoreDto.getScore()), UpdateBuilder.create("times", currentTimes+1)); + } + } + + // 提交事务 + transactionManager.commit(status); + } catch (Exception e) { + // 如果发生异常,回滚事务 + if (status != null && !status.isCompleted()) { + transactionManager.rollback(status); + } + throw new RuntimeException(e); + } + }); + } } diff --git a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/ExamTestServiceImpl.java b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/ExamTestServiceImpl.java index 14fda5bd..33d38cd8 100644 --- a/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/ExamTestServiceImpl.java +++ b/servers/boe-server-all/src/main/java/com/xboe/module/exam/service/impl/ExamTestServiceImpl.java @@ -122,4 +122,10 @@ public class ExamTestServiceImpl implements IExamTestService { } return null; } + + @Override + public void removeRel(List ids) { + String idsStr = String.join(",", ids); + examTestDao.sqlUpdate("update boe_exam_test set ref_status=0 where id in (?1)",idsStr); + } } diff --git a/servers/boe-server-all/src/main/resources/application.properties b/servers/boe-server-all/src/main/resources/application.properties index 01a9218f..41865a60 100644 --- a/servers/boe-server-all/src/main/resources/application.properties +++ b/servers/boe-server-all/src/main/resources/application.properties @@ -74,4 +74,7 @@ manageApi.stu.offcourse=${boe.domain}/manageApi/stu/offcourse/getOffCourseId manageApi.editExam=${boe.domain}/manageApi/admin/project/editExam #获取离职教师id userBasic.getTeacherIds=${boe.domain}/userbasic/user/getTeacherInfo -coursesuilt.getStudyStatus=${boe.domain}/manageApi/stu/project/completeStatus \ No newline at end of file +userBasic.getUserIdByWorkNum=${boe.domain}/userbasic/user/getUserIdByWorkNum +coursesuilt.getStudyStatus=${boe.domain}/manageApi/stu/project/completeStatus +coursesuilt.checkBanding=${boe.domain}/manageApi/stu/task/exam/checkBanding +coursesuilt.syncExamScoreToCourseSuite=${boe.domain}/manageApi/stu/task/exam/syncExamScoreToCourseSuite \ No newline at end of file