package com.ruoyi.system.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ruoyi.common.NumberDisplaceChineseUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.ReportingStatusEnum;
import com.ruoyi.common.enums.ShowStatusEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.BeanUtils;
import com.ruoyi.common.utils.CollUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.TbBasicData;
import com.ruoyi.system.domain.TbBasicDataField;
import com.ruoyi.system.domain.TbDept;
import com.ruoyi.system.domain.TbField;
import com.ruoyi.system.dto.BasicDataDTO;
import com.ruoyi.system.listener.BasicDataListener;
import com.ruoyi.system.mapper.TbBasicDataMapper;
import com.ruoyi.system.service.TbBasicDataFieldService;
import com.ruoyi.system.service.TbBasicDataService;
import com.ruoyi.system.service.TbDeptService;
import com.ruoyi.system.service.TbFieldService;
import com.ruoyi.system.vo.BasicDataReportingVO;
import com.ruoyi.system.vo.FieldReportingVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* 基础数据表 服务实现类
*
*
* @author mitao
* @since 2024-03-13
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class TbBasicDataServiceImpl extends ServiceImpl implements TbBasicDataService {
private final TbDeptService tbDeptService;
private final HttpServletResponse response;
private final TbFieldService tbFieldService;
private final TbBasicDataFieldService tbBasicDataFieldService;
@Override
public R getBasicFields(String deptAreaCode) throws Exception {
BasicDataReportingVO vo = new BasicDataReportingVO();
//校验区划代码
TbDept dept = tbDeptService.getOne(Wrappers.lambdaQuery().eq(TbDept::getAreaCode, deptAreaCode));
if (Objects.isNull(dept)) {
throw new ServiceException(String.format("区划代码%s不存在", deptAreaCode));
}
Date date = new Date();
//当前所在季度
int quarterOfYear = DateUtils.getQuarterOfYear(date);
String quarterOfYearStr = NumberDisplaceChineseUtil.numberToChinese(quarterOfYear);
Map quarterDate = DateUtils.getQuarterDate(date);
//当前季度开始
Date quarterStart = quarterDate.get("first");
//当前季度结束
Date quarterEnd = quarterDate.get("last");
//判断当前时间是否在季度初1-15号
Instant instant = quarterStart.toInstant();
LocalDate quarterStartLocalDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate fifteenDaysLimit = quarterStartLocalDate.plusDays(15);
LocalDate now = LocalDate.now();
vo.setQuarter(String.format("%s年%s季度",now.getYear(),quarterOfYearStr));
vo.setStatus(ReportingStatusEnum.UNFILLED);
//如果当前时间不在规定范围内:季度初1-15号
if (now.isBefore(quarterStartLocalDate) || now.isAfter(fifteenDaysLimit)) {
return R.ok(vo,"请于季度初1-15号上传季度数据。");
}
//查询是否有当前季度的填报记录
TbBasicData basicData = this.getOne(Wrappers.lambdaQuery()
.eq(TbBasicData::getDeptAreaCode, dept.getAreaCode())
.between(TbBasicData::getCreateTime, quarterStart,quarterEnd));
//查询需要填写的字段
List list = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
if (CollUtils.isNotEmpty(list)) {
List fieldReportingVOS = BeanUtils.copyList(list, FieldReportingVO.class);
vo.setFields(fieldReportingVOS);
}
if (Objects.isNull(basicData)) {
vo.setQuarter(String.format("%s年%s季度",now.getYear(),quarterOfYearStr));
vo.setStatus(ReportingStatusEnum.UNFILLED);
return R.ok(vo);
}else {
vo.setStatus(basicData.getStatus());
//查询已填报数据 包含数据缺失和已填报
List basicDataFields = tbBasicDataFieldService.lambdaQuery()
.eq(TbBasicDataField::getBasicDataId, basicData.getId()).list();
if (CollUtils.isNotEmpty(basicDataFields)) {
Map fieldMap = basicDataFields.stream()
.collect(Collectors.toMap(TbBasicDataField::getFieldId, Function.identity()));
vo.getFields().forEach(item -> {
TbBasicDataField tbBasicDataField = fieldMap.get(item.getId());
if (Objects.nonNull(tbBasicDataField)) {
item.setValue(tbBasicDataField.getFieldValue());
}
});
return R.ok(vo);
}
}
return R.ok(vo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveBasicData(BasicDataDTO dto) {
//TODO
//LoginUser loginUser = SecurityUtils.getLoginUser();
//数据校验
if (Objects.isNull(dto) || CollUtils.isEmpty(dto.getFields())) {
return;
}
TbBasicData tbBasicData = BeanUtils.copyBean(dto, TbBasicData.class);
this.saveOrUpdate(tbBasicData);
//保存基础数据动态字段数据
List tbBasicDataFields = BeanUtils.copyList(dto.getFields(), TbBasicDataField.class);
tbBasicDataFields.forEach(item -> item.setBasicDataId(tbBasicData.getId()));
//将该基础数据的动态字段数据全部删除
tbBasicDataFieldService.remove(null);
tbBasicDataFieldService.saveBatch(tbBasicDataFields);
}
@Override
public void downloadImportTemplate() throws Exception {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = "地方财政运行及“三保”情况统计表";
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
//查询需要填写的动态字段
List list = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
// 这里需要设置不关闭流
EasyExcel.write(response.getOutputStream()).head(head(list))
.autoCloseStream(Boolean.FALSE).sheet("模板")
.doWrite(dataList(list));
}
private List> dataList(List list) throws Exception {
//TODO
//LoginUser loginUser = SecurityUtils.getLoginUser();
TbDept dept = tbDeptService.getById(44);
//当前所在季度
int quarterOfYear = DateUtils.getQuarterOfYear(new Date());
String quarterOfYearStr = NumberDisplaceChineseUtil.numberToChinese(quarterOfYear);
List> excellist = new ArrayList>();
List> head = head(list);
List