Compare commits

..

1 Commits

10 changed files with 20 additions and 207 deletions

View File

@@ -8,11 +8,9 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.boe.feign.api.courseweb.entity.ExamTestDto;
import com.boe.feign.api.courseweb.entity.ProjectStudyDto;
import com.boe.feign.api.courseweb.remote.ExternalRemoteClient;
import com.boe.feign.api.courseweb.remote.OffCourseRemoteClient;
import com.boe.feign.api.courseweb.remote.ProjectAdminRemoteClient;
import com.boe.feign.api.courseweb.remote.ProjectRemoteClient;
import com.boe.feign.api.courseweb.reps.ExamStudyRecordParam;
import com.boe.feign.api.infrastructure.entity.CommonSearchVo;
import com.boe.feign.api.infrastructure.entity.Dict;
import com.boe.feign.api.infrastructure.remote.DictRemoteClient;
@@ -75,8 +73,6 @@ public class ThirdApi {
@Resource
private ProjectRemoteClient projectRemoteClient;
@Resource
ExternalRemoteClient externalRemoteClient;
@Resource
private DictRemoteClient dictRemoteClient;
@@ -266,19 +262,11 @@ public class ThirdApi {
}
public List<StudyCourse> getStudyCourseList(String studyId, String courseId, String token) {
log.info(" 1 studyId = "+ studyId + " ,courseId = " + courseId );
if ( studyId == null || courseId == null ){
log.error(" 在线课学习记录 参数不能为空 ");
return new ArrayList<>();
}
StudyCourseVo studyCourseVo = new StudyCourseVo();
studyCourseVo.setStudyId(studyId);
studyCourseVo.setCourseId(courseId);
ProjectStudyDto projectStudyDto = new ProjectStudyDto();
// BeanUtil.copyProperties(studyCourseVo, studyCourseVo);
projectStudyDto.setStudyId(Long.parseLong(studyId));
projectStudyDto.setCourseId(Long.parseLong(courseId));
log.info(" 12 在线课学习记录 studyId = "+ projectStudyDto.getStudyId() + " ,courseId = " + projectStudyDto.getCourseId() );
BeanUtil.copyProperties(studyCourseVo, studyCourseVo);
projectRemoteClient.updateStudyStatus(projectStudyDto);
return new ArrayList<>();
}
@@ -394,8 +382,4 @@ public class ThirdApi {
.body()).orElseThrow(() -> new RuntimeException("token校验失败"));
log.info("updateOrSaveCourse = " + resp);
}
public void syncExamStudyRecord(ExamStudyRecordParam param) {
externalRemoteClient.syncExamStudyRecord(param);
}
}

View File

@@ -122,20 +122,13 @@ public class OutSideDataServiceImpl implements IOutSideDataService {
//这里应该是单独的线程去处理
user.setId(getNodeText(result.get("userId")));//最新接口变化id改成userId
String band=getNodeText(result.get("bandCode"));
try {
if(StringUtils.isNotBlank(band) && band.length()>4 && band.contains("band")) {
String bandNum=band.substring(4);
user.setBandLevel(Integer.valueOf(bandNum));
}else if (StringUtils.isNotBlank(band) && band.length()>4 && band.contains("Level")) {
String bandNum=band.substring(5);
user.setBandLevel(Integer.valueOf(bandNum));
}else {
user.setBandLevel(0);
}
} catch (NumberFormatException e) {
user.setBandLevel(0);
}
user.setAvatar(getNodeText(result.get("avatar")));
if(StringUtils.isNotBlank(band) && band.length()>4) {
String bandNum=band.substring(4);
user.setBandLevel(Integer.valueOf(bandNum));
}else {
user.setBandLevel(0);
}
user.setAvatar(getNodeText(result.get("avatar")));
user.setCode(getNodeText(result.get("userNo")));
if(StringUtils.isBlank(user.getCode())) {

View File

@@ -140,9 +140,6 @@ public class CasesApi extends ApiBaseController {
List<Cases> cases = views.getList();
if (CollUtil.isNotEmpty(cases)) {
for (Cases c : cases) {
if ("null".equals(c.getSummary())) {
c.setSummary(null);
}
StringBuffer stringBuffer = new StringBuffer();
List<CasesMajorType> caseId = casesMajorTypeDao.findList(FieldFilters.eq("caseId", c.getId()));
if (caseId != null && !caseId.isEmpty()) {

View File

@@ -49,12 +49,4 @@ public class CourseTeacher extends IdBaseEntity {
@Transient
private String code;
/**供应商*/
@Transient
private String supplier;
/**讲师类型 1 内部讲师 2外部讲师*/
@Transient
private Integer teacherType;
}

View File

@@ -480,7 +480,7 @@ public class CourseServiceImpl implements ICourseService {
String sql = "SELECT DISTINCT\n" +
"rt.course_id\n" +
"FROM\n" +
"boe_new.student s INNER JOIN boe_new.router_task rt on s.pid=rt.router_id inner join boe_course c on c.id=rt.course_id\n" +
"boe.student s INNER JOIN boe.router_task rt on s.pid=rt.router_id inner join boe_course c on c.id=rt.course_id\n" +
"\n" +
"WHERE\n" +
"\n" +
@@ -503,7 +503,7 @@ public class CourseServiceImpl implements ICourseService {
String sql = "SELECT DISTINCT\n" +
"pt.course_id\n" +
"FROM\n" +
"boe_new.student s INNER JOIN boe_new.project_task pt on s.pid=pt.project_id inner join boe_course c on c.id=pt.course_id\n" +
"boe.student s INNER JOIN boe.project_task pt on s.pid=pt.project_id inner join boe_course c on c.id=pt.course_id\n" +
"\n" +
"WHERE\n" +
"\n" +
@@ -560,8 +560,8 @@ public class CourseServiceImpl implements ICourseService {
String sql = "SELECT DISTINCT\n" +
"\tc.id \n" +
"FROM\n" +
"\tboe_new.student s\n" +
"\tINNER JOIN boe_new.grow_task gt ON s.pid = gt.grow_id\n" +
"\tboe.student s\n" +
"\tINNER JOIN boe.grow_task gt ON s.pid = gt.grow_id\n" +
"\tINNER JOIN boe_course c ON gt.course_id = c.id \n" +
"WHERE\n" +
"\ts.type = 14 \n" +

View File

@@ -8,8 +8,6 @@ import java.util.Map;
import javax.annotation.Resource;
import com.boe.feign.api.courseweb.reps.ExamStudyRecordParam;
import com.xboe.api.ThirdApi;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -39,10 +37,7 @@ public class AloneExamServiceImpl implements IAloneExamService{
@Resource
AloneExamDao aeDao;
@Resource
private ThirdApi thirdApi;
@Override
@Transactional
public void save(AloneExamAnswer aea){
@@ -106,18 +101,7 @@ public class AloneExamServiceImpl implements IAloneExamService{
// //这种情况汶是不存在的
// }
}
try {
ExamStudyRecordParam param = new ExamStudyRecordParam();
param.setTestId(aea.getTestId());
param.setAid(aea.getAid());
thirdApi.syncExamStudyRecord(param);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Override
@Transactional

View File

@@ -204,8 +204,6 @@ public class StudyCourseApi extends ApiBaseController{
Teacher t = teacherService.get(ct.getTeacherId());
if(t!=null) {
ct.setRemark(t.getDescription());
ct.setSupplier(t.getSupplier());
ct.setTeacherType(t.getTeacherType());
}
if(redisTemplate.opsForValue().get(ct.getTeacherId())==null){
List<String>list=new ArrayList<>();
@@ -214,11 +212,11 @@ public class StudyCourseApi extends ApiBaseController{
redisTemplate.opsForValue().set(teacherVo.get(0).getTeacherId(), teacherVo.get(0).getStatus());
//设置过期时间为1天
redisTemplate.expire(teacherVo.get(0).getTeacherId(), 24 * 60 * 60, TimeUnit.SECONDS);
if (Objects.equals(redisTemplate.opsForValue().get(ct.getTeacherId()), "1") && t.getTeacherType() == 1 ){
if (Objects.equals(redisTemplate.opsForValue().get(ct.getTeacherId()), "1")){
ct.setTeacherName("BOE教师");
}
}
if (Objects.equals(redisTemplate.opsForValue().get(ct.getTeacherId()), "1") && t.getTeacherType() == 1 ){
if (Objects.equals(redisTemplate.opsForValue().get(ct.getTeacherId()), "1")){
ct.setTeacherName("BOE教师");
}
}
@@ -345,8 +343,6 @@ public class StudyCourseApi extends ApiBaseController{
}
//追加学习时长
studyService.appendStudyDuration(sci.getStudyId(),item.getId(),sci.getContentId(),sci.getDuration());
log.info(" 1 在线课学习记录 sci.getStudyId() = "+ sci.getStudyId() + " , sci.getCourseId() = " + sci.getCourseId() );
List<StudyCourse> allUserList = thirdApi.getStudyCourseList(sci.getStudyId() ,sci.getCourseId(), token);
log.info("在线课学习记录"+allUserList);
return success(item.getId());

View File

@@ -1,108 +0,0 @@
package com.xboe.school.study.api;
import com.xboe.school.study.service.IStudyService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* @author by lyc
* @date 2025/3/3
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class StudyCourseTask {
private final IStudyService studyService;
private final StringRedisTemplate redisTemplate;
/**
* 定时任务
* 获取redis 中学习结束的数据更新入库
* */
@XxlJob("saveStudyCourseItemLastTime")
public void saveStudyCourseItemLastTime() {
log.info("------定时任务-获取redis 中学习结束的数据更新入库------" );
// 1. 定义匹配模式匹配所有目标key
final String KEY_PATTERN = "studyContentId:*:last_active";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
// 2. 使用SCAN安全遍历避免阻塞
ScanOptions options = ScanOptions.scanOptions()
.match(KEY_PATTERN)
.count(100) // 分页大小
.build();
try (RedisConnection connection = Objects.requireNonNull(redisTemplate.getConnectionFactory()).getConnection()) {
Cursor<byte[]> cursor = connection.scan(options);
// 3. 遍历处理符合条件的key
while (cursor.hasNext()) {
String redisKey = new String(cursor.next());
log.info("------定时任务-获取redis 中学习结束的数据更新入库------redisKey = " + redisKey );
// 4. 获取剩余TTL
Long ttl = redisTemplate.getExpire(redisKey, TimeUnit.SECONDS);
log.info("------定时任务-获取redis 中学习结束的数据更新入库------ttl = " + ttl );
// 5. 过滤条件:剩余时间 >= 29天23小时30分钟转换为秒
// 总需时间 = (30天 - 30分钟) = 29天23小时30分钟 = 2590200秒
// 5分钟 300秒 || 2592000 - 300 = 2591700
if (ttl <= 2590200) {
try {
// 6. 提取studyContentId
String[] parts = redisKey.split(":");
if (parts.length < 2) continue;
String studyContentId = parts[1];
// 7. 获取存储的时间点(示例逻辑)
String redisValue = redisTemplate.opsForValue().get(redisKey);
if (redisValue == null) continue;
String[] partValues = redisValue.split("&");
int lastStudyTime = Integer.parseInt(partValues[0]);
LocalDateTime timestamp = null;
if (partValues.length >= 2){
timestamp = LocalDateTime.parse(partValues[1], formatter);
}
log.info("-定时任务-获取redis 中学习结束的数据更新入库---studyContentId = " + studyContentId + ",lastStudyTime = " + lastStudyTime + ", timestamp = " + timestamp);
// 8. 更新数据库(调用已有服务方法)
studyService.updateStudyCourseItemLastTime(studyContentId, lastStudyTime, timestamp);
// 9. 删除Redis键原子操作
redisTemplate.delete(redisKey);
log.info("处理成功 key: {}, lastStudyTime: {}", redisKey, lastStudyTime);
} catch (Exception e) {
log.error("处理失败 key: {}", redisKey, e);
}
}
}
cursor.close();
} catch (Exception e) {
log.error("定时任务执行异常", e);
}
/* // 新增日志逻辑
if (ttl <= 172800) {
studyService.saveCourseExpireLog(
studyContentId,
lastStudyTime,
redisKey,
ttl,
"system_job"
);
}*/
}
}

View File

@@ -1,6 +1,5 @@
package com.xboe.school.study.service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@@ -100,5 +99,4 @@ public interface IStudyService {
List<StudyCourseItem> getList(String courseId, String contentId, String name, Integer status);
void updateStudyCourseItemLastTime(String studyContentId, int lastStudyTime, LocalDateTime timestamp);
}

View File

@@ -1,6 +1,5 @@
package com.xboe.school.study.service.impl;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
@@ -16,7 +15,6 @@ import com.xboe.school.study.entity.StudyCourse;
import com.xboe.system.user.entity.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.xboe.common.OrderCondition;
@@ -53,10 +51,7 @@ public class StudyServiceImpl implements IStudyService{
@Autowired
UserDao userDao;
@Autowired
StringRedisTemplate redisTemplate;
@Override
public StudyCourseItem checkHas(String studyId,String contentId) {
List<StudyCourseItem> items = scItemDao.findList(FieldFilters.eq("studyId", studyId),FieldFilters.eq("contentId", contentId));
@@ -328,27 +323,9 @@ public class StudyServiceImpl implements IStudyService{
}
// 更新 前端传输已学习时长
@Override
public void updateLastTime(String studyContentId, int lastStudyTime,String aid) {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
String value = lastStudyTime + "&" + now.format(formatter); // 使用ISO8601时间格式
log.info("-study-video-time-----value = " + value);
// 20250303 优化 多次更新改一次更新
// 更新Redis中的最后活跃时间带30秒过期
redisTemplate.opsForValue().set(
"studyContentId:" + studyContentId + ":last_active",
value,
Duration.ofSeconds(2592000)
);
log.info("-study-video-time-redis保存---value = " + value);
// Duration.ofDays(30) 也就是 2592000秒
}
@Override
@Transactional
public void updateStudyCourseItemLastTime(String studyContentId, int lastStudyTime,LocalDateTime timestamp) {
log.info("-study-video-time-定时---studyContentId = " + studyContentId + ",lastStudyTime = " + lastStudyTime + ", timestamp = " + timestamp);
public void updateLastTime(String studyContentId, int lastStudyTime,String aid) {
// 更新最后的学习时间点
LocalDateTime now=LocalDateTime.now();
UpdateBuilder update=UpdateBuilder.from(StudyCourseItem.class);
@@ -356,9 +333,9 @@ public class StudyServiceImpl implements IStudyService{
//只记录时间长的时候的处理
update.addFilter(FieldFilters.lt("lastStudyTime", lastStudyTime));
update.addUpdateField("lastStudyTime", lastStudyTime);
update.addUpdateField("lastTime", timestamp==null ? now : timestamp);
update.addUpdateField("lastTime", now);
scItemDao.update(update.builder());
log.info("-study-video-time-mysql保存---studyContentId = " + studyContentId);
//增加用户的学习时长,在api中调用
}
@Override