# ManagersScorecardServiceImpl.java

    package cloud.wconnect.workperformance.service.monthlyreport.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.FunctionIdConstant;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.CommonService;
    import cloud.wconnect.commonlib.util.S3Utils;
    import cloud.wconnect.commonlib.util.TransactionUtils;
    import cloud.wconnect.workperformance.cons.S3BucketFunctionCons;
    import cloud.wconnect.workperformance.cons.monthlyreport.AreaEnum;
    import cloud.wconnect.workperformance.entity.monthlyreport.MonthlyReport;
    import cloud.wconnect.workperformance.entity.monthlyreport.ReportAttachment;
    import cloud.wconnect.workperformance.pojo.dto.monthlyreport.AttachmentDTO;
    import cloud.wconnect.workperformance.pojo.dto.monthlyreport.managerscorecard.ManagersScorecardDetailDTO;
    import cloud.wconnect.workperformance.pojo.dto.scorecardgm.ScoreCardGmDTO;
    import cloud.wconnect.workperformance.service.monthlyreport.IManagersScorecardService;
    import cloud.wconnect.workperformance.service.monthlyreport.IReportAttachmentService;
    import cloud.wconnect.workperformance.service.scorecardgm.IScoreCardGmService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.Executor;

    /**
     * Managers’ Scorecard 区域业务层
     *
     * @author lichen
     * @date 2023/9/5
     */
    @Service
    @DS("monthly_report")
    public class ManagersScorecardServiceImpl implements IManagersScorecardService {

        @Autowired
        private IReportAttachmentService reportAttachmentService;
        @Autowired
        private IScoreCardGmService scoreCardGmService;
        @Autowired
        private BeanMapper beanMapper;
        @Value("${aws-s3.region}")
        private String region;
        @Value("#{${aws-s3.function-bucket}}")
        private Map<String, Map<String, Object>> bucketMap;
        @Autowired
        private Executor executor;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private CommonService commonService;

        /**
         * 获取Managers’ Scorecard区域详情
         *
         * @param monthlyReport 月报
         * @param propertyId    资产id
         * @return cloud.wconnect.workperformance.pojo.dto.monthlyreport.managerscorecard.ManagersScorecardDetailDTO
         * @author lichen
         * @date 2023/9/5
         */
        @Override
        public ManagersScorecardDetailDTO getManagersScorecard(MonthlyReport monthlyReport, Integer propertyId) {
            //查询附件集合
            List<ReportAttachment> attachments = reportAttachmentService
                    .listByReportIdAndAreaId(propertyId, monthlyReport.getId(), AreaEnum.MANAGERS_SCORECARD.getAreaId());
            //获取资产信息
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            //查询评分数据
            ScoreCardGmDTO scoreCardGmDTO = new ScoreCardGmDTO();
            if (commonService.checkOpenFunction(propertyDTO, FunctionIdConstant.GM_SCORECARD)) {
                //查询评分数据
                scoreCardGmDTO = scoreCardGmService.getDetail4MonthlyReport(propertyId, monthlyReport.getYear(), monthlyReport.getMonth());
            }
            return new ManagersScorecardDetailDTO(beanMapper.mapList(attachments, AttachmentDTO.class), scoreCardGmDTO);
        }

        /**
         * 保存Managers’ Scorecard区域数据
         *
         * @param monthlyReport 月报
         * @param propertyDTO   资产DTO
         * @param attachments   附件集合
         * @return void
         * @author lichen
         * @date 2023/9/5
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void save(MonthlyReport monthlyReport, PropertyDTO propertyDTO, List<AttachmentDTO> attachments) {
            //保存前的s3key集合
            List<String> saveBeforeS3Keys = reportAttachmentService.listByReportIdAndAreaId(propertyDTO.getId(), monthlyReport.getId(), AreaEnum.MANAGERS_SCORECARD.getAreaId())
                    .stream().map(ReportAttachment::getFileKey).toList();

            //删除附件
            reportAttachmentService.removeByReportIdAndAreaId(monthlyReport.getPropertyId(), monthlyReport.getId(), AreaEnum.MANAGERS_SCORECARD.getAreaId());

            //批量保存附件
            List<String> saveAfterS3Keys = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(attachments)) {
                List<ReportAttachment> reportAttachments = Lists.newArrayListWithCapacity(attachments.size());
                for (AttachmentDTO attachment : attachments) {
                    reportAttachments.add(ReportAttachment.builder()
                            .tenantId(propertyDTO.getTenantId())
                            .propertyId(propertyDTO.getId())
                            .reportId(monthlyReport.getId())
                            .areaId(AreaEnum.MANAGERS_SCORECARD.getAreaId())
                            .fileName(attachment.getFileName())
                            .fileKey(attachment.getFileKey())
                            .build());
                    saveAfterS3Keys.add(attachment.getFileKey());
                }
                reportAttachmentService.saveBatch(reportAttachments);
            }

            /**
             * 事务提交后删除s3附件
             */
            TransactionUtils.afterCommitAsyncExecute(executor, () -> {
                List<String> delS3Keys = Lists.newArrayList(saveBeforeS3Keys);
                delS3Keys.removeAll(saveAfterS3Keys);
                S3Utils.batchDeleteFile(region, bucketMap.get(S3BucketFunctionCons.MONTHLY_REPORT), delS3Keys);
            });
        }
    }