package com.yunhai.bschclassmanage.service.impl; import com.yunhai.bschclassmanage.Repository.BaseYearTermRepository; import com.yunhai.bschclassmanage.annotation.OperationLog; import com.yunhai.bschclassmanage.entity.BaseYearTerm; import com.yunhai.bschclassmanage.model.entityField.EntityFieldNames; import com.yunhai.bschclassmanage.model.tool.YearTerm; import com.yunhai.bschclassmanage.model.vo.BaseYearTermVO; import com.yunhai.bschclassmanage.service.IBaseYearTermService; import com.yunhai.bschclassmanage.service.ILogService; import com.yunhai.bschclassmanage.utils.LogContextHolder; import com.yunhai.bschclassmanage.utils.RedisConstants; import com.yunhai.bschclassmanage.utils.RedisUtil; import com.yunhai.bschclassmanage.utils.UserContext; import com.yunhai.platform.utils.exception.DException; import lombok.extern.slf4j.Slf4j; import org.apache.http.client.utils.DateUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.time.ZoneId; import java.util.*; import java.util.stream.Collectors; @Slf4j @Service public class BaseYearTermService implements IBaseYearTermService { @Autowired private BaseYearTermRepository baseYearTermRepository; @Autowired private RedisUtil redisUtil; @Autowired private ILogService logService; private static final String MODULE_SYSTEM="系统管理"; //学年学期 private String cacheKey = RedisConstants.SYSTEM_YEARTERM; public List getAllYearTerm() { if (redisUtil.hasKey(cacheKey)) { return redisUtil.getList(cacheKey, BaseYearTerm.class); } Sort sort = Sort.by(Sort.Order.desc(EntityFieldNames.year)); List clist = baseYearTermRepository.findAll(sort); redisUtil.set(cacheKey, clist, RedisConstants.CACHE_EXPIRE_30D); return clist; } public List getAllYearTermVO() { List entities = getAllYearTerm(); return convertToVOList(entities); } public BaseYearTerm getNowYearTerm() { Date now = new Date(); List yearTermList = getAllYearTerm(); if (yearTermList == null || yearTermList.isEmpty()) { return null; } return yearTermList.stream() .filter(s -> s.getYearStartDate().compareTo(now) <= 0 && s.getYearEndDate().compareTo(now) >= 0) .findFirst() .orElse(null); } @OperationLog(module = MODULE_SYSTEM) @Transactional(rollbackFor = Exception.class) public void createNowYearTerm(UserContext.UserInfo user,BaseYearTerm entity){ if(getAllYearTerm().stream().anyMatch(s->s.getYear().equals(entity.getYear()))) throw new DException("创建学年已存在!"); redisUtil.del(cacheKey); baseYearTermRepository.save(entity); { String content = createNowYearTermLog(entity); LogContextHolder.setDescription(content); } } private String createNowYearTermLog(BaseYearTerm entity) { try { // 构建日志内容 String content = String.format("创建新学年学期: 学年[%d], 学年起止[%s ~ %s], 第一学期[%s ~ %s], 第二学期[%s ~ %s], 升级日期[%s]", entity.getYear(), entity.getYearStartDate() != null ? entity.getYearStartDate().toString() : "未设置", entity.getYearEndDate() != null ? entity.getYearEndDate().toString() : "未设置", entity.getFirstTermStartDate() != null ? entity.getFirstTermStartDate().toString() : "未设置", entity.getFirstTermEndDate() != null ? entity.getFirstTermEndDate().toString() : "未设置", entity.getSecondTermStartDate() != null ? entity.getSecondTermStartDate().toString() : "未设置", entity.getSecondTermEndDate() != null ? entity.getSecondTermEndDate().toString() : "未设置", entity.getUpgradeDate() != null ? entity.getUpgradeDate().toString() : "未设置" ); return content; } catch (Exception e) { log.error("记录创建学年学期日志失败", e); return "创建学年学期日志失败"; } } @OperationLog(module = MODULE_SYSTEM) @Transactional(rollbackFor = Exception.class) public void updateYearTerm(UserContext.UserInfo user,BaseYearTerm entity){ if (entity.getId() == null) { throw new DException("更新时ID不能为空"); } BaseYearTerm existing = baseYearTermRepository.findById(entity.getId()) .orElseThrow(() -> new DException("学年记录不存在,ID=" + entity.getId())); BaseYearTerm oldEntity = new BaseYearTerm(); BeanUtils.copyProperties(existing, oldEntity); // 将传入 entity 中允许更新的字段复制到 existing,忽略 id 及创建审计字段 BeanUtils.copyProperties(entity, existing, EntityFieldNames.id, EntityFieldNames.createDate, EntityFieldNames.createUserId); redisUtil.del(cacheKey); baseYearTermRepository.save(entity); { String content = updateYearTermLog(user,oldEntity,entity); LogContextHolder.setDescription(content); } } private String updateYearTermLog(UserContext.UserInfo user,BaseYearTerm oldEntity, BaseYearTerm newEntity) { try { List changes = new ArrayList<>(); if (!oldEntity.getYear().equals(newEntity.getYear())) { changes.add("年份: " + oldEntity.getYear() + " -> " + newEntity.getYear()); } // 比较所有日期字段 compareDateField(changes, "学年开始", oldEntity.getYearStartDate(), newEntity.getYearStartDate()); compareDateField(changes, "学年结束", oldEntity.getYearEndDate(), newEntity.getYearEndDate()); compareDateField(changes, "第一学期开始", oldEntity.getFirstTermStartDate(), newEntity.getFirstTermStartDate()); compareDateField(changes, "第一学期结束", oldEntity.getFirstTermEndDate(), newEntity.getFirstTermEndDate()); compareDateField(changes, "第二学期开始", oldEntity.getSecondTermStartDate(), newEntity.getSecondTermStartDate()); compareDateField(changes, "第二学期结束", oldEntity.getSecondTermEndDate(), newEntity.getSecondTermEndDate()); compareDateField(changes, "升级日期", oldEntity.getUpgradeDate(), newEntity.getUpgradeDate()); String changeStr = changes.isEmpty() ? "无变化" : String.join("; ", changes); String content = String.format("更新学年学期(ID=%d,年份=%d):%s", newEntity.getId(), newEntity.getYear(), changeStr); return content; } catch (Exception e) { log.error("记录更新学年学期日志失败", e); return "更新学年学期日志失败"; } } private void compareDateField(List changes, String fieldName, Date oldDate, Date newDate) { // 如果两个日期都为 null,视为无变化 if (oldDate == null && newDate == null) { return; } // 如果其中一个为 null,或两者不相等,记录变更 if (oldDate == null || newDate == null || !oldDate.equals(newDate)) { String oldStr = oldDate != null ? DateUtils.formatDate(oldDate, "yyyy-MM-dd") : "null"; String newStr = newDate != null ? DateUtils.formatDate(newDate, "yyyy-MM-dd") : "null"; changes.add(fieldName + ": " + oldStr + " -> " + newStr); } } public BaseYearTermVO convertToVO(BaseYearTerm entity) { if (entity == null) return null; BaseYearTerm nowTerm = getNowYearTerm(); Integer nowId = nowTerm != null ? nowTerm.getId() : null; return BaseYearTermVO.of(entity, nowId); } public List convertToVOList(List entities) { if (entities == null) return null; BaseYearTerm nowTerm = getNowYearTerm(); Integer nowId = nowTerm != null ? nowTerm.getId() : null; return entities.stream() .map(entity -> BaseYearTermVO.of(entity, nowId)) .collect(Collectors.toList()); } public boolean isUpgradeDate(Date date) { if (date == null) { return false; } // 1. 获取当前学年 BaseYearTerm currentTerm = getNowYearTerm(); if (currentTerm == null) { return false; // 没有当前学年,无法升级 } // 2. 获取当前学年配置的升级日期 Date upgradeDate = currentTerm.getUpgradeDate(); if (upgradeDate == null) { return false; // 当前学年未设置升级日期 } // 3. 比较日期部分(忽略时分秒) Calendar inputCal = Calendar.getInstance(); inputCal.setTime(date); Calendar termCal = Calendar.getInstance(); termCal.setTime(upgradeDate); return inputCal.get(Calendar.YEAR) == termCal.get(Calendar.YEAR) && inputCal.get(Calendar.MONTH) == termCal.get(Calendar.MONTH) && inputCal.get(Calendar.DAY_OF_MONTH) == termCal.get(Calendar.DAY_OF_MONTH); } public boolean isBackupClassDataDate(Date date) { BaseYearTerm nowTerm = getNowYearTerm(); if (nowTerm == null) { return false; } LocalDate target = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); Date firstEnd = nowTerm.getFirstTermEndDate(); if (firstEnd != null) { LocalDate firstEndDate = firstEnd.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); if (target.equals(firstEndDate.plusDays(1))) { return true; } } Date secondEnd = nowTerm.getSecondTermEndDate(); if (secondEnd != null) { LocalDate secondEndDate = secondEnd.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); if (target.equals(secondEndDate.plusDays(1))) { return true; } } return false; } @Override public YearTerm getCurrentYearTerm() { BaseYearTerm nowTerm = getNowYearTerm(); if (nowTerm == null) { throw new DException("当前学年未设置,请先配置学年学期"); } int year = nowTerm.getYear(); int term = getCurrentTerm(); // 调用下面定义的 getCurrentTerm 方法 return new YearTerm(year, term); } // 辅助方法(如果还没实现) public int getCurrentYear() { BaseYearTerm nowTerm = getNowYearTerm(); if (nowTerm == null) { throw new DException("当前学年未设置"); } return nowTerm.getYear(); } public int getCurrentTerm() { BaseYearTerm nowTerm = getNowYearTerm(); if (nowTerm == null) { throw new DException("当前学年未设置"); } Date now = new Date(); Date firstStart = nowTerm.getFirstTermStartDate(); Date firstEnd = nowTerm.getFirstTermEndDate(); if (firstStart != null && firstEnd != null) { if (!now.before(firstStart) && !now.after(firstEnd)) { return 1; } } Date secondStart = nowTerm.getSecondTermStartDate(); Date secondEnd = nowTerm.getSecondTermEndDate(); if (secondStart != null && secondEnd != null) { if (!now.before(secondStart) && !now.after(secondEnd)) { return 2; } } throw new DException("当前日期不在任何学期区间内,请检查学年学期配置"); } }