# WalkRoomRequestLogServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.service.PropertyInternalService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.frontoffice.entity.walkroomrequest.WalkRoomDateinOther;
    import cloud.wconnect.frontoffice.entity.walkroomrequest.WalkRoomRequest;
    import cloud.wconnect.frontoffice.entity.walkroomrequest.WalkRoomRequestLog;
    import cloud.wconnect.frontoffice.mapper.walkroomrequest.WalkRoomRequestLogMapper;
    import cloud.wconnect.frontoffice.pojo.dto.walkroomrequest.WalkRoomLogContentDTO;
    import cloud.wconnect.frontoffice.pojo.dto.walkroomrequest.WalkRoomLogDTO;
    import cloud.wconnect.frontoffice.service.walkroomrequest.IWalkRoomRequestLogService;
    import cloud.wconnect.frontoffice.service.walkroomrequest.IWalkRoomRequestService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    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.context.annotation.Lazy;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.*;
    import java.util.stream.Collectors;

    /**
     * <p>
     * Walk Room Requests 操作日志 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2023-07-08
     */
    @Service
    @DS("logbook")
    public class WalkRoomRequestLogServiceImpl extends ServiceImpl<WalkRoomRequestLogMapper, WalkRoomRequestLog> implements IWalkRoomRequestLogService {

        @Autowired
        private BeanMapper beanMapper;
        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private PropertyInternalService propertyInternalService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        @Lazy
        private IWalkRoomRequestService walkRoomRequestService;

        /**
         * 保存新增walkRoom的日志
         *
         * @param insertWalkRoomRequest 新增的walkRoomRequest数据
         * @param loginUserId           登录用户id
         * @return void
         * @author lichen
         * @date 2023/7/13
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveLogForInsert(WalkRoomRequest insertWalkRoomRequest, int loginUserId) {
            WalkRoomLogContentDTO logContentDTO = beanMapper.map(insertWalkRoomRequest, WalkRoomLogContentDTO.class, logContentDto -> {
                logContentDto.setUpdatedBy(0);
                logContentDto.setUpdatedTime(0L);
                //设置操作类型
                logContentDto.setType(WalkRoomLogContentDTO.ADD);
            });
            //转化为json字符串
            String content = JsonUtils.convertObjToString(objectMapper, logContentDTO);

            //构建log对象
            WalkRoomRequestLog walkRoomRequestLog = new WalkRoomRequestLog();
            walkRoomRequestLog.setWalkRoomReqId(insertWalkRoomRequest.getId());
            walkRoomRequestLog.setContent(content);
            walkRoomRequestLog.setCreatedBy(loginUserId);
            walkRoomRequestLog.setCreatedTime(DateTimeUtils.nowTimestamp());
            //新增
            save(walkRoomRequestLog);
        }

        /**
         * 保存修改walkRoom的日志
         *
         * @param reqId       walk room的主键id
         * @param loginUserId 登录用户id
         * @return void
         * @author lichen
         * @date 2023/7/13
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveLogForUpdate(Long reqId, int loginUserId) {
            //查询walkRoom数据
            WalkRoomRequest walkRoomRequest = walkRoomRequestService.getById(reqId);
            //WalkRoomRequest -> WalkRoomLogContentDTO
            WalkRoomLogContentDTO logContentDTO = beanMapper.map(walkRoomRequest, WalkRoomLogContentDTO.class);
            //设置操作类型
            logContentDTO.setType(WalkRoomLogContentDTO.UPDATE);

            //转化为json字符串
            String content = JsonUtils.convertObjToString(objectMapper, logContentDTO);

            //构建log对象
            WalkRoomRequestLog walkRoomRequestLog = new WalkRoomRequestLog();
            walkRoomRequestLog.setWalkRoomReqId(reqId);
            walkRoomRequestLog.setContent(content);
            walkRoomRequestLog.setCreatedBy(loginUserId);
            walkRoomRequestLog.setCreatedTime(DateTimeUtils.nowTimestamp());
            //新增
            save(walkRoomRequestLog);
        }

        /**
         * 查询walkRoom的日志
         *
         * @param tenantId 租户id
         * @param reqId    walk room主键id
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.dto.walkroom.WalkRoomLogDTO>
         * @author lichen
         * @date 2023/7/13
         */
        @Override
        public List<WalkRoomLogDTO> listByReqId(Integer tenantId, Long reqId) {
            //查询walkRoom的日志
            List<WalkRoomRequestLog> logs = list(new LambdaQueryWrapper<WalkRoomRequestLog>().eq(WalkRoomRequestLog::getWalkRoomReqId, reqId));
            if (CollectionUtils.isEmpty(logs)) return Collections.emptyList();

            Set<Integer> userIdSet = new HashSet<>();
            Set<Integer> propertyIdSet = new HashSet<>();

            List<WalkRoomLogDTO> logVOS = Lists.newArrayListWithCapacity(logs.size());
            //循环logs
            for (WalkRoomRequestLog log : logs) {
                WalkRoomLogDTO walkRoomLogDTO = new WalkRoomLogDTO();
                walkRoomLogDTO.setId(log.getId());

                //设置日志内容
                WalkRoomLogContentDTO contentDTO = JsonUtils.convertStringToObject(objectMapper, log.getContent(), WalkRoomLogContentDTO.class);
                walkRoomLogDTO.setContent(contentDTO);

                //设置操作人信息
                if (Objects.nonNull(contentDTO.getType())) {
                    if (contentDTO.getType() == WalkRoomLogContentDTO.ADD) {//新增
                        walkRoomLogDTO.setOperatorType(WalkRoomLogContentDTO.ADD);
                        walkRoomLogDTO.setOperatorId(contentDTO.getCreatedBy());
                        walkRoomLogDTO.setOperatorTime(contentDTO.getCreatedTime());
                    } else if (contentDTO.getType() == WalkRoomLogContentDTO.UPDATE) {//修改
                        walkRoomLogDTO.setOperatorType(WalkRoomLogContentDTO.UPDATE);
                        walkRoomLogDTO.setOperatorId(contentDTO.getUpdatedBy());
                        walkRoomLogDTO.setOperatorTime(contentDTO.getUpdatedTime());
                    } else {//确认
                        walkRoomLogDTO.setOperatorType(WalkRoomLogContentDTO.CONFIRM);
                        walkRoomLogDTO.setOperatorId(contentDTO.getConfirmUserId());
                        walkRoomLogDTO.setOperatorTime(contentDTO.getConfirmTime());
                    }
                } else {//兼容存量type为空的数据
                    if (Objects.nonNull(contentDTO.getUpdatedBy()) && contentDTO.getUpdatedBy() > 0) {
                        walkRoomLogDTO.setOperatorType(WalkRoomLogContentDTO.UPDATE);
                        walkRoomLogDTO.setOperatorId(contentDTO.getUpdatedBy());
                        walkRoomLogDTO.setOperatorTime(contentDTO.getUpdatedTime());
                    } else {
                        walkRoomLogDTO.setOperatorType(WalkRoomLogContentDTO.ADD);
                        walkRoomLogDTO.setOperatorId(contentDTO.getCreatedBy());
                        walkRoomLogDTO.setOperatorTime(contentDTO.getCreatedTime());
                    }
                }

                logVOS.add(walkRoomLogDTO);

                //收集操作人集合
                userIdSet.add(walkRoomLogDTO.getOperatorId());
                userIdSet.add(contentDTO.getAgentUserId());
                //收集资产id集合
                propertyIdSet.add(contentDTO.getFromPropertyId());
                propertyIdSet.add(contentDTO.getToPropertyId());
            }

            //查询资产集合
            Map<Integer, String> propertyId2PropertyName = propertyInternalService.listPropertyName(propertyIdSet);
            //查询用户集合
            List<UserDTO> users = userInternalService.getUsers(tenantId, userIdSet);
            //用户姓名集合
            Map<Integer, String> userId2UserName = users.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO::getName));
            //用户头像集合
            Map<Integer, String> userId2Avatar = users.stream().filter(item -> Objects.nonNull(item.getAvatar()))
                    .collect(Collectors.toMap(UserDTO::getId, UserDTO::getAvatar));

            logVOS.forEach(log -> {
                //设置操作人姓名
                log.setOperatorName(userId2UserName.get(log.getOperatorId()));
                //设置操作人头像
                log.setAvatar(userId2Avatar.get(log.getOperatorId()));

                WalkRoomLogContentDTO content = log.getContent();
                //设置操作人姓名
                content.setAgentUserName(userId2UserName.get(content.getAgentUserId()));
                //设置资产名称
                content.setFromPropertyName(propertyId2PropertyName.get(content.getFromPropertyId()));
                content.setToPropertyName(propertyId2PropertyName.get(content.getToPropertyId()));
            });

            //根据操作时间、日志id倒序排列
            logVOS.sort(Comparator.comparing(WalkRoomLogDTO::getOperatorTime).thenComparing(WalkRoomLogDTO::getId).reversed());
            return logVOS;
        }

        /**
         * 保存log
         *
         * @param walkRoomRequest walk room数据
         * @param dateinOther     入住明细记录
         * @param loginUserId     登录用户id
         * @return void
         * @author lichen
         * @date 2023/7/20
         */
        @Override
        public void saveConfirmLog(WalkRoomRequest walkRoomRequest, WalkRoomDateinOther dateinOther, int loginUserId) {
            //入住记录变更后，更新walk room request的更新人和更新时间
            walkRoomRequest.setUpdatedBy(loginUserId);
            walkRoomRequest.setUpdatedTime(DateTimeUtils.nowTimestamp());

            //WalkRoomRequest -> WalkRoomLogContentDTO
            WalkRoomLogContentDTO logContentDTO = beanMapper.map(walkRoomRequest, WalkRoomLogContentDTO.class, dto -> {
                //设置入住记录相关信息
                dto.setCrsNumber(dateinOther.getCrsNumber());
                dto.setStatus(dateinOther.getStatus());
                dto.setDateinComment(dateinOther.getComment());
                dto.setConfirmUserId(dateinOther.getUpdateBy());
                dto.setConfirmTime(dateinOther.getUpdateTime());
                //设置操作类型
                dto.setType(WalkRoomLogContentDTO.CONFIRM);
            });

            //转化为json字符串
            String content = JsonUtils.convertObjToString(objectMapper, logContentDTO);

            //构建log对象
            WalkRoomRequestLog walkRoomRequestLog = new WalkRoomRequestLog();
            walkRoomRequestLog.setWalkRoomReqId(walkRoomRequest.getId());
            walkRoomRequestLog.setContent(content);
            walkRoomRequestLog.setCreatedBy(loginUserId);
            walkRoomRequestLog.setCreatedTime(DateTimeUtils.nowTimestamp());
            //新增
            save(walkRoomRequestLog);
        }
    }