refactor: 根包由 com.bestsch.bschclassmanage 重命名为 com.yunhai.bschclassmanage
- git mv src/main/java/com/bestsch/bschclassmanage -> src/main/java/com/yunhai/bschclassmanage - 255 个 Java 文件的 package/import 同步替换为 com.yunhai.bschclassmanage - pom.xml 项目 groupId 设为 com.yunhai(与外部依赖 com.bestsch:bsch-* 无关,未改动) - IDE 缓存 workspace.xml 路径同步更新(外部依赖坐标 com.bestsch:bsch-* 保持不动)
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
package com.yunhai.bschclassmanage.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.yunhai.bschclassmanage.Repository.SchClassRepository;
|
||||
import com.yunhai.bschclassmanage.Repository.SchDicCampusRepository;
|
||||
import com.yunhai.bschclassmanage.annotation.OperationLog;
|
||||
import com.yunhai.bschclassmanage.entity.SchDicCampus;
|
||||
import com.yunhai.bschclassmanage.model.constant.LogModule;
|
||||
import com.yunhai.bschclassmanage.model.entityField.EntityFieldNames;
|
||||
import com.yunhai.bschclassmanage.model.vo.SelectIntVO;
|
||||
import com.yunhai.bschclassmanage.service.ISchDicCampusService;
|
||||
import com.yunhai.bschclassmanage.utils.*;
|
||||
import com.yunhai.platform.utils.exception.DException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SchDicCampusService implements ISchDicCampusService {
|
||||
|
||||
@Autowired
|
||||
private SchDicCampusRepository schDicCampusRepository;
|
||||
|
||||
|
||||
@Autowired
|
||||
private SchClassRepository schClassRepository;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
|
||||
public List<SchDicCampus> getSchDicCampusList(Integer schId) {
|
||||
Specification<SchDicCampus> spec = (root, query, cb) -> {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
predicates.add(cb.equal(root.get(EntityFieldNames.schId), schId));
|
||||
return cb.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
return schDicCampusRepository.findAll(spec);
|
||||
}
|
||||
|
||||
// 获取学校院校列表(带缓存)
|
||||
public List<SchDicCampus> getSchDicCampusCacheList(Integer schId) {
|
||||
String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + schId;
|
||||
if (redisUtil.hasKey(cacheKey)) {
|
||||
// 注意:返回副本或不可变列表,避免外部修改影响缓存
|
||||
return redisUtil.getList(cacheKey,SchDicCampus.class);
|
||||
}
|
||||
// 同步查询数据库,防止缓存击穿
|
||||
synchronized (this) {
|
||||
if (redisUtil.hasKey(cacheKey)) {
|
||||
return redisUtil.getList(cacheKey,SchDicCampus.class);
|
||||
}
|
||||
List<SchDicCampus> list = getSchDicCampusList(schId);
|
||||
|
||||
// 根据 sort 字段升序排序,null 值排在最后
|
||||
list.sort(Comparator.comparing(SchDicCampus::getSort,
|
||||
Comparator.nullsLast(Comparator.naturalOrder())));
|
||||
|
||||
redisUtil.set(cacheKey, new ArrayList<>(list), RedisConstants.CACHE_EXPIRE_30D);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@OperationLog(module = LogModule.CAMPUS)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveSchCampus(UserContext.UserInfo user, SchDicCampus entity) {
|
||||
|
||||
Integer schId=user.getSchId();
|
||||
|
||||
boolean isNew=entity.getId() == null || entity.getId() == 0;
|
||||
// 参数校验
|
||||
if (entity.getName() == null || entity.getName().trim().isEmpty())
|
||||
throw new IllegalArgumentException("校区名称不能为空");
|
||||
|
||||
boolean nameExists;
|
||||
SchDicCampus oldEntity=null;
|
||||
|
||||
if (isNew) {
|
||||
// 新增:检查同名校区
|
||||
nameExists = schDicCampusRepository.existsBySchIdAndName(schId, entity.getName());
|
||||
if (nameExists) {
|
||||
throw new IllegalArgumentException("校区名称已存在:" + entity.getName());
|
||||
}
|
||||
OtherUtil.setBaseEntityValue(user, entity);
|
||||
|
||||
schDicCampusRepository.save(entity);
|
||||
} else {
|
||||
// 更新:排除自身,检查其他校区同名
|
||||
nameExists = schDicCampusRepository.existsBySchIdAndNameAndIdNot(schId, entity.getName(), entity.getId());
|
||||
if (nameExists) {
|
||||
throw new IllegalArgumentException("校区名称已存在:" + entity.getName());
|
||||
}
|
||||
Integer entityId=entity.getId();
|
||||
SchDicCampus existing = schDicCampusRepository.findById(entityId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("校区不存在,ID=" + entityId));
|
||||
|
||||
oldEntity=OtherUtil.deepCopy(existing,SchDicCampus.class);
|
||||
|
||||
OtherUtil.setBaseEntityValue(user, entity);
|
||||
|
||||
BeanUtils.copyProperties(entity, existing,
|
||||
EntityFieldNames.id,
|
||||
EntityFieldNames.schId,
|
||||
EntityFieldNames.code,
|
||||
EntityFieldNames.createDate,
|
||||
EntityFieldNames.createUserId);
|
||||
|
||||
entity=schDicCampusRepository.save(existing);
|
||||
}
|
||||
|
||||
// 清除缓存
|
||||
String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + schId;
|
||||
redisUtil.del(cacheKey);
|
||||
|
||||
{
|
||||
String description = buildCampusLogDescription(entity,isNew,oldEntity);
|
||||
LogContextHolder.setDescription(description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建学部操作的详细日志描述
|
||||
*/
|
||||
private String buildCampusLogDescription(SchDicCampus newEntity,boolean isNew,SchDicCampus oldEntity) {
|
||||
if (isNew) {
|
||||
return String.format("新增校区:%s(序号:%d)",
|
||||
newEntity.getName(),
|
||||
newEntity.getSort() != null ? newEntity.getSort() : 0);
|
||||
} else {
|
||||
List<String> changes = new ArrayList<>();
|
||||
if (!Objects.equals(oldEntity.getName(), newEntity.getName())) {
|
||||
changes.add(String.format("名称从 '%s' 修改为 '%s'", oldEntity.getName(), newEntity.getName()));
|
||||
}
|
||||
if (!Objects.equals(oldEntity.getSort(), newEntity.getSort())) {
|
||||
changes.add(String.format("序号从 %d 修改为 %d", oldEntity.getSort(), newEntity.getSort()));
|
||||
}
|
||||
if (changes.isEmpty()) {
|
||||
return "更新校区:无实际变更";
|
||||
}
|
||||
return "更新校区:" + String.join(";", changes);
|
||||
}
|
||||
}
|
||||
|
||||
@OperationLog(module = LogModule.CAMPUS)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void sortSchCampus(UserContext.UserInfo user,List<Integer> ids)
|
||||
{
|
||||
List<SchDicCampus> campusList = getSchDicCampusCacheList(user.getSchId());
|
||||
Map<Integer, SchDicCampus> campusMap = campusList.stream()
|
||||
.collect(Collectors.toMap(SchDicCampus::getId, Function.identity()));
|
||||
|
||||
Date now = new Date();
|
||||
// 1. 按传入顺序更新 sort 值
|
||||
int sortOrder = 1;
|
||||
for (Integer id : ids) {
|
||||
SchDicCampus campus = campusMap.get(id);
|
||||
if (campus != null) {
|
||||
campus.setSort(sortOrder++);
|
||||
campus.setUpdateDate(now);
|
||||
campus.setUpdateUserId(user.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 处理未出现在排序列表中的校区(设置 sort = null 或一个大值)
|
||||
for (SchDicCampus campus : campusList) {
|
||||
if (!ids.contains(campus.getId())) {
|
||||
campus.setSort(null); // 或者设置一个最大值,比如 999
|
||||
campus.setUpdateDate(now);
|
||||
campus.setUpdateUserId(user.getUserId());
|
||||
}
|
||||
}
|
||||
// 批量保存
|
||||
schDicCampusRepository.saveAll(campusList);
|
||||
String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + user.getSchId();
|
||||
redisUtil.del(cacheKey);
|
||||
{
|
||||
String names = ids.stream()
|
||||
.map(id -> {
|
||||
SchDicCampus m = campusMap.get(id);
|
||||
return m != null ? m.getName() : String.valueOf(id);
|
||||
})
|
||||
.collect(Collectors.joining("、"));
|
||||
String description = String.format("调整校区排序:共 %d 个专业(列表:%s)", ids.size(), names);
|
||||
LogContextHolder.setDescription(description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除校区
|
||||
* 1. 参数非空校验
|
||||
* 2. 校验校区是否存在(匹配学校+校区ID,防止跨学校删除)
|
||||
* 3. 校验校区是否绑定班级,存在关联则禁止删除
|
||||
* 4. 删除数据库数据 + 清除对应学校校区缓存
|
||||
* @param id 校区ID
|
||||
*/
|
||||
|
||||
@OperationLog(module = LogModule.CAMPUS)
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(UserContext.UserInfo user, Integer id) {
|
||||
// 1. 参数合法性校验
|
||||
if (user.getSchId() == null || id == null) {
|
||||
throw new DException("学校ID、校区ID不能为空");
|
||||
}
|
||||
|
||||
// 2. 校验当前学校下该校区是否存在,防止越权删除其他学校校区
|
||||
SchDicCampus campus = schDicCampusRepository.findByIdAndSchId(id, user.getSchId())
|
||||
.orElseThrow(() -> new DException("校区不存在,无法删除"));
|
||||
|
||||
// 3. 业务校验:判断校区是否关联班级,有班级则禁止删除
|
||||
long bindClassCount = schClassRepository.countByCampusId(id);
|
||||
if (bindClassCount > 0) {
|
||||
throw new DException(String.format("该校区下存在%s个班级,不可删除,请先移除班级关联", bindClassCount));
|
||||
}
|
||||
|
||||
// 4. 删除数据
|
||||
schDicCampusRepository.delete(campus);
|
||||
|
||||
// 5. 清除当前学校校区缓存
|
||||
String cacheKey = RedisConstants.SCHOOL_CAMPUS + "_" + user.getSchId();
|
||||
redisUtil.del(cacheKey);
|
||||
|
||||
LogContextHolder.setDescription("删除校区:"+campus.getName());
|
||||
log.debug("操作人:{},删除校区日志:{}", user.getUserName(), JSON.toJSONString(campus));
|
||||
}
|
||||
|
||||
public List<SelectIntVO> select(Integer schId) {
|
||||
List<SchDicCampus> list = getSchDicCampusCacheList(schId);
|
||||
return ModelMapperUtil.toSelectIntVOList(list, SchDicCampus::getId, SchDicCampus::getName);
|
||||
}
|
||||
|
||||
public Map<Integer, String> toIdAndNameMap(Integer schId) {
|
||||
List<SchDicCampus> list = getSchDicCampusCacheList(schId);
|
||||
return ModelMapperUtil.toMap(list, SchDicCampus::getId, SchDicCampus::getName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user