# LogbookCommentServiceImpl.java

    package cloud.wconnect.frontoffice.service.logbook.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.AttachmentUtil;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.S3Utils;
    import cloud.wconnect.commonlib.util.TransactionUtils;
    import cloud.wconnect.frontoffice.cons.S3BucketFunctionCons;
    import cloud.wconnect.frontoffice.entity.logbook.Logbook;
    import cloud.wconnect.frontoffice.entity.logbook.LogbookComment;
    import cloud.wconnect.frontoffice.mapper.logbook.LogbookCommentMapper;
    import cloud.wconnect.frontoffice.pojo.dto.logbook.LogbookCommentDTO;
    import cloud.wconnect.frontoffice.service.logbook.ILogbookCommentService;
    import cloud.wconnect.frontoffice.service.logbook.ILogbookService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.fasterxml.jackson.databind.ObjectMapper;
    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.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.concurrent.Executor;
    import java.util.stream.Collectors;

    /**
     * <p>
     *  服务实现类
     * </p>
     *
     * @author yyt
     * @since 2023-03-18
     */
    @Service
    @DS("logbook")
    public class LogbookCommentServiceImpl extends ServiceImpl<LogbookCommentMapper, LogbookComment> implements ILogbookCommentService {

        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private ILogbookService logbookService;
        @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 ObjectMapper objectMapper;

        /**
         * 获取 logbook 备注列表
         *
         * @param tenantId tenant id
         * @param id       logbook id
         * @return logbook 备注列表
         * @author yyt
         * @date 2023/3/21
         */
        @Override
        public List<LogbookCommentDTO> listComment(int tenantId, int id) {
            // 创建时间 倒序显示
            List<LogbookComment> logbookComments = baseMapper.selectList(new QueryWrapper<LogbookComment>().lambda()
                    .eq(LogbookComment::getLogbookId, id).orderByDesc(LogbookComment::getCreateTime));
            if (CollectionUtils.isEmpty(logbookComments)) {
                return Collections.emptyList();
            }

            List<Integer> userIds = logbookComments.stream().map(LogbookComment::getCreateId).distinct().collect(Collectors.toList());
            Map<Integer, UserDTO> userById = userInternalService.getUsers(tenantId, userIds)
                    .stream().collect(Collectors.toMap(UserDTO::getId, v->v));

            return beanMapper.mapList(logbookComments, LogbookCommentDTO.class,
                    item -> {
                        UserDTO userDTO = userById.get(item.getCreateId());
                        item.setCreateName(userDTO.getName());
                        item.setAvatar(userDTO.getAvatar());
                    });
        }

        /**
         * 新增备注
         *
         * @param id         logbook id
         * @param propertyId 资产 id
         * @param commentDTO 备注内容
         * @param userId     操作人
         * @return comment
         * @author yyt
         * @date 2023/3/21
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public LogbookComment saveComment(int id, int propertyId, LogbookCommentDTO commentDTO, int userId) {
            Logbook logbook = logbookService.getByIdForUpdate(id);
            Logbook updateLogbook = new Logbook();
            updateLogbook.setCommentCount(logbook.getCommentCount() + 1);
            updateLogbook.setId(id);
            logbookService.updateById(updateLogbook);

            LogbookComment logbookComment = beanMapper.map(commentDTO, LogbookComment.class);
            logbookComment.setLogbookId(id);
            logbookComment.setPropertyId(propertyId);
            logbookComment.setCreateId(userId);
            logbookComment.setCreateTime(DateTimeUtils.nowTimestamp());
            save(logbookComment);

            return logbookComment;
        }

        /**
         * 校验 Comment 存在
         *
         * @param logbookId logbook id
         * @param cid       comment id
         * @return Comment
         * @author yyt
         * @date 2023/3/21
         */
        @Override
        public LogbookComment checkCommentExist(int logbookId, int cid) {
            LogbookComment comment = getOne(new QueryWrapper<LogbookComment>().lambda().eq(LogbookComment::getLogbookId, logbookId)
                    .eq(LogbookComment::getId, cid));
            if (Objects.isNull(comment)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the logbookComment is not found;id:" + cid + ";logbookId:" + logbookId);
            }

            return comment;
        }

        /**
         * 删除备注
         *
         * @param id      logbook id
         * @param comment comment
         * @author yyt
         * @date 2023/4/6
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void remove(int id, LogbookComment comment) {
            Logbook logbook = logbookService.getByIdForUpdate(id);
            Logbook updateLogbook = new Logbook();
            updateLogbook.setCommentCount(logbook.getCommentCount() - 1);
            updateLogbook.setId(id);
            logbookService.updateById(updateLogbook);

            removeById(comment.getId());

            if(comment.getCommentType() == LogbookComment.COMMENT_TYPE_PICTURE){
                TransactionUtils.afterCommitAsyncExecute(executor, () -> {
                    List<String> delS3Keys = AttachmentUtil.getKeysByAttachments(Lists.newArrayList(comment.getContent()), objectMapper);
                    S3Utils.batchDeleteFile(region,bucketMap.get(S3BucketFunctionCons.LOGBOOK),delS3Keys);
                });
            }
        }

    }