mitao
2024-03-27 789b5b823440d174a198a35fd033ca975cb54f4a
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TbBasicDataServiceImpl.java
@@ -1,10 +1,42 @@
package com.ruoyi.system.service.impl;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.domain.TbBasicData;
import com.google.common.collect.Lists;
import com.ruoyi.common.basic.PageDTO;
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.common.utils.NumberDisplaceChineseUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.dto.BasicDataDTO;
import com.ruoyi.system.listener.BasicDataListener;
import com.ruoyi.system.mapper.TbBasicDataMapper;
import com.ruoyi.system.service.TbBasicDataService;
import com.ruoyi.system.query.ScoreQuery;
import com.ruoyi.system.service.*;
import com.ruoyi.system.vo.BasicDataReportingVO;
import com.ruoyi.system.vo.FieldReportingVO;
import com.ruoyi.system.vo.ScoreVO;
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.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;
/**
 * <p>
@@ -14,7 +46,181 @@
 * @author mitao
 * @since 2024-03-13
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TbBasicDataServiceImpl extends ServiceImpl<TbBasicDataMapper, TbBasicData> implements TbBasicDataService {
    private final TbDeptService tbDeptService;
    private final HttpServletResponse response;
    private final TbFieldService tbFieldService;
    private final TbBasicDataFieldService tbBasicDataFieldService;
    private final TbBasicDataConfigService tbBasicDataConfigService;
    private final TbBasicDataConfigDetailService tbBasicDataConfigDetailService;
    private final TbScoreService scoreService;
    @Override
    public R<BasicDataReportingVO> getBasicFields(String deptAreaCode) throws Exception {
        BasicDataReportingVO vo = new BasicDataReportingVO();
        //校验区划代码
        TbDept dept = tbDeptService.getOne(Wrappers.<TbDept>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<String, Date> 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.<TbBasicData>lambdaQuery()
                .eq(TbBasicData::getDeptAreaCode, dept.getAreaCode())
                .between(TbBasicData::getCreateTime, quarterStart,quarterEnd));
        //查询需要填写的字段
        List<TbField> list = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
        if (CollUtils.isNotEmpty(list)) {
            List<FieldReportingVO> 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<TbBasicDataField> basicDataFields = tbBasicDataFieldService.lambdaQuery()
                    .eq(TbBasicDataField::getBasicDataId, basicData.getId()).list();
            if (CollUtils.isNotEmpty(basicDataFields)) {
                Map<Integer, TbBasicDataField> 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<TbBasicDataField> 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<TbField> 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<List<Object>> dataList(List<TbField> 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<List<Object>> excellist = new ArrayList<List<Object>>();
        List<List<String>> head = head(list);
        List<Object> columnNo = Lists.newArrayList("栏号");
        for (int i = 1; i < head.size(); i++) {
            columnNo.add(String.valueOf(i));
        }
        excellist.add(columnNo);
        excellist.add(Lists.newArrayList(dept.getAreaName(), String.format("%s季度",quarterOfYearStr)));
        return excellist;
    }
    private List<List<String>> head(List<TbField> list) {
        List<List<String>> headTitles = Lists.newArrayList();
        //固定字段
        headTitles.add(Lists.newArrayList("地区"));
        headTitles.add(Lists.newArrayList("填报季度"));
        headTitles.add(Lists.newArrayList("转移支付规模"));
        headTitles.add(Lists.newArrayList("当期GDP"));
        list.forEach(item ->{
            headTitles.add(Lists.newArrayList(item.getLevelOneCategory(), item.getLevelTwoCategory(), item.getLevelThreeCategory(), item.getFieldName()));
        });
        headTitles.add(Lists.newArrayList("备注"));
        return headTitles;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importBasicData(MultipartFile file) throws Exception {
        //TODO
        //LoginUser loginUser = SecurityUtils.getLoginUser();
        TbDept dept = tbDeptService.getById(44);
        //查询需要填写的动态字段
        List<TbField> fieldList = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
        EasyExcel.read(file.getInputStream(), new BasicDataListener(this,fieldList,
                tbFieldService,dept,tbBasicDataFieldService,tbBasicDataConfigService,
                tbBasicDataConfigDetailService,scoreService)).sheet().doRead();
    }
    @Override
    public PageDTO<ScoreVO> pageScore(ScoreQuery query) {
        Page<ScoreVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        //todo 获取当前登录部门
        //校验区划代码
        TbDept dept = tbDeptService.getById(44);
        Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date());
        //当前季度开始
        Date quarterStart = quarterDate.get("first");
        //当前季度结束
        Date quarterEnd = quarterDate.get("last");
        //查询是否有当前季度的填报记录
        TbBasicData basicData = this.getOne(Wrappers.<TbBasicData>lambdaQuery()
                .eq(TbBasicData::getDeptAreaCode, dept.getAreaCode())
                .between(TbBasicData::getCreateTime, quarterStart,quarterEnd));
        if (Objects.isNull(basicData)) {
            return PageDTO.empty(page);
        }
        query.setBasicDataId(basicData.getId());
        //查询对应的基础数据配置
        List<ScoreVO> vos = scoreService.pageScore(query,page);
        return PageDTO.of(page, vos);
    }
}