# M3PlReportLogServiceImpl.java

    package cloud.wconnect.finance.service.pl.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.finance.entity.pl.M3PlReportLog;
    import cloud.wconnect.finance.mapper.pl.M3PlReportLogMapper;
    import cloud.wconnect.finance.pojo.dto.pl.PlReportLogDTO;
    import cloud.wconnect.finance.service.pl.IM3PlReportLogService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;

    import javax.annotation.Nullable;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;

    /**
     * <p>
     * P&L功能生成log 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2025-09-25
     */
    @Service
    @DS("finance")
    public class M3PlReportLogServiceImpl extends ServiceImpl<M3PlReportLogMapper, M3PlReportLog> implements IM3PlReportLogService {

        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 根据资产id和月份查询P&L功能生成log
         *
         * @param tenantId   租户id
         * @param propertyId 资产id
         * @param yearMonth  月份，例如：202506
         * @param id         日志id
         * @return java.util.List<cloud.wconnect.finance.pojo.dto.pl.PlReportLogDTO>
         * @author lichen
         * @date 2025/9/29
         */
        @Override
        public List<PlReportLogDTO> listByYearMonth(Integer tenantId, int propertyId, Integer yearMonth, @Nullable Integer id) {
            List<M3PlReportLog> list = list(new LambdaQueryWrapper<M3PlReportLog>().eq(M3PlReportLog::getPropertyId, propertyId)
                    .eq(Objects.nonNull(id), M3PlReportLog::getId, id)
                    .eq(M3PlReportLog::getYearMonth, yearMonth)
                    .orderByDesc(M3PlReportLog::getId));
            if (CollectionUtils.isEmpty(list)) return Collections.emptyList();

            List<Integer> userIds = list.stream().map(M3PlReportLog::getCreateUserId).distinct().toList();
            Map<Integer, UserDTO> userId2DTO = userInternalService.getUserMapByIds(tenantId, userIds);
            return beanMapper.mapList(list, PlReportLogDTO.class, (entity, dto) -> {
                UserDTO userDTO = userId2DTO.getOrDefault(entity.getCreateUserId(), new UserDTO());
                dto.setCreateUserName(userDTO.getName());
                dto.setAvatar(userDTO.getAvatar());
            });
        }

        /**
         * 插入处理中的log
         *
         * @param tenantId   租户id
         * @param propertyId 资产id
         * @param yearMonth  月份，例如：202506
         * @param userId     用户id
         * @return java.lang.Integer
         * @author lichen
         * @date 2025/10/2
         */
        @Override
        public Integer insertProcessingLog(Integer tenantId, Integer propertyId, Integer yearMonth, int userId) {
            M3PlReportLog log = new M3PlReportLog();
            log.setTenantId(tenantId);
            log.setPropertyId(propertyId);
            log.setYearMonth(yearMonth);
            log.setCreateUserId(userId);
            log.setCreateTime(DateTimeUtils.nowTimestamp());
            log.setStatus(M3PlReportLog.STATUS_PROCESSING);
            //新增
            save(log);

            return log.getId();
        }

        /**
         * 检查指定资产指定月份是否正在生成报告
         *
         * @param propertyId 资产id
         * @param yearMonth  月份，例如：202506
         * @author lichen
         * @date 2025/9/29
         */
        @Override
        public boolean checkIsBeingGenerated(Integer propertyId, Integer yearMonth) {
            //查询最新的 log
            M3PlReportLog m3PlReportLog = getOne(new LambdaQueryWrapper<M3PlReportLog>().eq(M3PlReportLog::getPropertyId, propertyId)
                    .eq(M3PlReportLog::getYearMonth, yearMonth)
                    .orderByDesc(M3PlReportLog::getId)
                    .last("limit 1"));
            return Objects.nonNull(m3PlReportLog) && M3PlReportLog.STATUS_PROCESSING == m3PlReportLog.getStatus();
        }

        /**
         * 更新log为失败
         *
         * @param logId                   log id
         * @param messageFlagCallM3Failed 错误信息
         * @author lichen
         * @date 2025/9/29
         */
        @Override
        @Async
        public void updateFailed(Integer logId, int messageFlagCallM3Failed) {
            M3PlReportLog m3PlReportLog = new M3PlReportLog();
            m3PlReportLog.setId(logId);
            m3PlReportLog.setStatus(M3PlReportLog.STATUS_FAILED);
            m3PlReportLog.setMessageFlag(messageFlagCallM3Failed);
            m3PlReportLog.setUpdateTime(DateTimeUtils.nowTimestamp());
            updateById(m3PlReportLog);
        }

        /**
         * 更新log为成功
         *
         * @param logId log id
         * @return void
         * @author lichen
         * @date 2025/10/2
         */
        @Override
        @Async
        public void updateSuccess(Integer logId) {
            M3PlReportLog m3PlReportLog = new M3PlReportLog();
            m3PlReportLog.setId(logId);
            m3PlReportLog.setStatus(M3PlReportLog.STATUS_SUCCESS);
            m3PlReportLog.setUpdateTime(DateTimeUtils.nowTimestamp());
            updateById(m3PlReportLog);
        }
    }