Compare commits

..

1 Commits

Author SHA1 Message Date
yangxinyu
c01a69c9df feat:提交审核(目前只完成停用/启用部分内容) 2025-12-10 17:50:46 +08:00
14 changed files with 251 additions and 100 deletions

View File

@@ -1,54 +0,0 @@
package com.xboe.module.course.api;
import com.xboe.core.JsonResponse;
import com.xboe.core.api.ApiBaseController;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.WrapperQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Collections;
@RestController
@RequestMapping("/xboe/m/course/manage")
@Slf4j
public class CourseEsApi extends ApiBaseController {
@Autowired(required = false)
private RestHighLevelClient restHighLevelClient;
@GetMapping("/es/sort")
public JsonResponse updateSortWeight() {
UpdateByQueryRequest request = new UpdateByQueryRequest("new_resource_list");
// 使用 Painless 脚本为文档添加 sortWeight 字段
Script script = new Script(
ScriptType.INLINE,
"painless",
"ctx._source.sortWeight = 9999",
Collections.emptyMap()
);
request.setScript(script);
// 可选:只更新那些还没有 sortWeight 字段的文档(避免覆盖已有值)
String query = "{ \"bool\": { \"must_not\": { \"exists\": { \"field\": \"sortWeight\" } } } }";
request.setQuery(new WrapperQueryBuilder(query));
try {
BulkByScrollResponse response = restHighLevelClient.updateByQuery(request, RequestOptions.DEFAULT);
return success(response.getUpdated());
} catch (IOException e) {
log.error("更新索引失败", e);
return error("更新索引失败");
}
}
}

View File

@@ -68,6 +68,9 @@ public class CourseManageApi extends ApiBaseController{
@Autowired
IOutSideDataService outsideService;
@Autowired
ICourseManageService courseManageService;
@Resource
IEmailService service;
@@ -688,6 +691,72 @@ public class CourseManageApi extends ApiBaseController{
return error("提交课程处理失败",e.getMessage());
}
}
/**
* 25.12.10新增提交审核到BPM
*
*
*/
@PostMapping("/bpm-submit")
@AutoLog(module = "课程",action = "提交审核到BPM",info = "")
public JsonResponse<BPMResponseDto> submitBPMCourseFull(@RequestBody CourseFullDto dto){
try {
BPMResponseDto response = null;
//首先判断是否为停用审核
if(dto.getAuditType() != null && dto.getAuditType()==0)
{
// 准备停用审核的JSON请求体,暂时先按照京东方大学堂后端调用BPM系统需要的接口文档的入参示例完成等到有外部接口时再修改
String jsonRequestBody = courseManageService.prepareDisableAuditRequest(dto);
// TODO: 调用BPM接口
// BPMResponseDto bpmResponsedto= courseManageService.callBPMInterface(jsonRequestBody);
// 构造返回结果
//实际使用中返回的值从BPM接口返回的JSON中获取
BPMResponseDto bpmResponsedto = new BPMResponseDto();
bpmResponsedto.setStatus("success");
bpmResponsedto.setAuditId("audit123456");
bpmResponsedto.setAuditApprover("管理员hrbp");
return success(bpmResponsedto);
}
//再判断是否为启用审核
else if(dto.getAuditType() != null && dto.getAuditType()==3)
{
// 准备启用审核的JSON请求体,暂时先按照京东方大学堂后端调用BPM系统需要的接口文档的入参示例完成等到有外部接口时再修改
String jsonRequestBody = courseManageService.prepareDisableAuditRequest(dto);
// TODO: 调用BPM接口
// BPMResponseDto bpmResponsedto= courseManageService.callBPMInterface(jsonRequestBody);
// 构造返回结果
//实际使用中返回的值从BPM接口返回的JSON中获取
BPMResponseDto bpmResponsedto = new BPMResponseDto();
bpmResponsedto.setStatus("success");
bpmResponsedto.setAuditId("audit123456");
bpmResponsedto.setAuditApprover("管理员hrbp");
return success(bpmResponsedto);
}
else{
//通过查看在boe_course_hrbp_audit表当中有没有旧的审核记录数据判断为创建审核还是编辑审核
//注:此处需要查一下查看表的时候需要限定审核记录的状态嘛,先查再问项目经理
String courseId=dto.getCourse().getId();
CourseHRBPAudit previousAudit = hrbpAuditService.hadAuditing(courseId);
if (previousAudit != null) {
// 存在历史审核记录,视为编辑审核
dto.setAuditType(2);
} else {
// 无历史审核记录,视为创建审核
dto.setAuditType(1);
}
}
return success(response);
} catch (Exception e) {
log.error("提交保存课程信息错误",e);
return error("error");
}
}
private String createEmailHtml(String name,String orgId, String orgName,String createBy,String courseName) throws Exception {
StringBuffer htmlMsg=new StringBuffer("<div style=\"line-height:30px;border:2px solid #2990ca;padding:20px\">");

View File

@@ -240,12 +240,12 @@ public class CourseDao extends BaseDao<Course> {
builder.append(" FROM boe_course c");
// 聚合教师姓名
builder.append(System.lineSeparator());
builder.append("LEFT JOIN (SELECT course_id, GROUP_CONCAT(teacher_name ORDER BY id SEPARATOR '') AS teacher_names FROM boe_course_teacher GROUP BY course_id) tch ON c.id = tch.course_id");
builder.append("LEFT JOIN (SELECT course_id, GROUP_CONCAT(teacher_name ORDER BY id SEPARATOR ',') AS teacher_names FROM boe_course_teacher GROUP BY course_id) tch ON c.id = tch.course_id");
// 学习人数聚合(满足时间条件的学习记录,且学习记录有效)
builder.append(System.lineSeparator());
builder.append("LEFT JOIN (SELECT course_id, COUNT(*) AS studys FROM boe_study_course WHERE status > 1");
builder.append("LEFT JOIN (SELECT course_id, COUNT(*) AS studys FROM boe_study_course");
if (filterLearningTime) {
builder.append(" AND (add_time >= :learningTimeStart AND add_time <= :learningTimeEnd) OR (finish_time >= :learningTimeStart AND finish_time <= :learningTimeEnd)");
builder.append(" WHERE (add_time >= :learningTimeStart AND add_time <= :learningTimeEnd) OR (finish_time >= :learningTimeStart AND finish_time <= :learningTimeEnd)");
}
builder.append(" GROUP BY course_id) stu ON c.id = stu.course_id");
// 评分聚合(在时间区间内的有效打分)
@@ -265,12 +265,6 @@ public class CourseDao extends BaseDao<Course> {
// 教师联查
builder.append(System.lineSeparator());
builder.append("LEFT JOIN boe_course_teacher ct ON c.id = ct.course_id");
// 排序字段是否为sysType
if (StringUtils.equals(queryDTO.getOrderField(), "sysType")) {
builder.append(System.lineSeparator()).append("LEFT JOIN boe_sys_type st1 ON c.sys_type1 = st1.id");
builder.append(System.lineSeparator()).append("LEFT JOIN boe_sys_type st2 ON c.sys_type2 = st2.id");
builder.append(System.lineSeparator()).append("LEFT JOIN boe_sys_type st3 ON c.sys_type3 = st3.id");
}
// where条件
// 第一个条件deleted = 0
@@ -336,12 +330,7 @@ public class CourseDao extends BaseDao<Course> {
}
if (queryDTO.getOpenCourse() != null) {
builder.append(System.lineSeparator());
// 兼容null数据
if (queryDTO.getOpenCourse() == 0) {
builder.append("AND (c.open_course IS NULL or c.open_course = 0)");
} else {
builder.append("AND c.open_course = 1");
}
builder.append("AND c.open_course = :openCourse");
}
if (StringUtils.isNotBlank(queryDTO.getOrgId())) {
builder.append(System.lineSeparator());
@@ -380,8 +369,7 @@ public class CourseDao extends BaseDao<Course> {
// 多字段排序: sysType resOwner
if (StringUtils.equals(orderField, "sysType")) {
for (int i = 1; i <= 3; i++) {
builder.append("st1.name ").append(orderAscStr).append(", st2.name ").append(orderAscStr).append(", st3.name ").append(orderAscStr).append(", ");
// builder.append("c.").append(orderFieldSql).append(i).append(" ").append(orderAscStr).append(", ");
builder.append("c.").append(orderFieldSql).append(i).append(" ").append(orderAscStr).append(", ");
}
} else if (StringUtils.equals(orderField, "resOwner")) {
builder.append("org.org_name ").append(orderAscStr).append(", ");
@@ -432,8 +420,8 @@ public class CourseDao extends BaseDao<Course> {
query.setParameter("publish", queryDTO.getPublish());
}
if (filterLearningTime) {
query.setParameter("learningTimeStart", queryDTO.getLearningTimeStart().withHour(0).withMinute(0).withSecond(0));
query.setParameter("learningTimeEnd", queryDTO.getLearningTimeEnd().withHour(23).withMinute(59).withSecond(59));
query.setParameter("learningTimeStart", queryDTO.getLearningTimeStart());
query.setParameter("learningTimeEnd", queryDTO.getLearningTimeEnd());
}
if (StringUtils.isNotBlank(queryDTO.getTeacherId())) {
String teacherIdStr = queryDTO.getTeacherId();
@@ -447,10 +435,9 @@ public class CourseDao extends BaseDao<Course> {
if (queryDTO.getEnabled() != null) {
query.setParameter("enabled", queryDTO.getEnabled());
}
// 这部分在where条件消化掉了故去掉
// if (queryDTO.getOpenCourse() != null) {
// query.setParameter("openCourse", queryDTO.getOpenCourse());
// }
if (queryDTO.getOpenCourse() != null) {
query.setParameter("openCourse", queryDTO.getOpenCourse());
}
if (StringUtils.isNotBlank(queryDTO.getResOwner1())) {
query.setParameter("orgId", queryDTO.getResOwner1());
}

View File

@@ -0,0 +1,26 @@
package com.xboe.module.course.dto;
import lombok.Data;
/**
* 25.12.10新增提交审核到BPM时的返回结果
*
*/
@Data
public class BPMResponseDto {
/**
* 调用BPM返回的状态success/error
*/
private String status;
/**
* 调用BPM成功时返回的审批单ID
*/
private String auditId;
/**
* 调用BPM成功时返回的审批人姓名
*/
private String auditApprover;
/**
* 调用BPM失败时返回的错误信息
*/
private String message;
}

View File

@@ -18,6 +18,20 @@ import lombok.Data;
*/
@Data
public class CourseFullDto {
/**
* 25.12.10新增
* 审核类型
* 0: 停用审核
* 1: 创建审核
* 2: 编辑审核
* 3启用审核
*/
private Integer auditType;
/**
* 25.12.10新增
* 提交审核的用户id
*/
private String userId;
/**是否是新建课程*/
private Boolean isNew;

View File

@@ -27,11 +27,6 @@ public class CourseToCourseFullText {
cft.setDevice(c.getDevice());
cft.setIsTop(c.getIsTop()? 1:0);
if (c.getSortWeight() != null) {
cft.setSortWeight(c.getSortWeight());
} else {
cft.setSortWeight(9999);
}
cft.setKeywords(c.getKeywords());
//DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//Long second = c.getPublishTime().toEpochSecond(ZoneOffset.of("+8"));

View File

@@ -32,6 +32,14 @@ public interface ICourseHRBPAuditService {
*/
CourseHRBPAudit hasAuditing(String courseId);
/**
* 25.12.10新增
* 检查课程是否已经有过审核记录了
* @param courseId
* @return
*/
CourseHRBPAudit hadAuditing(String courseId);
/**
* 根据课程、id获取课程的审核记录
* @param info 审核信息

View File

@@ -0,0 +1,9 @@
package com.xboe.module.course.service;
import com.xboe.module.course.dto.BPMResponseDto;
import com.xboe.module.course.dto.CourseFullDto;
public interface ICourseManageService {
String prepareDisableAuditRequest(CourseFullDto dto);
BPMResponseDto callBPMInterface(String jsonRequestBody);
}

View File

@@ -171,6 +171,19 @@ public class CourseHRBPAuditServiceImpl implements ICourseHRBPAuditService {
return hrbp;
}
/**
* 25.12.10新增
* 检查课程是否已经有过审核记录了
* @param courseId
* @return
*/
@Override
public CourseHRBPAudit hadAuditing(String courseId) {
//未审核的
CourseHRBPAudit hrbp = courseHRBPAuditDao.findOne(FieldFilters.eq("courseId", courseId),FieldFilters.eq("status", 9));
return hrbp;
}
@Override
public PageList<CourseHRBPAudit> pageList(Integer pageIndex, Integer pageSize, int userType, CourseHRBPAudit info) {
QueryBuilder query=QueryBuilder.from(CourseHRBPAudit.class.getSimpleName()+" a,"+Course.class.getSimpleName()+" c");

View File

@@ -0,0 +1,91 @@
package com.xboe.module.course.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xboe.core.utils.OkHttpUtil;
import com.xboe.module.course.dto.BPMResponseDto;
import com.xboe.module.course.dto.CourseFullDto;
import com.xboe.module.course.service.ICourseManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class CourseManageServiceImpl implements ICourseManageService {
@Autowired
private OkHttpUtil okHttpUtil;
/**
* 调用外部接口前讲DTO转换成JSON字符串
*/
@Override
public String prepareDisableAuditRequest(CourseFullDto dto) {
try {
// 创建顶层对象
Map<String, Object> request = new HashMap<>();
// 构造auditContent部分
Map<String, Object> auditContent = new HashMap<>();
//auditContent.put("auditType", "停用课程");
if(dto.getAuditType()==0)
{
auditContent.put("auditType", "停用课程");
}
else{
auditContent.put("auditType", "启用课程");
}
// 构造courseInfo部分
Map<String, String> courseInfo = new HashMap<>();
courseInfo.put("name", dto.getCourse().getName());
auditContent.put("courseInfo", courseInfo);
// 将auditContent放入请求体
request.put("auditContent", auditContent);
// 添加用户ID
request.put("userId", dto.getUserId());
// 转换为JSON字符串
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(request);
} catch (Exception e) {
throw new RuntimeException("构造停用审核JSON请求体失败", e);
}
}
/**
* 调用外部接口
*/
@Override
public BPMResponseDto callBPMInterface(String jsonRequestBody){
try {
String token = "";
// BPM接口地址,先按照接口文档写,得到实际的地址之后再修改
String url = "http://bpm-system-address/xboe/bpm/audit/submit";
// 设置请求头
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
// 添加认证头
headers.put("Authorization", "Bearer " + token);
// Map转String数组
List<String> headerList = new ArrayList<>();
for (Map.Entry<String, String> entry : headers.entrySet()) {
headerList.add(entry.getKey() + ":" + entry.getValue());
}
String[] headerArr = headerList.toArray(new String[0]);
// 发送POST请求
String response = okHttpUtil.doPostJson(url, jsonRequestBody,headerArr);
// 解析响应
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(response, BPMResponseDto.class);
} catch (Exception e) {
throw new RuntimeException("调用BPM接口失败: " + e.getMessage());
}
}
}

View File

@@ -119,7 +119,7 @@ public class CoursePageServiceImpl implements ICoursePageService {
}
return courseList.stream()
.map(c -> convertToVo(c, courseTeacherList))
.sorted(Comparator.comparing(CoursePageVo::getSortWeight, Comparator.nullsLast(Comparator.naturalOrder())))
.sorted(Comparator.comparing(CoursePageVo::getSortWeight)) // 按照sortWeight字段进行排序
.collect(Collectors.toList());
}
@@ -245,16 +245,15 @@ public class CoursePageServiceImpl implements ICoursePageService {
// 课程时长:秒转分
map.put("courseDuration", coursePageVo.getCourseDuration() / 60);
map.put("studys", coursePageVo.getStudys());
// 课程评分显示1位小数四舍五入
map.put("score", coursePageVo.getScore() == null ? "0.0" : String.format("%.1f", coursePageVo.getScore()));
map.put("score", coursePageVo.getScore());
map.put("status", CourseStatusEnum.getByCode(coursePageVo.getStatus()).getLabel());
map.put("published", coursePageVo.getPublished() == null || !coursePageVo.getPublished() ? "未发布" : "已发布");
map.put("enabled", coursePageVo.getEnabled() == null || !coursePageVo.getEnabled() ? "停用" : "启用");
map.put("enabled", coursePageVo.getEnabled() == null || coursePageVo.getEnabled() ? "停用" : "启用");
map.put("openCourse", coursePageVo.getOpenCourse() == null || coursePageVo.getOpenCourse() == 0 ? "" : "");
map.put("orgName", coursePageVo.getOrgFullName()); // 修改为组织全名
map.put("sysCreateBy", coursePageVo.getSysCreateBy());
map.put("createFrom", CourseCreateFromEnum.getByCode(coursePageVo.getCreateFrom()).getLabel());
map.put("sysCreateTime", coursePageVo.getSysCreateTime() == null ? "" : formatter.format(coursePageVo.getSysCreateTime()));
map.put("sysCreateTime", formatter.format(coursePageVo.getSysCreateTime()));
dataList.add(map);
}

View File

@@ -65,15 +65,13 @@ public class StudySignupApi extends ApiBaseController{
* @return 返回课程报名表的集合
*/
@PostMapping("/pagelist")
public JsonResponse<PageList<StudySignup>> findPage(Pagination pager, String courseId, String name, Integer signType,String aid) {
public JsonResponse<PageList<StudySignup>> findPage(Pagination pager, String courseId, String name, Integer signType) {
// if(StringUtils.isBlank(courseId)){
// return error("无课程信息");
// }
StudySignup ss=new StudySignup();
ss.setCourseId(courseId);
ss.setName(name);
//25.12.11 新增aid筛选
ss.setAid(aid);
//2025.11.28 新增signType筛选
ss.setSignType(signType);
//CurrentUser cuser=getCurrent();

View File

@@ -159,10 +159,8 @@ public class StudyCourseServiceImpl implements IStudyCourseService{
if(sc.getStartTime()!=null){
query.addFilter(FieldFilters.eq("startTime",sc.getStartTime()));
}
//25.12.11新增添加根据用户aid通过逗号分隔查询
if(StringUtils.isNotBlank(sc.getAid())) {
String userIdStr=sc.getAid();
query.addFilter(FieldFilters.in("aid",userIdStr.split(",")));
query.addFilter(FieldFilters.eq("aid", sc.getAid()));
}
}
// 原有查询是否结束逻辑

View File

@@ -223,11 +223,9 @@ public class StudySignupServiceImpl implements IStudySignupService{
if(ss.getCourseType()!=null) {
query.addFilter(FieldFilters.eq("courseType", ss.getCourseType()));
}
//25.12.11新增添加根据用户aid通过逗号分隔查询
if(StringUtils.isNotBlank(ss.getAid())){
String userIdStr = ss.getAid();
query.addFilter(FieldFilters.in("aid",userIdStr.split(",")));
}
if(StringUtils.isNotBlank(ss.getAid())) {
query.addFilter(FieldFilters.eq("aid", ss.getAid()));
}
// 25.11.26新增添加根据报名方式查询1自主报名2管理代报
if (ss.getSignType() != null) {
query.addFilter(FieldFilters.eq("signType", ss.getSignType()));