package com.gkhy.exam.system.service.impl;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.gkhy.exam.common.api.CommonPage;
|
import com.gkhy.exam.common.api.CommonResult;
|
import com.gkhy.exam.common.exception.ApiException;
|
import com.gkhy.exam.common.utils.PageUtils;
|
import com.gkhy.exam.common.utils.SecurityUtils;
|
import com.gkhy.exam.system.domain.*;
|
import com.gkhy.exam.system.domain.vo.DeptDetialVo;
|
import com.gkhy.exam.system.mapper.InternalAuditCarryMapper;
|
import com.gkhy.exam.system.mapper.InternalAuditCheckCatalogueMapper;
|
import com.gkhy.exam.system.mapper.InternalAuditCheckContentMapper;
|
import com.gkhy.exam.system.mapper.SysClauseManagementMapper;
|
import com.gkhy.exam.system.service.InternalAuditCarryService;
|
import com.gkhy.exam.system.service.InternalAuditCheckService;
|
import org.checkerframework.checker.units.qual.A;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.StringUtils;
|
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class InternalAuditCarryServiceImpl extends ServiceImpl<InternalAuditCarryMapper, InternalAuditCarry> implements InternalAuditCarryService {
|
|
|
@Autowired
|
private InternalAuditCarryMapper carryMapper;
|
|
@Autowired
|
private InternalAuditCheckService internalAuditCheckService;
|
|
@Autowired
|
private SysClauseManagementMapper sysClauseManagementMapper;
|
|
@Autowired
|
private InternalAuditCheckCatalogueMapper checkCatalogueMapper;
|
|
@Autowired
|
private InternalAuditCheckContentMapper checkContentMapper;
|
|
@Autowired
|
private SysDeptServiceImpl sysDeptService;
|
|
@Override
|
public CommonPage selectCarryList(InternalAuditCarry carry) {
|
if (!SecurityUtils.adminUser()){
|
if (carry.getCompanyId()==null){
|
throw new ApiException("非管理员操作,企业id不可为空");
|
}
|
}
|
PageUtils.startPage();
|
List<InternalAuditCarry> internalAuditCarries = carryMapper.selectCarryList(carry);
|
for (InternalAuditCarry internalAuditCarry : internalAuditCarries) {
|
List<InternalAuditCarryDept> internalAuditCarryDepts = carryMapper.selectCarryDeptList(internalAuditCarry.getId());
|
internalAuditCarry.setDeptList(internalAuditCarryDepts);
|
}
|
return CommonPage.restPage(internalAuditCarries);
|
}
|
|
@Override
|
public CommonResult insertCarry(InternalAuditCarry carry) {
|
|
List<InternalAuditCarry> internalAuditCarries = carryMapper.selectList(Wrappers.<InternalAuditCarry>lambdaQuery()
|
.eq(InternalAuditCarry::getCompanyId, carry.getCompanyId())
|
.eq(InternalAuditCarry::getYear, carry.getYear())
|
.eq(InternalAuditCarry::getDelFlag,1));
|
if (internalAuditCarries.size()>0){
|
throw new ApiException("当前企业已有相关数据");
|
}
|
carry.setCreateBy(SecurityUtils.getUsername());
|
carry.setCreateTime(LocalDateTime.now());
|
carryMapper.insert(carry);
|
List<InternalAuditCarryDept> deptList = carry.getDeptList();
|
for (InternalAuditCarryDept internalAuditCarryDept : deptList) {
|
internalAuditCarryDept.setCarryId(carry.getId());
|
}
|
carryMapper.insertCarryDept(deptList);
|
|
saveInternalAuditCheck(carry);
|
|
return CommonResult.success();
|
}
|
|
private CommonResult saveInternalAuditCheck(InternalAuditCarry carry) {
|
// 2. 空指针防护:避免deptList为null导致循环NPE
|
List<InternalAuditCarryDept> deptList = carry.getDeptList();
|
if (CollectionUtils.isEmpty(deptList)) {
|
return CommonResult.success();
|
}
|
|
for (InternalAuditCarryDept internalAuditCarryDept : deptList) {
|
// 3. 跳过空的部门项,避免后续NPE
|
if (internalAuditCarryDept == null) {
|
continue;
|
}
|
|
InternalAuditCheck internalAuditCheck = new InternalAuditCheck();
|
// 基础字段赋值(保留原逻辑,无改动)
|
internalAuditCheck.setCompanyId(carry.getCompanyId());
|
internalAuditCheck.setYear(carry.getYear());
|
internalAuditCheck.setDeptId(internalAuditCarryDept.getDeptId());
|
internalAuditCheck.setPersonId(internalAuditCarryDept.getCheckId());
|
internalAuditCheck.setCheckTime(internalAuditCarryDept.getDate());
|
|
// 4. 时间字段安全赋值:避免date/startTime/endTime为null导致atTime()报错
|
LocalDate checkDate = internalAuditCarryDept.getDate();
|
LocalTime startTime = internalAuditCarryDept.getStartTime();
|
LocalTime endTime = internalAuditCarryDept.getEndTime();
|
if (checkDate != null && startTime != null) {
|
internalAuditCheck.setStartTime(checkDate.atTime(startTime));
|
}
|
if (checkDate != null && endTime != null) {
|
internalAuditCheck.setEndTime(checkDate.atTime(endTime));
|
}
|
|
// 5. 部门ID转换安全处理:避免非数字字符串导致NumberFormatException
|
Integer deptId1 = internalAuditCarryDept.getDeptId();
|
Long deptId;
|
try {
|
deptId = Long.valueOf(deptId1);
|
} catch (NumberFormatException e) {
|
continue;
|
}
|
|
// 6. 查询结果空防护:避免deptDetialVo为null导致后续getSysDeptResponsibilitys()报错
|
DeptDetialVo deptDetialVo = sysDeptService.selectDeptById(deptId);
|
if (deptDetialVo == null) {
|
continue;
|
}
|
|
List<SysDeptResponsibility> sysDeptResponsibilitys = deptDetialVo.getSysDeptResponsibilitys();
|
List<InternalAuditCheckCatalogue> internalAuditCheckCatalogues = new ArrayList<>();
|
// 7. 责任项列表空防护:避免循环null集合
|
if (!CollectionUtils.isEmpty(sysDeptResponsibilitys)) {
|
for (SysDeptResponsibility sysDeptResponsibility : sysDeptResponsibilitys) {
|
if (sysDeptResponsibility == null) {
|
continue;
|
}
|
|
InternalAuditCheckCatalogue internalAuditCheckCatalogue = new InternalAuditCheckCatalogue();
|
// 8. clauseId安全转换:避免null导致Math.toIntExact()报错
|
Long clauseId = sysDeptResponsibility.getClauseId();
|
if (clauseId != null) {
|
internalAuditCheckCatalogue.setCatalogueId(Math.toIntExact(clauseId));
|
} else {
|
continue;
|
}
|
|
// 9. 条款查询结果空防护:避免sysClauseManagement为null导致getPoints()报错
|
SysClauseManagement sysClauseManagement = sysClauseManagementMapper.selectById(clauseId);
|
if (sysClauseManagement == null) {
|
continue;
|
}
|
|
// 简化集合创建(原逻辑不变,仅优化初始化)
|
List<InternalAuditCheckContent> internalAuditCheckContents = new ArrayList<>();
|
InternalAuditCheckContent internalAuditCheckContent = new InternalAuditCheckContent();
|
internalAuditCheckContent.setPointKey(sysClauseManagement.getPoints());
|
internalAuditCheckContents.add(internalAuditCheckContent);
|
|
internalAuditCheckCatalogue.setCheckContents(internalAuditCheckContents);
|
internalAuditCheckCatalogues.add(internalAuditCheckCatalogue);
|
}
|
}
|
|
internalAuditCheck.setCheckCatalogues(internalAuditCheckCatalogues);
|
|
internalAuditCheckService.insertInternalAuditCheck(internalAuditCheck);
|
}
|
return CommonResult.success();
|
}
|
|
@Override
|
public CommonResult updateCarry(InternalAuditCarry carry) {
|
carry.setUpdateBy(SecurityUtils.getUsername());
|
carry.setUpdateTime(LocalDateTime.now());
|
carryMapper.updateById(carry);
|
List<InternalAuditCarryDept> deptList = carry.getDeptList();
|
for (InternalAuditCarryDept internalAuditCarryDept : deptList) {
|
internalAuditCarryDept.setCarryId(carry.getId());
|
}
|
Integer i = carryMapper.deletedCarryDeptByCarryId(carry.getId());
|
carryMapper.insertCarryDept(deptList);
|
|
updateInternalAuditCheck(carry);
|
return CommonResult.success();
|
}
|
|
private CommonResult updateInternalAuditCheck(InternalAuditCarry carry) {
|
// 2. 空指针防护:避免deptList为null导致循环NPE
|
List<InternalAuditCarryDept> deptList = carry.getDeptList();
|
if (CollectionUtils.isEmpty(deptList)) {
|
log.warn("保存/更新内部审计检查:部门列表为空,companyId={}, year={}");
|
return CommonResult.success();
|
}
|
|
for (InternalAuditCarryDept internalAuditCarryDept : deptList) {
|
// 3. 跳过空的部门项,避免后续NPE
|
if (internalAuditCarryDept == null) {
|
log.warn("保存/更新内部审计检查:部门项为null,跳过");
|
continue;
|
}
|
|
InternalAuditCheck internalAuditCheck = new InternalAuditCheck();
|
// 基础字段赋值(保留原逻辑不变)
|
internalAuditCheck.setCompanyId(carry.getCompanyId());
|
internalAuditCheck.setYear(carry.getYear());
|
internalAuditCheck.setDeptId(internalAuditCarryDept.getDeptId());
|
internalAuditCheck.setPersonId(internalAuditCarryDept.getCheckId());
|
internalAuditCheck.setCheckTime(internalAuditCarryDept.getDate());
|
|
// 4. 时间字段安全赋值:避免date/startTime/endTime为null导致atTime()报错
|
LocalDate checkDate = internalAuditCarryDept.getDate();
|
LocalTime startTime = internalAuditCarryDept.getStartTime();
|
LocalTime endTime = internalAuditCarryDept.getEndTime();
|
if (checkDate != null && startTime != null) {
|
internalAuditCheck.setStartTime(checkDate.atTime(startTime));
|
} else {
|
log.warn("保存/更新内部审计检查:开始时间构造失败(日期/时段为空),deptId={}");
|
}
|
if (checkDate != null && endTime != null) {
|
internalAuditCheck.setEndTime(checkDate.atTime(endTime));
|
} else {
|
log.warn("保存/更新内部审计检查:结束时间构造失败(日期/时段为空),deptId={}");
|
}
|
|
// 5. 部门ID转换安全处理:避免非数字字符串导致NumberFormatException
|
Integer deptIdStr = internalAuditCarryDept.getDeptId();
|
|
Long deptId;
|
try {
|
deptId = Long.valueOf(deptIdStr);
|
} catch (NumberFormatException e) {
|
continue;
|
}
|
|
// 6. 查询部门详情空防护:避免deptDetialVo为null导致后续NPE
|
DeptDetialVo deptDetialVo = sysDeptService.selectDeptById(deptId);
|
if (deptDetialVo == null) {
|
log.warn("保存/更新内部审计检查:未查询到部门详情,deptId={}");
|
continue;
|
}
|
List<SysDeptResponsibility> sysDeptResponsibilitys = deptDetialVo.getSysDeptResponsibilitys();
|
|
List<InternalAuditCheckCatalogue> internalAuditCheckCatalogues = new ArrayList<>();
|
|
// 7. 构建查询条件(保留原逻辑,仅优化日志)
|
Map<String, Object> queryMap = new HashMap<>();
|
queryMap.put("dept_id", internalAuditCheck.getDeptId());
|
queryMap.put("year", internalAuditCheck.getYear());
|
queryMap.put("company_id", internalAuditCheck.getCompanyId());
|
queryMap.put("del_flag", 0);
|
List<InternalAuditCheck> internalAuditChecks = internalAuditCheckService.selectByMap(queryMap);
|
log.debug("保存/更新内部审计检查:查询已有记录,条件={},查询结果数={}");
|
|
|
|
// 9. 循环构建新检查项(增加多层空防护)
|
if (!CollectionUtils.isEmpty(sysDeptResponsibilitys)) {
|
for (SysDeptResponsibility sysDeptResponsibility : sysDeptResponsibilitys) {
|
if (sysDeptResponsibility == null) {
|
log.warn("保存/更新内部审计检查:部门责任项为null,跳过");
|
continue;
|
}
|
|
// 防护:clauseId为空跳过,避免Math.toIntExact()报错
|
Long clauseId = sysDeptResponsibility.getClauseId();
|
if (clauseId == null) {
|
log.warn("保存/更新内部审计检查:条款ID为空,跳过该责任项");
|
continue;
|
}
|
|
InternalAuditCheckCatalogue catalogue = new InternalAuditCheckCatalogue();
|
catalogue.setCatalogueId(Math.toIntExact(clauseId));
|
|
// 防护:条款查询为空跳过,避免getPoints()报错
|
SysClauseManagement clauseManagement = sysClauseManagementMapper.selectById(clauseId);
|
if (clauseManagement == null) {
|
continue;
|
}
|
|
// 构建检查内容(保留原逻辑)
|
List<InternalAuditCheckContent> checkContents = new ArrayList<>();
|
InternalAuditCheckContent content = new InternalAuditCheckContent();
|
content.setPointKey(clauseManagement.getPoints());
|
checkContents.add(content);
|
catalogue.setCheckContents(checkContents);
|
|
internalAuditCheckCatalogues.add(catalogue);
|
}
|
} else {
|
log.debug("保存/更新内部审计检查:部门无责任项,deptId={}");
|
}
|
|
// 8. 批量加载详情 + 合并已有检查项(关键防护:避免internalAuditChecks为空导致get(0)索引越界)
|
if (!CollectionUtils.isEmpty(internalAuditChecks)) {
|
batchLoadCheckDetails(internalAuditChecks);
|
InternalAuditCheck firstCheck = internalAuditChecks.get(0);
|
List<InternalAuditCheckCatalogue> existingCatalogues = firstCheck.getCheckCatalogues();
|
|
// 仅当旧数据非空、且新数据已存在时,才筛选合并旧数据
|
if (!CollectionUtils.isEmpty(existingCatalogues) && !internalAuditCheckCatalogues.isEmpty()) {
|
// 提取新数据的所有catalogue_id(用Set实现O(1)快速匹配)
|
Set<Integer> newCatalogueIds = internalAuditCheckCatalogues.stream()
|
.map(InternalAuditCheckCatalogue::getCatalogueId)
|
.collect(Collectors.toSet());
|
|
// 筛选旧数据:仅保留与新数据catalogue_id匹配的记录(避免无用旧数据)
|
List<InternalAuditCheckCatalogue> matchedOldCatalogues = existingCatalogues.stream()
|
.filter(oldCata -> newCatalogueIds.contains(oldCata.getCatalogueId()))
|
.collect(Collectors.toList());
|
|
// 合并筛选后的旧数据(新数据已在列表中,旧数据仅加匹配项)
|
internalAuditCheckCatalogues.addAll(matchedOldCatalogues);
|
} else if (CollectionUtils.isEmpty(internalAuditCheckCatalogues)) {
|
log.warn("保存/更新内部审计检查:无新构建的检查项,不合并旧数据,deptId={}, year={}");
|
} else {
|
log.warn("保存/更新内部审计检查:已有记录无检查项,deptId={}, year={}");
|
}
|
}
|
|
// 去重优化:按catalogue_id可靠去重(核心修改:替代distinct(),避免依赖equals/hashCode)
|
List<InternalAuditCheckCatalogue> uniqueCatalogues = internalAuditCheckCatalogues.stream()
|
.collect(Collectors.toMap(
|
InternalAuditCheckCatalogue::getCatalogueId, // 唯一键:catalogue_id(确保去重逻辑)
|
Function.identity(), // 值:检查项对象
|
(oldVal, newVal) -> newVal // 冲突策略:保留新数据(如需保留旧数据,改为oldVal)
|
))
|
.values()
|
.stream()
|
.collect(Collectors.toList());
|
|
// 最终设置(新数据全部保留,旧数据仅保留匹配项)
|
internalAuditCheck.setCheckCatalogues(uniqueCatalogues);
|
internalAuditCheck.setCheckCatalogues(uniqueCatalogues);
|
|
// 新增/更新判断(保留原逻辑,增加日志)
|
if (CollectionUtils.isEmpty(internalAuditChecks)) {
|
|
internalAuditCheckService.insertInternalAuditCheck(internalAuditCheck);
|
} else {
|
InternalAuditCheck existingCheck = internalAuditChecks.get(0);
|
internalAuditCheck.setId(existingCheck.getId());
|
internalAuditCheckService.updateByYearAndDeptId(internalAuditCheck);
|
}
|
}
|
|
return CommonResult.success();
|
}
|
|
|
|
private void batchLoadCheckDetails(List<InternalAuditCheck> checks) {
|
//收集所有检查ID
|
List<Integer> checkIds = checks.stream()
|
.map(InternalAuditCheck::getId)
|
.collect(Collectors.toList());
|
|
//批量查询所有目录
|
List<InternalAuditCheckCatalogue> allCatalogues = checkCatalogueMapper.selectByCheckIds(checkIds);
|
|
if (CollectionUtils.isEmpty(allCatalogues)) {
|
return;
|
}
|
|
//收集所有目录ID
|
List<Integer> catalogueIds = allCatalogues.stream()
|
.map(InternalAuditCheckCatalogue::getId)
|
.collect(Collectors.toList());
|
|
//批量查询所有内容
|
List<InternalAuditCheckContent> allContents = checkContentMapper.selectByCatalogueIds(catalogueIds);
|
|
//按目录ID分组内容
|
Map<Integer, List<InternalAuditCheckContent>> contentMap = allContents.stream()
|
.collect(Collectors.groupingBy(InternalAuditCheckContent::getCheckCatalogueId));
|
|
//按检查ID分组目录
|
Map<Integer, List<InternalAuditCheckCatalogue>> catalogueMap = allCatalogues.stream()
|
.collect(Collectors.groupingBy(InternalAuditCheckCatalogue::getCheckId));
|
|
//组装数据
|
for (InternalAuditCheck check : checks) {
|
List<InternalAuditCheckCatalogue> catalogues = catalogueMap.get(check.getId());
|
if (!CollectionUtils.isEmpty(catalogues)) {
|
for (InternalAuditCheckCatalogue catalogue : catalogues) {
|
List<InternalAuditCheckContent> contents = contentMap.get(catalogue.getId());
|
catalogue.setCheckContents(contents != null ? contents : new ArrayList<>());
|
}
|
check.setCheckCatalogues(catalogues);
|
}
|
}
|
}
|
|
|
@Override
|
public CommonResult deletedCarry(Integer carryId) {
|
InternalAuditCarry internalAuditCarry = new InternalAuditCarry();
|
internalAuditCarry.setId(carryId);
|
internalAuditCarry.setDelFlag(2);
|
internalAuditCarry.setUpdateBy(SecurityUtils.getUsername());
|
internalAuditCarry.setUpdateTime(LocalDateTime.now());
|
carryMapper.updateById(internalAuditCarry);
|
return CommonResult.success();
|
}
|
}
|