# BudgetDatabaseDataLogFbServiceImpl.java

    package cloud.wconnect.rateshop.service.budgetdatabase.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.pojo.query.PageSizeQuery;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.rateshop.entity.budgetdatabase.BudgetDatabaseDataLogFb;
    import cloud.wconnect.rateshop.mapper.budgetdatabase.BudgetDatabaseDataLogFbMapper;
    import cloud.wconnect.rateshop.pojo.dto.budgetdatabase.EditLogDTO;
    import cloud.wconnect.rateshop.pojo.dto.budgetdatabase.UpdatedInfoDTO;
    import cloud.wconnect.rateshop.service.budgetdatabase.IBudgetDatabaseDataLogFbService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * <p>
     *  服务实现类
     * </p>
     *
     * @author yyt
     * @since 2025-11-10
     */
    @Service
    @DS("rate_shop")
    public class BudgetDatabaseDataLogFbServiceImpl extends ServiceImpl<BudgetDatabaseDataLogFbMapper, BudgetDatabaseDataLogFb> implements IBudgetDatabaseDataLogFbService {

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

        /**
         * 获取操作 log
         *
         * @param propertyId 资产 id
         * @param tabId      tab id
         * @param area       区域
         * @param query      查询条件
         * @return 操作 log
         * @author yyt
         * @date 2025/11/10
         **/
        @Override
        public ListPagedDTO<EditLogDTO> list(int propertyId, int tabId, int area, PageSizeQuery query) {
            Page<BudgetDatabaseDataLogFb> page = page(new Page<>(query.getPage(), query.getSize()),
                    new QueryWrapper<BudgetDatabaseDataLogFb>().lambda()
                            .eq(BudgetDatabaseDataLogFb::getPropertyId, propertyId)
                            .eq(BudgetDatabaseDataLogFb::getTabId, tabId)
                            .eq(BudgetDatabaseDataLogFb::getUpdatedArea, area)
                            .orderByDesc(BudgetDatabaseDataLogFb::getId));
            List<BudgetDatabaseDataLogFb> records = page.getRecords();
            if (CollectionUtils.isEmpty(records)) {
                return new ListPagedDTO<>();
            }

            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            Map<Integer, UserDTO> userById = userInternalService.getUsers(propertyDTO.getTenantId(), records.stream().map(BudgetDatabaseDataLogFb::getUpdatedBy).distinct().toList())
                    .stream().collect(Collectors.toMap(UserDTO::getId, v -> v));

            return new ListPagedDTO<>(page.getTotal(), beanMapper.mapList(records, EditLogDTO.class,
                    dto -> {
                        UserDTO userDTO = userById.get(dto.getUpdatedBy());
                        dto.setUpdatedByName(userDTO.getName());
                        dto.setAvatar(userDTO.getAvatar());
                    }));
        }

        /**
         * 获取最后修改信息
         *
         * @param tabId       tab id
         * @param updatedArea 更新区域
         * @return 最后修改信息
         * @author yyt
         * @date 2025/11/10
         **/
        @Override
        public UpdatedInfoDTO getLastLogDTO(int tabId, int updatedArea) {
            BudgetDatabaseDataLogFb dataLog = getLastLog(tabId, updatedArea);
            if (Objects.nonNull(dataLog)) {
                PropertyDTO propertyDTO = propertyI18nRedisService.get(dataLog.getPropertyId());
                UserDTO user = userInternalService.getOne(propertyDTO.getTenantId(), dataLog.getUpdatedBy());
                UpdatedInfoDTO updatedInfoDTO = beanMapper.map(dataLog, UpdatedInfoDTO.class);
                updatedInfoDTO.setUpdatedName(user.getName());
                return updatedInfoDTO;
            }
            return null;
        }

        /**
         * 查询最后一次修改记录
         *
         * @param tabId        tab id
         * @param updatedArea 更新区域
         * @return 修改记录
         * @author yyt
         * @date 2025/11/14
         **/
        @Override
        public BudgetDatabaseDataLogFb getLastLog(int tabId, int updatedArea) {
            return getOne(new QueryWrapper<BudgetDatabaseDataLogFb>().lambda()
                    .eq(BudgetDatabaseDataLogFb::getTabId, tabId)
                    .eq(BudgetDatabaseDataLogFb::getUpdatedArea, updatedArea)
                    .orderByDesc(BudgetDatabaseDataLogFb::getId)
                    .last("limit 1"));
        }

        /**
         * 保存 log
         *
         * @param propertyId  资产 id
         * @param tabId       tab id
         * @param userId      用户 id
         * @param updatedArea 更新区域
         * @author yyt
         * @date 2025/11/10
         **/
        @Override
        public void saveLog(int propertyId, Integer tabId, int userId, int updatedArea) {
            BudgetDatabaseDataLogFb dataLog = new BudgetDatabaseDataLogFb();
            dataLog.setPropertyId(propertyId);
            dataLog.setTabId(tabId);
            dataLog.setUpdatedArea(updatedArea);
            dataLog.setUpdatedBy(userId);
            dataLog.setUpdatedTime(DateTimeUtils.nowTimestamp());
            save(dataLog);
        }

    }