package com.finance.system.service.impl;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finance.common.basic.PageDTO;
import com.finance.common.core.domain.R;
import com.finance.common.core.domain.entity.SysUser;
import com.finance.common.enums.ReportingStatusEnum;
import com.finance.common.enums.UserTypeEnum;
import com.finance.common.exception.ServiceException;
import com.finance.common.utils.BeanUtils;
import com.finance.common.utils.CollUtils;
import com.finance.common.utils.SecurityUtils;
import com.finance.common.utils.StringUtils;
import com.finance.system.domain.TbBasicData;
import com.finance.system.domain.TbDept;
import com.finance.system.dto.update.DeptFocusDTO;
import com.finance.system.handler.DeptVerifyHandler;
import com.finance.system.importExcel.DeptExcel;
import com.finance.system.mapper.TbDeptMapper;
import com.finance.system.query.DeptQuery;
import com.finance.system.service.ISysUserService;
import com.finance.system.service.TbBasicDataService;
import com.finance.system.service.TbDeptService;
import com.finance.system.vo.DeptVO;
import java.io.InputStream;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
/**
*
* 部门管理表 服务实现类
*
*
* @author mitao
* @since 2024-03-13
*/
@Service
@RequiredArgsConstructor
public class TbDeptServiceImpl extends ServiceImpl implements TbDeptService {
private final DeptVerifyHandler deptVerifyHandler;
private final ISysUserService sysUserService;
private final TbBasicDataService tbBasicDataService;
@Override
public PageDTO queryPage(DeptQuery query) {
Page page = new Page<>(query.getPageNum(), query.getPageSize());
Page userPage = sysUserService.lambdaQuery()
.eq(SysUser::getUserType, UserTypeEnum.DEPARTMENT.getCode())
.like(StringUtils.isNotEmpty(query.getAreaName()), SysUser::getAreaName,
query.getAreaName())
.like(StringUtils.isNotEmpty(query.getUserName()), SysUser::getUserName,
query.getUserName())
.like(StringUtils.isNotEmpty(query.getPhone()), SysUser::getPhoneNumber,
query.getPhone())
.orderByDesc(SysUser::getCreateTime)
.page(page);
if (CollUtils.isEmpty(userPage.getRecords())) {
return PageDTO.empty(page);
}
return PageDTO.of(userPage, DeptVO.class);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void importExcel(MultipartFile file) throws Exception {
ImportParams importParams = new ImportParams();
//表格标题行数,默认0
importParams.setTitleRows(1);
//是否需要校验上传的Excel
importParams.setNeedVerify(true);
//使用自定义校验规则
importParams.setVerifyHandler(deptVerifyHandler);
InputStream inputStream = file.getInputStream();
ExcelImportResult result = ExcelImportUtil.importExcelMore(inputStream,
DeptExcel.class, importParams);
inputStream.close();
List list = result.getList();
if (result.isVerifyFail() || CollectionUtils.isEmpty(list)) {
throw new ServiceException("文件校验失败,请检查数据填写是否完整");
}
List strings = hasDuplicateAreaCode(list);
if (!CollectionUtils.isEmpty(strings)) {
throw new ServiceException(
String.format("区划代码%s重复,请修改后重新导入", String.join(",", strings)));
} else {
List tbDeptList = BeanUtils.copyList(list, TbDept.class);
this.remove(null);
tbDeptList.forEach(dept -> {
dept.setPassword(SecurityUtils.encryptPassword(dept.getPassword()));
});
this.saveBatch(tbDeptList);
}
}
/**
* 校验区划代码是否重复
*
* @param deptList 部门列表
* @return 重复的区划代码
*/
public List hasDuplicateAreaCode(List deptList) {
Set areaCodes = new HashSet<>();
List result = new ArrayList<>();
for (DeptExcel dept : deptList) {
if (!areaCodes.add(dept.getAreaCode())) {
result.add(dept.getAreaCode());
}
}
return result;
}
@Override
public void focus(DeptFocusDTO dto) {
Optional sysUser = sysUserService.lambdaQuery()
.eq(SysUser::getUserId, dto.getUserId()).oneOpt();
if (sysUser.isPresent()) {
sysUserService.lambdaUpdate()
.eq(SysUser::getUserId, dto.getUserId())
.set(SysUser::getFocussed, dto.getFocussed())
.update();
}
}
@Override
public R reportingMessage() {
Date date = new Date();
Date quarterStart = DateUtil.beginOfQuarter(date);
Date quarterEnd = DateUtil.endOfQuarter(date);
//判断当前时间是否在季度初1-15号
Instant instant = quarterStart.toInstant();
LocalDate quarterStartLocalDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate fifteenDaysLimit = quarterStartLocalDate.plusDays(14);
LocalDate now = LocalDate.now();
//如果当前时间不在规定范围内:季度初1-15号
if (now.isAfter(quarterStartLocalDate) || now.isBefore(fifteenDaysLimit)) {
//查询所有的部门
List list = sysUserService.lambdaQuery()
.eq(SysUser::getUserType, UserTypeEnum.DEPARTMENT.getCode()).list();
Set deptAreaCodeList = list.stream().map(SysUser::getAreaCode)
.collect(Collectors.toSet());
//查询当前季度填报了数据的部门
List filledBasicData = tbBasicDataService.lambdaQuery()
.between(TbBasicData::getReportingTime, quarterStartLocalDate, fifteenDaysLimit)
.eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED).list();
Set filledDeptCodes = filledBasicData.stream().map(TbBasicData::getDeptAreaCode)
.collect(Collectors.toSet());
if (!filledDeptCodes.containsAll(deptAreaCodeList)) {
return R.fail("有部门未上传季度数据");
}
}
return R.ok();
}
}