package com.finance.system.service.impl; import cn.hutool.core.date.DateUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.fastjson2.JSONArray; 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.finance.common.basic.PageDTO; import com.finance.common.core.domain.R; import com.finance.common.core.domain.entity.SysUser; import com.finance.common.core.domain.model.LoginUser; import com.finance.common.enums.BusinessType; import com.finance.common.enums.CalculateTypeEnum; import com.finance.common.enums.DataScreenConfigEnum; import com.finance.common.enums.FieldInputTypeEnum; import com.finance.common.enums.FieldTypeEnum; import com.finance.common.enums.ReportingStatusEnum; import com.finance.common.enums.ShowStatusEnum; import com.finance.common.enums.UserTypeEnum; import com.finance.common.enums.ValueTypeEnum; import com.finance.common.exception.ServiceException; import com.finance.common.utils.BeanUtils; import com.finance.common.utils.CalculateUtil; import com.finance.common.utils.CollUtils; import com.finance.common.utils.DateUtils; import com.finance.common.utils.EasyExcelUtil; import com.finance.common.utils.SecurityUtils; import com.finance.common.utils.StringUtils; import com.finance.system.domain.TbBasicData; import com.finance.system.domain.TbBasicDataConfig; import com.finance.system.domain.TbBasicDataConfigDetail; import com.finance.system.domain.TbBasicDataField; import com.finance.system.domain.TbDataScreenScore; import com.finance.system.domain.TbField; import com.finance.system.domain.TbOperLog; import com.finance.system.domain.TbScore; import com.finance.system.dto.BasicDataDTO; import com.finance.system.dto.BasicDataFieldDTO; import com.finance.system.dto.CalculateItemDTO; import com.finance.system.dto.update.BasicDataUpdDTO; import com.finance.system.handler.CustomCellWriteHandler; import com.finance.system.listener.BasicDataListener; import com.finance.system.listener.HistoryDataListener; import com.finance.system.mapper.TbBasicDataMapper; import com.finance.system.query.CurrentFieldsQuery; import com.finance.system.query.ScoreCalculateQuery; import com.finance.system.query.ScoreQuery; import com.finance.system.service.ISysUserService; import com.finance.system.service.TbBasicDataConfigDetailService; import com.finance.system.service.TbBasicDataConfigService; import com.finance.system.service.TbBasicDataFieldService; import com.finance.system.service.TbBasicDataService; import com.finance.system.service.TbDataScreenConfigService; import com.finance.system.service.TbDataScreenScoreService; import com.finance.system.service.TbFieldService; import com.finance.system.service.TbOperLogService; import com.finance.system.service.TbScoreService; import com.finance.system.utils.FieldBuildUtil; import com.finance.system.vo.BasicDataReportingVO; import com.finance.system.vo.CurrentFieldsAllVO; import com.finance.system.vo.CurrentFieldsDetailVO; import com.finance.system.vo.CurrentFieldsVO; import com.finance.system.vo.DataScreenConfigVO; import com.finance.system.vo.FieldAndScoreDataVO; import com.finance.system.vo.FieldsTreeVO; import com.finance.system.vo.ScoreCalculateVO; import com.finance.system.vo.ScoreVO; import com.finance.system.vo.TransferPaymentScaleVO; import com.google.common.collect.Lists; import java.io.IOException; import java.net.URLEncoder; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; 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; /** * 基础数据表 服务实现类 * * @author mitao * @since 2024-03-13 */ @Slf4j @Service @RequiredArgsConstructor public class TbBasicDataServiceImpl extends ServiceImpl implements TbBasicDataService { private final HttpServletResponse response; private final TbFieldService tbFieldService; private final TbBasicDataFieldService tbBasicDataFieldService; private final TbBasicDataConfigService tbBasicDataConfigService; private final TbBasicDataConfigDetailService tbBasicDataConfigDetailService; private final TbScoreService tbScoreService; private final ISysUserService sysUserService; private final TbOperLogService tbOperLogService; private final TbDataScreenScoreService tbDataScreenScoreService; private final TbDataScreenConfigService tbDataScreenConfigService; public static void setFieldValues( List fields, Map fieldMap) { for (FieldsTreeVO field : fields) { TbBasicDataField tbBasicDataField = fieldMap.get(field.getId()); if (tbBasicDataField != null) { field.setValue( tbBasicDataField.getFieldValue()); } if (field.getChildren() != null && !field.getChildren().isEmpty()) { setFieldValues(field.getChildren(), fieldMap); } } } @Override public R getBasicFields() throws Exception { SysUser user = SecurityUtils.getLoginUser().getUser(); String deptAreaCode = user.getAreaCode(); BasicDataReportingVO vo = new BasicDataReportingVO(); // 校验区划代码 SysUser dept = sysUserService.getOne( Wrappers.lambdaQuery().eq(SysUser::getAreaCode, deptAreaCode)); if (Objects.isNull(dept)) { throw new ServiceException(String.format("区划代码%s不存在", deptAreaCode)); } Date date = new Date(); Date quarterStart = DateUtil.beginOfQuarter(date); Date quarterEnd = DateUtil.endOfQuarter(date); Instant instant = quarterStart.toInstant(); LocalDate quarterStartLocalDate = instant.atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate fifteenDaysLimit = quarterStartLocalDate.plusDays(14); LocalDate now = LocalDate.now(); vo.setQuarter(DateUtils.getNowQuarter()); vo.setStatus(ReportingStatusEnum.UNFILLED); // 如果当前时间不在规定范围内:季度初1-15号 TODO /* 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::getReportingTime, quarterStart, quarterEnd)); // 查询需要填写的字段 List list = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list(); List roots = new ArrayList<>(); FieldsTreeVO fieldsTreeVO = new FieldsTreeVO(); fieldsTreeVO.setId(-1L); fieldsTreeVO.setName("转移支付规模"); fieldsTreeVO.setCategory(Boolean.FALSE); FieldsTreeVO fieldsTreeVO2 = new FieldsTreeVO(); fieldsTreeVO2.setId(-2L); fieldsTreeVO2.setName("当期GDP"); fieldsTreeVO2.setCategory(Boolean.FALSE); roots.add(fieldsTreeVO); roots.add(fieldsTreeVO2); if (CollUtils.isNotEmpty(list)) { FieldBuildUtil.buildTreeFromTbFieldList(list, roots); FieldsTreeVO remark = new FieldsTreeVO(); remark.setId(-3L); remark.setName("备注"); roots.add(remark); vo.setFields(roots); } if (Objects.isNull(basicData)) { vo.setQuarter(DateUtils.getNowQuarter()); 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())); setFieldValues(vo.getFields(), fieldMap); return R.ok(vo); } } return R.ok(vo); } @Override @Transactional(rollbackFor = Exception.class) public void saveBasicData(BasicDataDTO dto) throws Exception { LoginUser loginUser = SecurityUtils.getLoginUser(); String areaCode = loginUser.getUser().getAreaCode(); // 数据校验 if (Objects.isNull(dto) || CollUtils.isEmpty(dto.getFields())) { return; } String nowQuarter = DateUtils.getNowQuarter(); // 查询需要填写的动态字段 List fieldList = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list(); Map fieldMap = fieldList.stream().collect(Collectors.toMap(TbField::getId, e -> e)); Optional basicDataOpt = this.lambdaQuery() .eq(TbBasicData::getDeptAreaCode, areaCode) .eq(TbBasicData::getQuarter, nowQuarter).oneOpt(); TbBasicData tbBasicData = BeanUtils.copyBean(dto, TbBasicData.class); if (basicDataOpt.isPresent()) { tbBasicData.setId(basicDataOpt.get().getId()); tbBasicData.setDeptAreaCode(areaCode); this.updateById(tbBasicData); //查询该基础数据的动态字端 List originFields = tbBasicDataFieldService.lambdaQuery() .eq(TbBasicDataField::getBasicDataId, tbBasicData.getId()).list(); CompletableFuture.runAsync( () -> saveExchangeLog(loginUser, basicDataOpt.get(), originFields, dto, fieldMap)); } else { tbBasicData.setDeptAreaCode(areaCode); tbBasicData.setStatus(ReportingStatusEnum.MISSING_DATA); tbBasicData.setQuarter(nowQuarter); tbBasicData.setReportingTime(DateUtils.getQuarterDate(nowQuarter)); this.save(tbBasicData); } // 保存基础数据动态字段数据 List tbBasicDataFieldsOrg = BeanUtils.copyList(dto.getFields(), TbBasicDataField.class); List tbBasicDataFields = tbBasicDataFieldsOrg.stream() .filter(item -> Objects.nonNull(item.getFieldValue())).collect( Collectors.toList()); tbBasicDataFields.forEach( item -> { item.setBasicDataId(tbBasicData.getId()); TbField tbField = fieldMap.get(item.getFieldId()); if (Objects.nonNull(tbField)) { item.setFieldName(tbField.getFieldName()); } Integer numMax = tbField.getNumMax(); Integer numMin = tbField.getNumMin(); Integer textMaxNum = tbField.getTextMaxNum(); Integer textMinNum = tbField.getTextMinNum(); if (FieldTypeEnum.NUMBER.equals(tbField.getFieldType()) && Objects.nonNull( numMax) && Objects.nonNull(numMin)) { double fieldValue = Double.parseDouble(item.getFieldValue()); if (fieldValue < numMin || fieldValue > numMax) { throw new ServiceException( String.format("字段%s的值不在范围%d-%d内", tbField.getFieldName(), numMin, numMax)); } } if (FieldTypeEnum.TEXT.equals(tbField.getFieldType()) && FieldInputTypeEnum.MANUAL_INPUT.equals( tbField.getTextInputType()) && Objects.nonNull( textMaxNum) && Objects.nonNull(textMinNum)) { String fieldValue = item.getFieldValue(); if (fieldValue.length() < numMin || fieldValue.length() > numMax) { throw new ServiceException( String.format("字段%s的值的长度不在范围%d-%d内", tbField.getFieldName(), textMinNum, textMaxNum)); } } }); // 添加固定字段 转移支付规模、当期GDP TbBasicDataField transferPaymentScale = new TbBasicDataField(); transferPaymentScale.setBasicDataId(tbBasicData.getId()); transferPaymentScale.setFieldId(-1L); transferPaymentScale.setFieldValue(tbBasicData.getTransferPaymentScale()); tbBasicDataFields.add(transferPaymentScale); TbBasicDataField currentGdp = new TbBasicDataField(); currentGdp.setBasicDataId(tbBasicData.getId()); currentGdp.setFieldId(-2L); currentGdp.setFieldValue(tbBasicData.getCurrentGdp()); tbBasicDataFields.add(currentGdp); TbBasicDataField remark = new TbBasicDataField(); remark.setBasicDataId(tbBasicData.getId()); remark.setFieldId(-3L); remark.setFieldValue(tbBasicData.getRemark()); tbBasicDataFields.add(remark); // 将该基础数据的动态字段数据全部删除 tbBasicDataFieldService.remove( Wrappers.lambdaQuery() .eq(TbBasicDataField::getBasicDataId, tbBasicData.getId())); tbBasicDataFieldService.saveBatch(tbBasicDataFields); // 需要填写的动态字段 Set fieldIds = fieldList.stream().map(TbField::getId).collect(Collectors.toSet()); // 用户填写的动态字段 Set deptFieldIds = tbBasicDataFields.stream().map(TbBasicDataField::getFieldId) .collect(Collectors.toSet()); boolean flag = deptFieldIds.containsAll(fieldIds) && (StringUtils.isNotEmpty(dto.getTransferPaymentScale()) && StringUtils.isNotEmpty(dto.getCurrentGdp())); if (flag) { tbBasicData.setStatus(ReportingStatusEnum.FILLED); this.updateById(tbBasicData); } if (ReportingStatusEnum.FILLED.equals(tbBasicData.getStatus())) { CompletableFuture.runAsync(() -> { calculateScore(tbBasicData, tbBasicDataFields); calculateScreenScore(tbBasicData, tbBasicDataFields); }); } } private void calculateScreenScore(TbBasicData tbBasicData, List tbBasicDataFields) { Map basicDataFieldMap = tbBasicDataFields.stream() .collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e)); DataScreenConfigVO riskLevel = tbDataScreenConfigService.getRiskLevel(); List dataIndicatorsConfig = tbDataScreenConfigService.getIndicatorsConfig( DataScreenConfigEnum.DATA_INDICATORS); List formalIndicatorsConfig = tbDataScreenConfigService.getIndicatorsConfig( DataScreenConfigEnum.FORMAL_INDICATORS); handleScoreCalculate(tbBasicData, riskLevel, basicDataFieldMap); for (DataScreenConfigVO config : dataIndicatorsConfig) { handleScoreCalculate(tbBasicData, config, basicDataFieldMap); } for (DataScreenConfigVO config : formalIndicatorsConfig) { handleScoreCalculate(tbBasicData, config, basicDataFieldMap); } } private void handleScoreCalculate(TbBasicData tbBasicData, DataScreenConfigVO vo, Map basicDataFieldMap) { TbDataScreenScore tbDataScreenScore = tbDataScreenScoreService.lambdaQuery() .eq(TbDataScreenScore::getBasicDataId, tbBasicData.getId()).eq( TbDataScreenScore::getDataScreenConfigId, vo.getId()).one(); if (Objects.isNull(tbDataScreenScore)) { tbDataScreenScore = new TbDataScreenScore(); tbDataScreenScore.setDataScreenConfigId(vo.getId()); tbDataScreenScore.setBasicDataId(tbBasicData.getId()); tbDataScreenScore.setDeptAreaCode(tbBasicData.getDeptAreaCode()); } List scoreCalculateList = vo.getScoreCalculateList(); for (CalculateItemDTO item : scoreCalculateList) { if (item.getValueType().equals(ValueTypeEnum.FIELD)) { TbBasicDataField basicDataField = basicDataFieldMap.get( Long.valueOf(item.getContent())); if (Objects.nonNull(basicDataField)) { item.setContent(basicDataField.getFieldValue()); } } } String calculateFormulaStr = scoreCalculateList.stream() .map(CalculateItemDTO::getContent).collect(Collectors.joining()); double score = CalculateUtil.calculate(calculateFormulaStr); tbDataScreenScore.setScore(score); if (vo.getType().equals(DataScreenConfigEnum.DATA_INDICATORS)) { List rateCalculateList = vo.getRateCalculateList(); for (CalculateItemDTO calculateItemDTO : rateCalculateList) { if (calculateItemDTO.getValueType().equals(ValueTypeEnum.FIELD)) { TbBasicDataField basicDataField = basicDataFieldMap.get( Long.valueOf(calculateItemDTO.getContent())); if (Objects.nonNull(basicDataField)) { calculateItemDTO.setContent(basicDataField.getFieldValue()); } } } String calculateRateFormulaStr = rateCalculateList.stream() .map(CalculateItemDTO::getContent).collect(Collectors.joining()); double scoreRate = CalculateUtil.calculate(calculateRateFormulaStr); tbDataScreenScore.setScoreRate(scoreRate); } tbDataScreenScoreService.saveOrUpdate(tbDataScreenScore); } private void saveExchangeLog(LoginUser loginUser, TbBasicData tbBasicData, List originFields, BasicDataDTO dto, Map fieldMap) { List tbOperlogList = new ArrayList<>(); String transferPaymentScale = tbBasicData.getTransferPaymentScale(); String currentGdp = tbBasicData.getCurrentGdp(); String remark = tbBasicData.getRemark(); String transferPaymentScaleEdit = dto.getTransferPaymentScale(); String currentGdpEdit = dto.getCurrentGdp(); String remarkEdit = dto.getRemark(); if (!transferPaymentScale.equals(transferPaymentScaleEdit)) { wrapOperLog(loginUser, tbBasicData, transferPaymentScale, transferPaymentScaleEdit, tbOperlogList, "转移支付规模"); } if (!currentGdp.equals(currentGdpEdit)) { wrapOperLog(loginUser, tbBasicData, currentGdp, currentGdpEdit, tbOperlogList, "当期GDP"); } if (!remark.equals(remarkEdit)) { wrapOperLog(loginUser, tbBasicData, remark, remarkEdit, tbOperlogList, "备注"); } Map basicDataFieldMap = originFields.stream() .collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e)); for (BasicDataFieldDTO field : dto.getFields()) { TbBasicDataField tbBasicDataField = basicDataFieldMap.get(field.getFieldId()); TbField tbField = fieldMap.get(field.getFieldId()); if (Objects.nonNull(tbBasicDataField) && Objects.nonNull(tbField) && !tbBasicDataField.getFieldValue().equals(field.getFieldValue())) { String levelOneCategory = tbField.getLevelOneCategory(); String levelTwoCategory = tbField.getLevelTwoCategory(); String levelThreeCategory = tbField.getLevelThreeCategory(); String fieldName = tbField.getFieldName(); StringBuilder result = new StringBuilder(); result.append(levelOneCategory).append("-"); if (StringUtils.isNotBlank(levelTwoCategory)) { result.append(levelTwoCategory).append("-"); if (StringUtils.isNotBlank(levelThreeCategory)) { result.append(levelThreeCategory).append("-").append(fieldName); } else { result.append(fieldName); } } else { result.append(field); } wrapOperLog(loginUser, tbBasicData, tbBasicDataField.getFieldValue(), field.getFieldValue(), tbOperlogList, result.toString()); } } } private static void wrapOperLog(LoginUser loginUser, TbBasicData tbBasicData, String before, String after, List tbOperlogList, String fieldName) { SysUser user = loginUser.getUser(); TbOperLog tbOperLog = new TbOperLog(); tbOperLog.setOperation(tbBasicData.getQuarter()); tbOperLog.setStaffName( user.getUserType() == UserTypeEnum.PLATFORM ? user .getUserName() : user.getNickName()); tbOperLog.setAreaName( user.getUserType() == UserTypeEnum.PLATFORM ? "平台" : user.getAreaName()); tbOperLog.setFieldName(fieldName); tbOperLog.setBusinessType(BusinessType.UPDBASICDATA.ordinal()); tbOperLog.setBeforeEdit(before); tbOperLog.setAfterEdit(after); tbOperlogList.add(tbOperLog); } @Override public void importBasicData(MultipartFile file) throws Exception { 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(); //TODO /* if (now.isBefore(quarterStartLocalDate) || now.isAfter(fifteenDaysLimit)) { throw new ServiceException("请于季度初1-15号上传季度数据。"); }*/ LoginUser loginUser = SecurityUtils.getLoginUser(); String areaCode = loginUser.getUser().getAreaCode(); EasyExcel.read( file.getInputStream(), new BasicDataListener( this, tbFieldService, areaCode, tbBasicDataFieldService, tbBasicDataConfigService, tbBasicDataConfigDetailService, tbScoreService, tbDataScreenScoreService, tbDataScreenConfigService)) .sheet() .headRowNumber(0) .doRead(); } private void calculateScore(TbBasicData tbBasicData, List fields) { // 计算得分 List list = tbBasicDataConfigService .lambdaQuery() .eq(TbBasicDataConfig::getStatus, ShowStatusEnum.SHOW) .list(); if (CollUtils.isEmpty(list)) { throw new ServiceException("计算得分失败,平台未配置得分计算规则"); } List numCalculates = list.stream() .filter(item -> CalculateTypeEnum.NUMBER.equals(item.getCalculateType())) .collect(Collectors.toList()); List textAndPercentages = list.stream() .filter(item -> !CalculateTypeEnum.NUMBER.equals(item.getCalculateType())) .collect(Collectors.toList()); Map basicDataFieldMap = fields.stream() .collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e)); if (CollUtils.isNotEmpty(numCalculates)) { for (TbBasicDataConfig item : numCalculates) { String numberCalculateFormula = item.getNumberCalculateFormula(); List calculateItemDTOS = JSONArray.parseArray( numberCalculateFormula, CalculateItemDTO.class); for (CalculateItemDTO dto : calculateItemDTOS) { if (ValueTypeEnum.FIELD.equals(dto.getValueType())) { TbBasicDataField tbBasicDataField = basicDataFieldMap.get( Long.valueOf(dto.getContent())); if (Objects.nonNull(tbBasicDataField)) { dto.setContent(tbBasicDataField.getFieldValue()); } } } String numberCalculateFormulaStr = calculateItemDTOS.stream() .map(CalculateItemDTO::getContent).collect(Collectors.joining()); double score = CalculateUtil.calculate(numberCalculateFormulaStr); TbScore tbScore = new TbScore(); tbScore.setBasicDataId(tbBasicData.getId()); tbScore.setScore(score); tbScore.setBasicDataConfigId(item.getId()); tbScoreService.save(tbScore); } } if (CollUtils.isNotEmpty(textAndPercentages)) { for (TbBasicDataConfig textAndPercentage : textAndPercentages) { TbScore tbScore = new TbScore(); List details = tbBasicDataConfigDetailService .lambdaQuery() .eq(TbBasicDataConfigDetail::getBasicDataConfigId, textAndPercentage.getId()) .list(); Map scoreMap = details.stream() .collect( Collectors.toMap( TbBasicDataConfigDetail::getKey, TbBasicDataConfigDetail::getValue)); if (CollUtils.isNotEmpty(details)) { TbBasicDataField textAndPercentageData = basicDataFieldMap.get( Long.valueOf(textAndPercentage.getFieldIdStr())); if (Objects.nonNull(textAndPercentageData)) { if (CalculateTypeEnum.TEXT.equals(textAndPercentage.getCalculateType())) { String score = scoreMap.get(textAndPercentageData.getFieldValue()); tbScore.setBasicDataId(tbBasicData.getId()); tbScore.setScore(Double.parseDouble(score)); tbScore.setBasicDataConfigId(textAndPercentage.getId()); tbScoreService.save(tbScore); } if (CalculateTypeEnum.PERCENTAGE.equals( textAndPercentage.getCalculateType())) { for (Map.Entry stringStringEntry : scoreMap.entrySet()) { String[] split = stringStringEntry.getKey().split("_"); double v = Double.parseDouble( textAndPercentageData.getFieldValue()); double min = Double.parseDouble(split[0]); double max = Double.parseDouble(split[1]); if (v >= min && v <= max) { tbScore.setScore( Double.parseDouble(stringStringEntry.getValue())); } } tbScore.setBasicDataId(tbBasicData.getId()); tbScore.setBasicDataConfigId(textAndPercentage.getId()); tbScoreService.save(tbScore); } } } } } } @Override public PageDTO pageScore(ScoreQuery query) { Page page = new Page<>(query.getPageNum(), query.getPageSize()); SysUser user = SecurityUtils.getLoginUser().getUser(); String areaCode = user.getAreaCode(); Date date = new Date(); Date quarterStart = DateUtil.beginOfQuarter(date); Date quarterEnd = DateUtil.endOfQuarter(date); // 查询是否有当前季度的填报记录 TbBasicData basicData = this.getOne( Wrappers.lambdaQuery() .eq(TbBasicData::getDeptAreaCode, areaCode) .between(TbBasicData::getReportingTime, quarterStart, quarterEnd)); if (Objects.isNull(basicData)) { return PageDTO.empty(page); } query.setBasicDataId(basicData.getId()); // 查询对应的基础数据配置 Page pageVO = tbScoreService.pageScore(query, page); return PageDTO.of(pageVO); } @Override public R fieldsDetails(Long id) { // 从数据库中获取基本数据 TbBasicData basicData = this.getById(id); if (Objects.isNull(basicData)) { throw new ServiceException("非法参数"); } CurrentFieldsDetailVO vo = BeanUtils.copyBean(basicData, CurrentFieldsDetailVO.class); vo.setId(basicData.getId()); // 查询用户信息 sysUserService .lambdaQuery() .eq(SysUser::getAreaCode, basicData.getDeptAreaCode()) .eq(SysUser::getUserType, UserTypeEnum.DEPARTMENT.getCode()) .oneOpt() .ifPresent( item -> { vo.setAreaName(item.getAreaName()); vo.setPhoneNumber(item.getPhoneNumber()); vo.setPersonInCharge(item.getPersonInCharge()); }); // 查询动态字段 List basicDataFields = tbBasicDataFieldService .lambdaQuery() .eq(TbBasicDataField::getBasicDataId, basicData.getId()) .list(); // 获取所有字段ID Set fieldIds = basicDataFields.stream().map(TbBasicDataField::getFieldId) .collect(Collectors.toSet()); // 根据字段ID查询字段信息并构建字段ID到字段对象的映射 Map fieldMap = tbFieldService .lambdaQuery() .in(!fieldIds.isEmpty(), TbField::getId, fieldIds) .list() .stream() .collect(Collectors.toMap(TbField::getId, e -> e)); // 根节点 List root = new ArrayList<>(); basicDataFields.stream() .filter(item -> item.getFieldId() == -1) .findFirst() .ifPresent( item -> { FieldsTreeVO fieldsTreeVO = new FieldsTreeVO(); fieldsTreeVO.setId(item.getFieldId()); fieldsTreeVO.setName("转移支付规模"); fieldsTreeVO.setValue(item.getFieldValue()); fieldsTreeVO.setCategory(Boolean.FALSE); root.add(fieldsTreeVO); }); basicDataFields.stream() .filter(item -> item.getFieldId() == -2) .findFirst() .ifPresent( item -> { FieldsTreeVO fieldsTreeVO = new FieldsTreeVO(); fieldsTreeVO.setId(item.getFieldId()); fieldsTreeVO.setName("当期GDP"); fieldsTreeVO.setValue(item.getFieldValue()); fieldsTreeVO.setCategory(Boolean.FALSE); root.add(fieldsTreeVO); }); FieldBuildUtil.buildTreeStructure(basicDataFields, fieldMap, root); basicDataFields.stream() .filter(item -> item.getFieldId() == -3) .findFirst() .ifPresent( item -> { FieldsTreeVO fieldsTreeVO = new FieldsTreeVO(); fieldsTreeVO.setId(item.getFieldId()); fieldsTreeVO.setName("备注"); fieldsTreeVO.setValue(item.getFieldValue()); fieldsTreeVO.setCategory(Boolean.FALSE); root.add(fieldsTreeVO); }); vo.setFields(root); return R.ok(vo); } @Override public R> fieldsStatics(CurrentFieldsQuery dto) { Page page = new Page<>(dto.getPageNum(), dto.getPageSize()); return R.ok(PageDTO.of(baseMapper.fieldsStatics(page, dto))); } @Override public CurrentFieldsAllVO fieldsStaticsAll() throws Exception { CurrentFieldsAllVO vo = new CurrentFieldsAllVO(); List roots = new ArrayList<>(); // 获取表头 FieldsTreeVO area = new FieldsTreeVO(); area.setCategory(Boolean.FALSE); area.setName("地区"); FieldsTreeVO quarter = new FieldsTreeVO(); quarter.setCategory(Boolean.FALSE); quarter.setName("填报季度"); FieldsTreeVO transferPaymentScale = new FieldsTreeVO(); transferPaymentScale.setName("转移支付规模"); FieldsTreeVO currentGdp = new FieldsTreeVO(); currentGdp.setCategory(Boolean.FALSE); currentGdp.setName("当期GDP"); roots.add(area); roots.add(quarter); roots.add(transferPaymentScale); roots.add(currentGdp); // 查询当前季度填写字段 List fieldList = tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list(); FieldBuildUtil.buildTreeFromTbFieldList(fieldList, roots); FieldsTreeVO remark = new FieldsTreeVO(); remark.setCategory(Boolean.FALSE); remark.setName("备注"); roots.add(remark); vo.setFields(roots); String nowQuarter = DateUtils.getNowQuarter(); // 查询上报的基础数据 List basicDataList = this.lambdaQuery() .eq(TbBasicData::getQuarter, nowQuarter) .eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED) .list(); if (CollUtils.isNotEmpty(basicDataList)) { Set areaCodeList = basicDataList.stream().map(TbBasicData::getDeptAreaCode) .collect(Collectors.toSet()); Map userMap = sysUserService.lambdaQuery().in(SysUser::getAreaCode, areaCodeList).list() .stream() .collect(Collectors.toMap(SysUser::getAreaCode, e -> e)); Set basicDataIds = basicDataList.stream().map(TbBasicData::getId).collect(Collectors.toSet()); List tbBasicDataFieldList = tbBasicDataFieldService .lambdaQuery() .in(TbBasicDataField::getBasicDataId, basicDataIds) .list(); // 值 List result = new ArrayList<>(); for (TbBasicData tbBasicData : basicDataList) { SysUser user = userMap.get(tbBasicData.getDeptAreaCode()); Map basicDataFieldMap = tbBasicDataFieldList.stream() .filter(field -> field.getBasicDataId().equals(tbBasicData.getId())) .collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e)); List item = new ArrayList<>(); item.add(Objects.nonNull(user) ? user.getAreaName() : ""); item.add(tbBasicData.getQuarter()); item.add(tbBasicData.getTransferPaymentScale()); item.add(tbBasicData.getCurrentGdp()); for (TbField tbField : fieldList) { TbBasicDataField tbBasicDataField = basicDataFieldMap.get(tbField.getId()); item.add( Objects.nonNull(tbBasicDataField) ? tbBasicDataField.getFieldValue() : ""); } item.add(tbBasicData.getRemark()); result.add(item); } vo.setValue(result); } return vo; } @Override public R> historyFieldsStatics(CurrentFieldsQuery dto) { Page page = new Page<>(dto.getPageNum(), dto.getPageSize()); // 当前所在季度 return R.ok(PageDTO.of(baseMapper.fieldsStatics(page, dto))); } @Override public PageDTO scoreCalculatePage(ScoreCalculateQuery query) { Page page = new Page<>(query.getPageNum(), query.getPageSize()); Page pageVO = tbBasicDataConfigService.scoreCalculatePage(query, page); return PageDTO.of(pageVO); } @Override public CurrentFieldsAllVO fieldsStaticsAll(String quarterStr) { CurrentFieldsAllVO vo = new CurrentFieldsAllVO(); List roots = new ArrayList<>(); // 获取表头 FieldsTreeVO area = new FieldsTreeVO(); area.setCategory(Boolean.FALSE); area.setName("地区"); FieldsTreeVO quarter = new FieldsTreeVO(); quarter.setCategory(Boolean.FALSE); quarter.setName("填报季度"); FieldsTreeVO transferPaymentScale = new FieldsTreeVO(); transferPaymentScale.setName("转移支付规模"); FieldsTreeVO currentGdp = new FieldsTreeVO(); currentGdp.setCategory(Boolean.FALSE); currentGdp.setName("当期GDP"); roots.add(area); roots.add(quarter); roots.add(transferPaymentScale); roots.add(currentGdp); List basicDataList = this.lambdaQuery() .eq(TbBasicData::getQuarter, quarterStr) .eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED) .list(); if (CollUtils.isEmpty(basicDataList)) { throw new ServiceException("非法参数"); } Long basicDataId = basicDataList.get(0).getId(); Set fieldIds = tbBasicDataFieldService .lambdaQuery() .eq(TbBasicDataField::getBasicDataId, basicDataId) .ne(TbBasicDataField::getFieldId, -1L) .ne(TbBasicDataField::getFieldId, -2L) .list() .stream() .map(TbBasicDataField::getFieldId) .collect(Collectors.toSet()); List fieldList = tbFieldService.lambdaQuery().in(TbField::getId, fieldIds).list(); if (CollUtils.isEmpty(fieldList)) { FieldsTreeVO remark = new FieldsTreeVO(); remark.setCategory(Boolean.FALSE); remark.setName("备注"); roots.add(remark); vo.setFields(roots); return vo; } FieldBuildUtil.buildTreeFromTbFieldList(fieldList, roots); FieldsTreeVO remark = new FieldsTreeVO(); remark.setCategory(Boolean.FALSE); remark.setName("备注"); roots.add(remark); vo.setFields(roots); Set areaCodeList = basicDataList.stream().map(TbBasicData::getDeptAreaCode) .collect(Collectors.toSet()); Map userMap = sysUserService.lambdaQuery().in(SysUser::getAreaCode, areaCodeList).list().stream() .collect(Collectors.toMap(SysUser::getAreaCode, e -> e)); Set basicDataIds = basicDataList.stream().map(TbBasicData::getId).collect(Collectors.toSet()); List basicDataFieldList = tbBasicDataFieldService .lambdaQuery() .in(TbBasicDataField::getBasicDataId, basicDataIds) .list(); // 值 List result = new ArrayList<>(); for (TbBasicData tbBasicData : basicDataList) { Map basicDataFieldMap = basicDataFieldList.stream() .filter(item -> tbBasicData.getId().equals(item.getBasicDataId())) .collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e)); SysUser user = userMap.get(tbBasicData.getDeptAreaCode()); List item = new ArrayList<>(); item.add(Objects.nonNull(user) ? user.getAreaName() : ""); item.add(tbBasicData.getQuarter()); item.add(tbBasicData.getTransferPaymentScale()); item.add(tbBasicData.getCurrentGdp()); for (TbField tbField : fieldList) { TbBasicDataField tbBasicDataField = basicDataFieldMap.get(tbField.getId()); item.add( Objects.nonNull(tbBasicDataField) ? tbBasicDataField.getFieldValue() : ""); } item.add(tbBasicData.getRemark()); result.add(item); } vo.setValue(result); return vo; } @Override @Transactional(rollbackFor = Exception.class) public void importData(MultipartFile file, String quarter) throws IOException { //校验季度 Date quarterDate = DateUtils.getQuarterDate(quarter); Map quarterMap = DateUtils.getQuarterDate(new Date()); Date date = quarterMap.get("first"); LocalDate quarterLocalDate = DateUtils.dateToLocalDate(quarterDate); LocalDate dateLocalDate = DateUtils.dateToLocalDate(date); if (quarterLocalDate.isAfter(dateLocalDate) || quarterLocalDate.equals(dateLocalDate)) { throw new ServiceException("请导入过去季度的数据。"); } EasyExcel.read( file.getInputStream(), new HistoryDataListener( this, tbFieldService, tbBasicDataFieldService, tbBasicDataConfigService, tbBasicDataConfigDetailService, tbScoreService, sysUserService, quarter, tbDataScreenScoreService, tbDataScreenConfigService)) .sheet() .doRead(); } @Override public void exportData(List quarterList) throws Exception { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); String fileName = "地方财政运行及“三保”情况统计表"; response.setHeader( "Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx"); //季度数据,用于反查字段 List tbBasicDataList = this.lambdaQuery() .in(TbBasicData::getQuarter, quarterList) .eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED) .groupBy(TbBasicData::getQuarter).list(); //符合导出条件的基础数据 List tbBasicDataListAll = this.lambdaQuery() .in(TbBasicData::getQuarter, quarterList) .eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED) .list(); //基础数据id列表 Set basicDataIdList = tbBasicDataListAll.stream().map(TbBasicData::getId) .collect(Collectors.toSet()); //涉及到的部门编码 Set userAreaCodeList = tbBasicDataListAll.stream().map(TbBasicData::getDeptAreaCode) .collect(Collectors.toSet()); //用户信息map Map userMap = sysUserService.lambdaQuery() .in(SysUser::getAreaCode, userAreaCodeList).list().stream() .collect(Collectors.toMap(SysUser::getAreaCode, e -> e)); //基础数据对应的字段值列表 List tbBasicDataFieldList = tbBasicDataFieldService.lambdaQuery() .in(TbBasicDataField::getBasicDataId, basicDataIdList) .list(); //构建Excel写对象 try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) .registerWriteHandler(new CustomCellWriteHandler()) .registerWriteHandler(EasyExcelUtil.getStyleStrategy()).build()) { WriteSheet writeSheet; //遍历季度基础数据 for (TbBasicData tbBasicData : tbBasicDataList) { //该季度的动态字段id列表 Set fieldIdList = tbBasicDataFieldList.stream() .filter(item -> tbBasicData.getId().equals(item.getBasicDataId())) .map(TbBasicDataField::getFieldId) .collect(Collectors.toSet()); //字段列表 List fieldList = tbFieldService.lambdaQuery() .in(TbField::getId, fieldIdList) .list(); //表头 List> head = head(fieldList); //过滤基础数据为遍历元素的季度 List list = tbBasicDataListAll.stream() .filter(item -> tbBasicData.getQuarter().equals(item.getQuarter())) .collect(Collectors.toList()); List> dataList = dataList(fieldList, list, tbBasicDataFieldList, userMap, head); // 构建sheet对象 writeSheet = EasyExcel.writerSheet(tbBasicData.getQuarter()).head(head).build(); // 写出sheet数据 excelWriter.write(dataList, writeSheet); } } } private List> dataList(List fieldList, List list, List tbBasicDataFieldList, Map userMap, List> head) { //所有数据集合 List> excellist = new ArrayList<>(); //构建栏号行 List columnNo = Lists.newArrayList("栏号"); for (int i = 1; i < head.size(); i++) { columnNo.add(String.valueOf(i)); } excellist.add(columnNo); //动态字段数据行 for (TbBasicData tbBasicData : list) { //转换为map,方便遍历的时候取 Map basicDataFieldMap = tbBasicDataFieldList.stream() .filter(item -> tbBasicData.getId().equals(item.getBasicDataId())) .collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e)); SysUser sysUser = userMap.get(tbBasicData.getDeptAreaCode()); if (CollUtils.isEmpty(basicDataFieldMap) || Objects.isNull(sysUser)) { continue; } List valueList = Lists.newArrayList(sysUser.getAreaName(), tbBasicData.getQuarter()); TbBasicDataField transferPaymentScale = basicDataFieldMap.get(-1L); valueList.add( Objects.nonNull(transferPaymentScale) ? transferPaymentScale.getFieldValue() : ""); TbBasicDataField currentGdp = basicDataFieldMap.get(-2L); valueList.add( Objects.nonNull(currentGdp) ? currentGdp.getFieldValue() : ""); for (TbField tbField : fieldList) { TbBasicDataField tbBasicDataField = basicDataFieldMap.get(tbField.getId()); valueList.add( Objects.nonNull(tbBasicDataField) ? tbBasicDataField.getFieldValue() : ""); } excellist.add(valueList); valueList.add(tbBasicData.getRemark()); } return excellist; } private List> head(List list) { List> headTitles = Lists.newArrayList(); // 固定字段 headTitles.add(Lists.newArrayList("地区")); headTitles.add(Lists.newArrayList("填报季度")); headTitles.add(Lists.newArrayList("转移支付规模")); headTitles.add(Lists.newArrayList("当期GDP")); list.forEach( item -> { String levelOneCategory = item.getLevelOneCategory(); String levelTwoCategory = item.getLevelTwoCategory(); String levelThreeCategory = item.getLevelThreeCategory(); String fieldName = item.getFieldName(); headTitles.add( Lists.newArrayList( levelOneCategory, StringUtils.isBlank(levelTwoCategory) ? fieldName : levelTwoCategory, StringUtils.isBlank(levelThreeCategory) ? fieldName : levelThreeCategory, fieldName)); }); headTitles.add(Lists.newArrayList("备注")); return headTitles; } @Override public Page transferPaymentScalePage(Page page, String quarter) { Page pageVO = baseMapper.transferPaymentScalePage( page, quarter); int rank = 1; for (TransferPaymentScaleVO record : pageVO.getRecords()) { record.setRank(rank++); } return pageVO; } @Override public List selectBasicDataFieldsConfig(String areaCode, String nowQuarter) { return baseMapper.selectBasicDataFieldsConfig(areaCode, nowQuarter); } @Override @Transactional(rollbackFor = Exception.class) public void editBasicData(BasicDataUpdDTO dto) throws Exception { LoginUser loginUser = SecurityUtils.getLoginUser(); // 数据校验 if (Objects.isNull(dto)) { return; } //查询基础数据 TbBasicData basicData = this.getById(dto.getId()); if (Objects.isNull(basicData)) { throw new ServiceException("非法参数"); } String nowQuarter = DateUtils.getNowQuarter(); this.updateById(basicData); //查询该基础数据的动态字端 List originFields = tbBasicDataFieldService.lambdaQuery() .eq(TbBasicDataField::getBasicDataId, basicData.getId()).list(); Set fieldIdList = originFields.stream().map(TbBasicDataField::getFieldId) .collect(Collectors.toSet()); Map fieldMap = tbFieldService.lambdaQuery().in(TbField::getId, fieldIdList) .list().stream().collect(Collectors.toMap(TbField::getId, e -> e)); CompletableFuture.runAsync( () -> saveExchangeLog(loginUser, basicData, originFields, BeanUtils.copyBean(dto, BasicDataDTO.class), fieldMap)); TbBasicData tbBasicData = BeanUtils.copyBean(dto, TbBasicData.class); // 保存基础数据动态字段数据 List tbBasicDataFields = BeanUtils.copyList(dto.getFields(), TbBasicDataField.class); for (TbBasicDataField item : tbBasicDataFields) { TbField tbField = fieldMap.get(item.getFieldId()); Integer numMax = tbField.getNumMax(); Integer numMin = tbField.getNumMin(); Integer textMaxNum = tbField.getTextMaxNum(); Integer textMinNum = tbField.getTextMinNum(); if (FieldTypeEnum.NUMBER.equals(tbField.getFieldType()) && Objects.nonNull( numMax) && Objects.nonNull(numMin)) { double fieldValue = Double.parseDouble(item.getFieldValue()); if (fieldValue < numMin || fieldValue > numMax) { throw new ServiceException( String.format("字段%s的值不在范围%d-%d内", tbField.getFieldName(), numMin, numMax)); } } if (FieldTypeEnum.TEXT.equals(tbField.getFieldType()) && FieldInputTypeEnum.MANUAL_INPUT.equals(tbField.getTextInputType()) && Objects.nonNull( textMaxNum) && Objects.nonNull(textMinNum)) { String fieldValue = item.getFieldValue(); if (fieldValue.length() < numMin || fieldValue.length() > numMax) { throw new ServiceException( String.format("字段%s的值的长度不在范围%d-%d内", tbField.getFieldName(), textMinNum, textMaxNum)); } } } tbBasicDataFields.forEach( item -> { item.setBasicDataId(tbBasicData.getId()); TbField tbField = fieldMap.get(item.getFieldId()); if (Objects.nonNull(tbField)) { item.setFieldName(tbField.getFieldName()); } }); // 添加固定字段 转移支付规模、当期GDP TbBasicDataField transferPaymentScale = new TbBasicDataField(); transferPaymentScale.setBasicDataId(tbBasicData.getId()); transferPaymentScale.setFieldId(-1L); transferPaymentScale.setFieldValue(tbBasicData.getTransferPaymentScale()); tbBasicDataFields.add(transferPaymentScale); TbBasicDataField currentGdp = new TbBasicDataField(); currentGdp.setBasicDataId(tbBasicData.getId()); currentGdp.setFieldId(-2L); currentGdp.setFieldValue(tbBasicData.getCurrentGdp()); tbBasicDataFields.add(currentGdp); TbBasicDataField remark = new TbBasicDataField(); remark.setBasicDataId(tbBasicData.getId()); remark.setFieldId(-3L); remark.setFieldValue(tbBasicData.getRemark()); tbBasicDataFields.add(remark); // 将该基础数据的动态字段数据全部删除 tbBasicDataFieldService.remove( Wrappers.lambdaQuery() .eq(TbBasicDataField::getBasicDataId, tbBasicData.getId())); tbBasicDataFieldService.saveBatch(tbBasicDataFields); if (ReportingStatusEnum.FILLED.equals(tbBasicData.getStatus())) { CompletableFuture.runAsync(() -> { calculateScore(tbBasicData, tbBasicDataFields); calculateScreenScore(tbBasicData, tbBasicDataFields); }); } } }