2026-01-04 14:45:09 +08:00
|
|
|
|
package com.gunshi.project.ss.service;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
2026-01-13 10:53:04 +08:00
|
|
|
|
import com.gunshi.db.dto.DateTimeRangeSo;
|
|
|
|
|
|
import com.gunshi.project.ss.common.util.LocalDateTimeConverter;
|
2026-01-04 14:45:09 +08:00
|
|
|
|
import com.gunshi.project.ss.entity.so.DocCenterPageSo;
|
|
|
|
|
|
import com.gunshi.project.ss.mapper.DocCenterMapper;
|
|
|
|
|
|
import com.gunshi.project.ss.model.DocCategory;
|
|
|
|
|
|
import com.gunshi.project.ss.model.DocCenter;
|
2026-01-13 10:53:04 +08:00
|
|
|
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
2026-01-04 14:45:09 +08:00
|
|
|
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
|
|
|
|
|
import com.ruoyi.common.utils.StringUtils;
|
2026-01-13 10:53:04 +08:00
|
|
|
|
import com.ruoyi.system.mapper.SysDeptMapper;
|
2026-01-04 14:45:09 +08:00
|
|
|
|
import com.ruoyi.system.mapper.SysUserMapper;
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
2026-01-13 10:53:04 +08:00
|
|
|
|
import java.util.*;
|
|
|
|
|
|
import java.util.stream.Collectors;
|
2026-01-04 14:45:09 +08:00
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
|
public class DocCenterService extends ServiceImpl<DocCenterMapper, DocCenter> {
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private DocCategoryService docCategoryService;
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private SysUserMapper sysUserMapper;
|
|
|
|
|
|
|
2026-01-13 10:53:04 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private SysDeptMapper sysDeptMapper;
|
|
|
|
|
|
|
2026-01-12 13:57:31 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private DocOperateLogService docOperateLogService;
|
|
|
|
|
|
|
2026-01-04 14:45:09 +08:00
|
|
|
|
public Page<DocCenter> pageInfo(DocCenterPageSo pageSo){
|
|
|
|
|
|
LambdaQueryWrapper<DocCenter> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
|
queryWrapper.eq(DocCenter::getDocCategoryId,pageSo.getDocCategoryId());
|
|
|
|
|
|
if(StringUtils.isNotEmpty(pageSo.getDocName())){
|
|
|
|
|
|
queryWrapper.like(DocCenter::getDocName,pageSo.getDocName());
|
|
|
|
|
|
}
|
|
|
|
|
|
if(pageSo.getSecretLevel() != null){
|
|
|
|
|
|
queryWrapper.eq(DocCenter::getSecretLevel,pageSo.getSecretLevel());
|
|
|
|
|
|
}
|
|
|
|
|
|
queryWrapper.orderByDesc(DocCenter::getCreateTime);
|
|
|
|
|
|
Page<DocCenter> docCenterPage = this.baseMapper.selectPage(pageSo.getPageSo().toPage(), queryWrapper);
|
|
|
|
|
|
for (DocCenter record : docCenterPage.getRecords()) {
|
|
|
|
|
|
if(record.getUserId() != null){
|
|
|
|
|
|
SysUser sysUser = sysUserMapper.selectUserById(record.getUserId());
|
|
|
|
|
|
if(sysUser != null){
|
|
|
|
|
|
record.setUserName(sysUser.getNickName());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
List<DocCategory> categoryPathRecursive = docCategoryService.findCategoryPathRecursive(record.getDocCategoryId());
|
|
|
|
|
|
List<String> categoryCodes = new ArrayList<>();
|
|
|
|
|
|
for (DocCategory docCategory : categoryPathRecursive) {
|
|
|
|
|
|
categoryCodes.add(docCategory.getCategoryCode());
|
|
|
|
|
|
}
|
|
|
|
|
|
categoryCodes.add(record.getDocNumber());
|
|
|
|
|
|
record.setCategoryCodes(categoryCodes);
|
|
|
|
|
|
}
|
|
|
|
|
|
return docCenterPage;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public boolean saveData(DocCenter docCenter) {
|
|
|
|
|
|
if(StringUtils.isBlank(docCenter.getBusinessName())){
|
|
|
|
|
|
throw new IllegalArgumentException("请传业务名称");
|
|
|
|
|
|
}
|
|
|
|
|
|
Long count = lambdaQuery().eq(DocCenter::getDocCategoryId, docCenter.getDocCategoryId()).count();
|
|
|
|
|
|
count++;
|
|
|
|
|
|
// 将 count 转换为字符串,前面补0,保持至少4位数字
|
|
|
|
|
|
String countStr = String.format("%04d", count);
|
|
|
|
|
|
docCenter.setDocNumber(countStr);
|
|
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
|
docCenter.setCreateTime(now);
|
|
|
|
|
|
if(docCenter.getReplaceId() != null){
|
|
|
|
|
|
//如果替换档案ID不为null,废弃原档案
|
|
|
|
|
|
DocCenter one = lambdaQuery().eq(DocCenter::getId, docCenter.getReplaceId()).one();
|
|
|
|
|
|
if(one == null){
|
|
|
|
|
|
throw new IllegalArgumentException("对不起,被替换的档案ID不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
//获取同一组有多少个版本
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery().eq(DocCenter::getGroupId, one.getGroupId())
|
|
|
|
|
|
.orderByDesc(DocCenter::getDocVersion)
|
|
|
|
|
|
.list();
|
|
|
|
|
|
//设置分组id
|
|
|
|
|
|
docCenter.setGroupId(one.getGroupId());
|
|
|
|
|
|
docCenter.setDocVersion(new BigDecimal(list.size()).add(BigDecimal.ONE));
|
|
|
|
|
|
//设置状态为已废除
|
|
|
|
|
|
one.setIsAbolish(1);
|
|
|
|
|
|
//设置废止时间(为替换档案的新增时间)
|
|
|
|
|
|
one.setAbolishTime(now);
|
|
|
|
|
|
updateById(one);
|
|
|
|
|
|
}else{
|
|
|
|
|
|
docCenter.setGroupId(IdWorker.getId());
|
|
|
|
|
|
docCenter.setDocVersion(BigDecimal.ONE);
|
|
|
|
|
|
docCenter.setIsAbolish(0);
|
|
|
|
|
|
docCenter.setAbolishTime(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
boolean save = this.save(docCenter);
|
2026-01-12 13:57:31 +08:00
|
|
|
|
docOperateLogService.saveLog(docCenter,1);
|
2026-01-04 14:45:09 +08:00
|
|
|
|
return save;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public DocCenter deleteById(Integer id) {
|
|
|
|
|
|
DocCenter center = this.baseMapper.selectById(id);
|
|
|
|
|
|
if(center == null) return null;
|
|
|
|
|
|
//根据组id查询版本号比他大的数据,然后这些数据的版本全部降1
|
|
|
|
|
|
List<DocCenter> versionGe = lambdaQuery().eq(DocCenter::getGroupId, center.getGroupId())
|
|
|
|
|
|
.ge(DocCenter::getDocVersion,center.getDocVersion().add(BigDecimal.ONE))
|
|
|
|
|
|
.orderByAsc(DocCenter::getDocVersion)
|
|
|
|
|
|
.list();
|
|
|
|
|
|
for (DocCenter docCenter : versionGe) {
|
|
|
|
|
|
docCenter.setDocVersion( docCenter.getDocVersion().subtract(BigDecimal.ONE) );
|
|
|
|
|
|
}
|
|
|
|
|
|
//如果删除的版本为第一版
|
|
|
|
|
|
if(center.getDocVersion().compareTo(BigDecimal.ONE) == 0 && versionGe.size() > 0){
|
|
|
|
|
|
//那么第二版的替换版本设置为空
|
|
|
|
|
|
DocCenter second = versionGe.get(0);
|
|
|
|
|
|
second.setReplaceId(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
//查询版本比它小的数据
|
|
|
|
|
|
List<DocCenter> versionLe = lambdaQuery().eq(DocCenter::getGroupId, center.getGroupId())
|
|
|
|
|
|
.le(DocCenter::getDocVersion, center.getDocVersion().subtract(BigDecimal.ONE))
|
|
|
|
|
|
.orderByDesc(DocCenter::getDocVersion).list();
|
|
|
|
|
|
//如果是中间版本
|
|
|
|
|
|
if(versionLe.size() > 0 && versionGe.size() > 0){
|
|
|
|
|
|
//第一个必它大的版本
|
|
|
|
|
|
DocCenter versionBig1 = versionGe.get(0);
|
|
|
|
|
|
//第一个比它小的版本
|
|
|
|
|
|
DocCenter versionSmall1 = versionLe.get(0);
|
|
|
|
|
|
versionBig1.setReplaceId(versionSmall1.getId());
|
|
|
|
|
|
} else if(versionLe.size() > 0){
|
|
|
|
|
|
//如果删除的是最新的版本的数据
|
|
|
|
|
|
DocCenter versionSmall1 = versionLe.get(0);
|
|
|
|
|
|
versionSmall1.setIsAbolish(0);
|
|
|
|
|
|
versionSmall1.setAbolishTime(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
removeById(id);
|
|
|
|
|
|
if(versionGe.size() > 0){
|
|
|
|
|
|
updateBatchById(versionGe);
|
|
|
|
|
|
}
|
|
|
|
|
|
if(versionLe.size() > 0){
|
|
|
|
|
|
updateBatchById(versionLe);
|
|
|
|
|
|
}
|
2026-01-12 13:57:31 +08:00
|
|
|
|
docOperateLogService.saveLog(center,3);
|
2026-01-04 14:45:09 +08:00
|
|
|
|
return center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public boolean updateData(DocCenter docCenter) {
|
|
|
|
|
|
DocCenter one = lambdaQuery().eq(DocCenter::getId, docCenter.getId()).one();
|
|
|
|
|
|
if(one == null){
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
//获取替换id
|
|
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
|
if(docCenter.getReplaceId() != null){
|
|
|
|
|
|
//如果替换档案ID不为null,废弃原档案
|
|
|
|
|
|
DocCenter replaceOne = lambdaQuery().eq(DocCenter::getId, docCenter.getReplaceId()).one();
|
|
|
|
|
|
if(replaceOne == null){
|
|
|
|
|
|
throw new IllegalArgumentException("对不起,被替换的档案ID不存在");
|
|
|
|
|
|
}
|
|
|
|
|
|
//获取同一组有多少个版本
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery().eq(DocCenter::getGroupId, replaceOne.getGroupId())
|
|
|
|
|
|
.orderByDesc(DocCenter::getDocVersion)
|
|
|
|
|
|
.list();
|
|
|
|
|
|
//设置分组id
|
|
|
|
|
|
docCenter.setGroupId(replaceOne.getGroupId());
|
|
|
|
|
|
docCenter.setDocVersion(new BigDecimal(list.size()).add(BigDecimal.ONE));
|
|
|
|
|
|
//设置状态为已废除
|
|
|
|
|
|
replaceOne.setIsAbolish(1);
|
|
|
|
|
|
//设置废止时间(为替换档案的新增时间)
|
|
|
|
|
|
replaceOne.setAbolishTime(now);
|
|
|
|
|
|
updateById(replaceOne);
|
|
|
|
|
|
}
|
|
|
|
|
|
boolean flag = updateById(docCenter);
|
2026-01-12 13:57:31 +08:00
|
|
|
|
docOperateLogService.saveLog(docCenter,2);
|
2026-01-04 14:45:09 +08:00
|
|
|
|
return flag;
|
|
|
|
|
|
}
|
2026-01-13 10:53:04 +08:00
|
|
|
|
|
|
|
|
|
|
public Map<String, Long> groupByType(DateTimeRangeSo dateTimeRangeSo) {
|
|
|
|
|
|
Map<String, Long> res = new HashMap<>();
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery()
|
|
|
|
|
|
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
|
|
|
|
|
|
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd()).list();
|
|
|
|
|
|
|
|
|
|
|
|
//获取去重的所有资料分类ID
|
|
|
|
|
|
List<Long> categoryIds = list.stream().distinct().map(o -> {
|
|
|
|
|
|
return o.getDocCategoryId();
|
|
|
|
|
|
}).collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
|
|
List<DocCategory> level3Category = docCategoryService.lambdaQuery().in(DocCategory::getId, categoryIds).list();
|
|
|
|
|
|
|
|
|
|
|
|
for (DocCategory docCategory : level3Category) {
|
|
|
|
|
|
long count = list.stream().filter(o -> {
|
|
|
|
|
|
return docCategory.getId().equals(o.getDocCategoryId());
|
|
|
|
|
|
}).count();
|
|
|
|
|
|
res.put(docCategory.getCategoryName(),count);
|
|
|
|
|
|
}
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, Long> groupByDept(DateTimeRangeSo dateTimeRangeSo) {
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery()
|
|
|
|
|
|
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
|
|
|
|
|
|
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd()).list();
|
|
|
|
|
|
// 按用户ID分组,再转换到部门
|
|
|
|
|
|
return list.stream()
|
|
|
|
|
|
.filter(doc -> doc.getUserId() != null)
|
|
|
|
|
|
.collect(Collectors.groupingBy(
|
|
|
|
|
|
DocCenter::getUserId, // 先按用户分组
|
|
|
|
|
|
Collectors.counting() // 统计每个用户的文档数
|
|
|
|
|
|
))
|
|
|
|
|
|
.entrySet().stream()
|
|
|
|
|
|
.collect(Collectors.toMap(
|
|
|
|
|
|
entry -> {
|
|
|
|
|
|
// 根据用户ID获取部门名称
|
|
|
|
|
|
Long userId = entry.getKey();
|
|
|
|
|
|
Long userDocCount = entry.getValue();
|
|
|
|
|
|
|
|
|
|
|
|
SysUser user = sysUserMapper.selectUserById(userId);
|
|
|
|
|
|
if (user == null || user.getDeptId() == null) {
|
|
|
|
|
|
return "未知部门";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SysDept dept = sysDeptMapper.selectDeptById(user.getDeptId());
|
|
|
|
|
|
return dept != null ? dept.getDeptName() : "未知部门";
|
|
|
|
|
|
},
|
|
|
|
|
|
Map.Entry::getValue, // 文档数量
|
|
|
|
|
|
Long::sum // 相同部门合并
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, Long> groupBySecret(DateTimeRangeSo dateTimeRangeSo) {
|
|
|
|
|
|
Map<String, Long> res = new HashMap<>();
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery()
|
|
|
|
|
|
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
|
|
|
|
|
|
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd()).list();
|
|
|
|
|
|
|
|
|
|
|
|
List<Integer> secretLevel = list.stream().distinct().map(o -> {
|
|
|
|
|
|
return o.getSecretLevel();
|
|
|
|
|
|
}).collect(Collectors.toList());
|
|
|
|
|
|
for (Integer level : secretLevel) {
|
|
|
|
|
|
long count = list.stream().filter(o -> o.getSecretLevel().equals(level)).count();
|
|
|
|
|
|
if(level == 0){
|
|
|
|
|
|
res.put("公开",count);
|
|
|
|
|
|
}else if(level == 1){
|
|
|
|
|
|
res.put("秘密",count);
|
|
|
|
|
|
}else if(level == 2){
|
|
|
|
|
|
res.put("机密",count);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, Long> groupByVersion(DateTimeRangeSo dateTimeRangeSo) {
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery()
|
|
|
|
|
|
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
|
|
|
|
|
|
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd())
|
|
|
|
|
|
.list();
|
|
|
|
|
|
|
|
|
|
|
|
return list.stream()
|
|
|
|
|
|
.filter(doc -> doc.getDocVersion() != null) // 过滤null值
|
|
|
|
|
|
.collect(Collectors.groupingBy(
|
|
|
|
|
|
doc -> doc.getDocVersion().toString(), // 转为String作为key
|
|
|
|
|
|
Collectors.counting()
|
|
|
|
|
|
));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Map<String, Long> groupByTm(DateTimeRangeSo dateTimeRangeSo) {
|
|
|
|
|
|
// 1. 查询数据
|
|
|
|
|
|
List<DocCenter> list = lambdaQuery()
|
|
|
|
|
|
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
|
|
|
|
|
|
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd())
|
|
|
|
|
|
.list();
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 按年月分组统计
|
|
|
|
|
|
Map<String, Long> grouped = list.stream()
|
|
|
|
|
|
.collect(Collectors.groupingBy(
|
|
|
|
|
|
doc -> {
|
|
|
|
|
|
LocalDateTime createTime = doc.getCreateTime();
|
|
|
|
|
|
// 格式化为年月:2025-11
|
|
|
|
|
|
return String.format("%d-%02d",
|
|
|
|
|
|
createTime.getYear(),
|
|
|
|
|
|
createTime.getMonthValue());
|
|
|
|
|
|
},
|
|
|
|
|
|
Collectors.counting()
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 补全缺失的月份
|
|
|
|
|
|
return fillMissingMonths(grouped, dateTimeRangeSo.getStart(),dateTimeRangeSo.getEnd());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 补全缺失月份的方法
|
|
|
|
|
|
*/
|
|
|
|
|
|
private Map<String, Long> fillMissingMonths(Map<String, Long> grouped, Date startDate, Date endDate) {
|
|
|
|
|
|
Map<String, Long> result = new LinkedHashMap<>(); // 保持插入顺序
|
|
|
|
|
|
|
|
|
|
|
|
// 将Date转换为LocalDateTime
|
|
|
|
|
|
LocalDateTime start = LocalDateTimeConverter.fromDate(startDate);
|
|
|
|
|
|
LocalDateTime end = LocalDateTimeConverter.fromDate(endDate);
|
|
|
|
|
|
|
|
|
|
|
|
// 调整到每月的第一天
|
|
|
|
|
|
LocalDateTime current = start.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
|
|
|
LocalDateTime lastMonth = end.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历每个月份
|
|
|
|
|
|
while (!current.isAfter(lastMonth)) {
|
|
|
|
|
|
String monthKey = String.format("%d-%02d",
|
|
|
|
|
|
current.getYear(),
|
|
|
|
|
|
current.getMonthValue());
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有数据则取数据,否则为0
|
|
|
|
|
|
result.put(monthKey, grouped.getOrDefault(monthKey, 0L));
|
|
|
|
|
|
|
|
|
|
|
|
// 下一个月
|
|
|
|
|
|
current = current.plusMonths(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
2026-01-04 14:45:09 +08:00
|
|
|
|
}
|