# ScheduleDepartmentPermissionConfigServiceImpl.java

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

    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.cons.DataPermissionConfigConstant;
    import cloud.wconnect.commonlib.cons.DataPermissionStatusEnum;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.RoleDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.pojo.dto.UsergroupDTO;
    import cloud.wconnect.commonlib.pojo.dto.result.ResultDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.service.DataPermissionConfigInternalService;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.commonlib.util.TransactionUtils;
    import cloud.wconnect.workperformance.cons.schedule.ScheduleErrorFiledCons;
    import cloud.wconnect.workperformance.entity.schedule.ScheduleDepartment;
    import cloud.wconnect.workperformance.entity.schedule.ScheduleDepartmentPermissionConfig;
    import cloud.wconnect.workperformance.mapper.schedule.ScheduleDepartmentPermissionConfigMapper;
    import cloud.wconnect.workperformance.pojo.dto.schedule.UpdateDepartmentPermissionConfigDTO;
    import cloud.wconnect.workperformance.pojo.dto.schedule.UserDepartmentPermissionDTO;
    import cloud.wconnect.workperformance.service.schedule.IScheduleDepartmentPermissionConfigService;
    import cloud.wconnect.workperformance.service.schedule.IScheduleDepartmentService;
    import cloud.wconnect.workperformance.service.schedule.IScheduleEmailConfigService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    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.concurrent.Executor;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 部门权限配置 服务实现类
     * </p>
     *
     * @author yyt
     * @since 2023-06-28
     */
    @Service
    @DS("work_performance")
    public class ScheduleDepartmentPermissionConfigServiceImpl extends ServiceImpl<ScheduleDepartmentPermissionConfigMapper, ScheduleDepartmentPermissionConfig> implements IScheduleDepartmentPermissionConfigService {

        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private IScheduleEmailConfigService scheduleEmailConfigService;
        @Autowired
        private DataPermissionConfigInternalService dataPermissionConfigInternalService;
        @Lazy
        @Autowired
        private IScheduleDepartmentService scheduleDepartmentService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;
        @Autowired
        private Executor executor;

        /**
         * 获取用户拥有 有效状态下的 数据权限的配置信息
         *
         * @param tenantId     租户
         * @param propertyId   资产
         * @param userId       用户
         * @param departmentId 部门
         * @return 权限的配置信息
         * @author yyt
         * @date 2023/6/29
         */
        @Override
        public List<ScheduleDepartmentPermissionConfig> getHasAccessPermissionConfigs(Integer tenantId, Integer propertyId, int userId,
                                                                                      Integer departmentId) {
            UserDTO userDTO = userInternalService.getOneByProperty(tenantId, propertyId, userId);

            // 用户拥有的角色 id
            List<Integer> roleIds = userDTO.getRoles().stream()
                    .map(RoleDTO::getId).collect(Collectors.toList());

            // 用户拥有的用户组 id
            List<Integer> userGroupIds = userDTO.getUserGroups().stream()
                    .map(UsergroupDTO::getId).collect(Collectors.toList());

            LambdaQueryWrapper<ScheduleDepartmentPermissionConfig> queryWrapper = new QueryWrapper<ScheduleDepartmentPermissionConfig>().lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getPropertyId, propertyId)
                    .eq(ScheduleDepartmentPermissionConfig::getStatus, DataPermissionConfigConstant.STATUS_NORMAL)
                    .and(query -> query
                            .nested(q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, userId))
                            .or(CollectionUtils.isNotEmpty(roleIds), q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_ROLE)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, roleIds))
                            .or(CollectionUtils.isNotEmpty(userGroupIds), q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER_GROUP)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, userGroupIds))
                    );

            if (Objects.nonNull(departmentId)) {
                queryWrapper.eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId);
            }

            return list(queryWrapper);
        }

        /**
         * 获取用户数据权限的配置信息
         *
         * @param tenantId     租户
         * @param propertyId   资产
         * @param userId       用户
         * @param departmentId 部门
         * @return 权限的配置信息
         * @author yyt
         * @date 2023/6/29
         */
        @Override
        public List<ScheduleDepartmentPermissionConfig> getAllPermissionConfigs(Integer tenantId, Integer propertyId, int userId,
                                                                                Integer departmentId) {
            UserDTO userDTO = userInternalService.getOneByProperty(tenantId, propertyId, userId);

            // 用户拥有的角色 id
            List<Integer> roleIds = userDTO.getRoles().stream()
                    .map(RoleDTO::getId).collect(Collectors.toList());

            // 用户拥有的用户组 id
            List<Integer> userGroupIds = userDTO.getUserGroups().stream()
                    .map(UsergroupDTO::getId).collect(Collectors.toList());

            /**
             * 查询两种类型的数据，目的是防止重复申请
             * 1、类型是 角色、用户组，有效状态下的数据
             * 2、类型是用户的数据，不分状态
             */
            LambdaQueryWrapper<ScheduleDepartmentPermissionConfig> queryWrapper = new QueryWrapper<ScheduleDepartmentPermissionConfig>().lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getPropertyId, propertyId)
                    .and(query -> query
                            .nested(q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, userId))
                            .or(CollectionUtils.isNotEmpty(roleIds), q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_ROLE)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, roleIds)
                                    .eq(ScheduleDepartmentPermissionConfig::getStatus, DataPermissionConfigConstant.STATUS_NORMAL))
                            .or(CollectionUtils.isNotEmpty(userGroupIds), q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER_GROUP)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, userGroupIds)
                                    .eq(ScheduleDepartmentPermissionConfig::getStatus, DataPermissionConfigConstant.STATUS_NORMAL))
                    );

            if (Objects.nonNull(departmentId)) {
                queryWrapper.eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId);
            }

            return list(queryWrapper);
        }

        /**
         * 用户申请部门权限
         *
         * @param scheduleDepartment      部门
         * @param propertyDTO             资产
         * @param userId                  用户 id
         * @param departmentPermissionDTO 申请权限信息
         * @return cloud.wconnect.commonlib.pojo.dto.result.ResultDTO<java.lang.Void>
         * @author yyt
         * @date 2023/6/29
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public ResultDTO<Void> apply(ScheduleDepartment scheduleDepartment, PropertyDTO propertyDTO, int userId, UserDepartmentPermissionDTO departmentPermissionDTO) {
            Integer tenantId = propertyDTO.getTenantId();
            Integer propertyId = propertyDTO.getId();
            Integer departmentId = scheduleDepartment.getId();

            //申请的权限类型
            int applyPermissionType;
            String permissionTypeI18nCode;
            if (Objects.nonNull(departmentPermissionDTO.getRead())) {
                applyPermissionType = DataPermissionConfigConstant.PERMISSION_TYPE_READY;
                permissionTypeI18nCode = DataPermissionConfigConstant.DATA_PERMISSION_READ_ONLY;
            } else {
                applyPermissionType = DataPermissionConfigConstant.PERMISSION_TYPE_WRITE;
                permissionTypeI18nCode = DataPermissionConfigConstant.DATA_PERMISSION_READ_WRITE;
            }

            //错误描述的参数集合
            LinkedHashMap<String, Boolean> errorParamMap = new LinkedHashMap<>();
            errorParamMap.put(scheduleDepartment.getName(), false);
            errorParamMap.put(permissionTypeI18nCode, true);
            //不同语言下，错误描述的参数集合
            Map<String, List<Object>> errorParamMapByAllLanguage = i18nMessageUtils.getErrorParamMap(errorParamMap);

            //校验用户是否拥有指定部门的指定权限
            if (checkUserHasPermission(tenantId, propertyId, departmentId, userId, applyPermissionType)) {
                return ResultDTO.fail(BaseErrorCodeEnum.ALREADY_HAVE_DATA_PERMISSION.getCode(),
                        i18nMessageUtils.getAllLanguageMsg(ScheduleErrorFiledCons.SCHEDULE_ALREADY_HAVE_DATA_PERMISSION, errorParamMapByAllLanguage));
            }

            //校验用户是否重复申请
            long applyingPermissionConfig = count(new QueryWrapper<ScheduleDepartmentPermissionConfig>().lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getPropertyId, propertyId)
                    .eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId)
                    .eq(ScheduleDepartmentPermissionConfig::getTargetId, userId)
                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER)
                    .eq(ScheduleDepartmentPermissionConfig::getPermissionType, applyPermissionType)
                    .eq(ScheduleDepartmentPermissionConfig::getStatus, DataPermissionConfigConstant.STATUS_WAIT_PASS));
            if (applyingPermissionConfig > 0) {
                return ResultDTO.dataValidationError(i18nMessageUtils.getAllLanguageMsg(ScheduleErrorFiledCons.SCHEDULE_ALREADY_APPLY_DATA_PERMISSION,
                        errorParamMapByAllLanguage));
            }

            // 新增权限
            ScheduleDepartmentPermissionConfig scheduleDepartmentPermissionConfig = new ScheduleDepartmentPermissionConfig()
                    .setPropertyId(propertyId).setDepartmentId(departmentId).setPermissionType(applyPermissionType)
                    .setTargetType(DataPermissionConfigConstant.IDENTITY_TYPE_USER).setTargetId(userId)
                    .setStatus(DataPermissionConfigConstant.STATUS_WAIT_PASS).setCreatedBy(userId)
                    .setCreatedTime(DateTimeUtils.nowTimestamp());
            baseMapper.insert(scheduleDepartmentPermissionConfig);

            // 发送申请数据权限通知
            TransactionUtils.afterCommitAsyncExecute(executor, () -> {
                // 发送申请部门权限邮件
                scheduleEmailConfigService.sendApplyEmail(propertyDTO, scheduleDepartment, Objects.nonNull(departmentPermissionDTO.getWrite()), userId);
            });
            return ResultDTO.success();
        }

        /**
         * 校验用户是否拥有指定部门的指定权限
         *
         * @param tenantId       租户id
         * @param propertyId     资产id
         * @param departmentId   部门id
         * @param userId         用户
         * @param permissionType 权限类型，读或写
         * @return boolean
         * @author lichen
         * @date 2025/11/12
         */
        private boolean checkUserHasPermission(Integer tenantId, Integer propertyId, Integer departmentId, int userId, Integer permissionType) {
            UserDTO userDTO = userInternalService.getOneByProperty(tenantId, propertyId, userId);

            // 用户拥有的角色 id
            List<Integer> roleIds = userDTO.getRoles().stream()
                    .map(RoleDTO::getId).collect(Collectors.toList());

            // 用户拥有的用户组 id
            List<Integer> userGroupIds = userDTO.getUserGroups().stream()
                    .map(UsergroupDTO::getId).collect(Collectors.toList());

            // 查询权限配置
            LambdaQueryWrapper<ScheduleDepartmentPermissionConfig> queryWrapper = new QueryWrapper<ScheduleDepartmentPermissionConfig>().lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getPropertyId, propertyId)
                    .eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId)
                    .eq(ScheduleDepartmentPermissionConfig::getStatus, DataPermissionConfigConstant.STATUS_NORMAL)
                    .and(query -> query
                            .nested(q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, userId))
                            .or(CollectionUtils.isNotEmpty(roleIds), q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_ROLE)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, roleIds))
                            .or(CollectionUtils.isNotEmpty(userGroupIds), q -> q
                                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, DataPermissionConfigConstant.IDENTITY_TYPE_USER_GROUP)
                                    .in(ScheduleDepartmentPermissionConfig::getTargetId, userGroupIds))
                    );

            if (Objects.nonNull(departmentId)) {
                queryWrapper.eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId);
            }

            List<ScheduleDepartmentPermissionConfig> permissionConfigs = list(queryWrapper);
            // 没有权限
            if (CollectionUtils.isEmpty(permissionConfigs)) return false;

            if (permissionType == DataPermissionConfigConstant.PERMISSION_TYPE_READY) {
                // 只要有任意一个权限，则返回 true
                return CollectionUtils.isNotEmpty(permissionConfigs);
            } else {
                // 判断是否存在写权限
                return permissionConfigs.stream().anyMatch(item -> item.getPermissionType() == DataPermissionConfigConstant.PERMISSION_TYPE_WRITE);
            }
        }

        /**
         * 检查部门权限配置存在
         *
         * @param propertyId     资产 id
         * @param departmentId   部门 id
         * @param permissionType 权限类型（1：可读，2：可改）
         * @param targetType     目标类型（0：角色，1：用户组，2：用户）
         * @param targetId       目标 id
         * @return true:存在，false：不存在
         * @author yyt
         * @date 2023/7/1
         */
        @Override
        public boolean checkPermissionConfigExist(Integer propertyId, Integer departmentId, Integer permissionType,
                                                  Integer targetType, Integer targetId) {
            return getOne(new QueryWrapper<ScheduleDepartmentPermissionConfig>().lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getPropertyId, propertyId)
                    .eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId)
                    .eq(ScheduleDepartmentPermissionConfig::getPermissionType, permissionType)
                    .eq(ScheduleDepartmentPermissionConfig::getTargetType, targetType)
                    .eq(ScheduleDepartmentPermissionConfig::getTargetId, targetId)) != null;
        }

        /**
         * 新增部门权限配置
         *
         * @param propertyId          资产 id
         * @param id                  部门 id
         * @param permissionConfigDTO 权限配置信息
         * @param userId              操作人
         * @author yyt
         * @date 2023/7/1
         */
        @Override
        public void savePermissionConfig(Integer propertyId, int id, UpdateDepartmentPermissionConfigDTO permissionConfigDTO, int userId) {
            // 验重
            boolean exist = checkPermissionConfigExist(propertyId, id, permissionConfigDTO.getPermissionType(),
                    permissionConfigDTO.getTargetType(), permissionConfigDTO.getTargetId());
            if (exist) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_EXISTED, BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "Failed to save existing data.");
            }

            Integer tenantId = propertyI18nRedisService.get(propertyId).getTenantId();
            // 校验状态
            List<Integer> permissionApiIds = permissionConfigDTO.getPermissionType() == DataPermissionConfigConstant.PERMISSION_TYPE_READY ?
                    DataPermissionConfigConstant.SCHEDULE_READ_API_ID : DataPermissionConfigConstant.SCHEDULE_WRITE_API_ID;
            boolean hasPermission = dataPermissionConfigInternalService.verifyDataPermissionStatus(tenantId,
                    propertyId, permissionApiIds, permissionConfigDTO.getTargetId(), permissionConfigDTO.getTargetType());
            if (!hasPermission) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_PERMISSION_INVALID,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "The data permission is invalid");
            }

            save(new ScheduleDepartmentPermissionConfig().setPropertyId(propertyId).setDepartmentId(id)
                    .setPermissionType(permissionConfigDTO.getPermissionType()).setTargetType(permissionConfigDTO.getTargetType())
                    .setTargetId(permissionConfigDTO.getTargetId())
                    .setStatus(DataPermissionConfigConstant.STATUS_NORMAL)
                    .setCreatedBy(userId).setCreatedTime(DateTimeUtils.nowTimestamp()));
        }

        /**
         * 校验权限配置存在
         *
         * @param id           配置 id
         * @param departmentId 部门 id
         * @return 权限配置
         * @author yyt
         * @date 2023/7/1
         */
        @Override
        public ScheduleDepartmentPermissionConfig checkExist(int id, int departmentId) {
            ScheduleDepartmentPermissionConfig config = getOne(new QueryWrapper<ScheduleDepartmentPermissionConfig>().lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getId, id)
                    .eq(ScheduleDepartmentPermissionConfig::getDepartmentId, departmentId));
            if (Objects.isNull(config)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the scheduleDepartmentPermissionConfig is not found;id" + id);
            }
            return config;
        }

        /**
         * 允许用户申请的部门权限
         *
         * @param config      权限配置
         * @param propertyDTO 资产
         * @author yyt
         * @date 2023/7/3
         */
        @Override
        public void passPermissionConfig(ScheduleDepartmentPermissionConfig config, PropertyDTO propertyDTO) {
            if (config.getStatus() != DataPermissionConfigConstant.STATUS_WAIT_PASS) {
                throw new BadRequestException(CommonErrorI18nConstant.STATUS_MUST_BE,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(DataPermissionStatusEnum.WAITING_FOR_APPROVAL.getI18nCode()),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "the scheduleDepartmentPermissionConfig status is not wait pass;configId:" + config.getId());
            }

            // 校验当前用后所属角色是否有权限，有权限则状态标记有效，否则标记无效
            List<Integer> permissionApiIds = config.getPermissionType() == DataPermissionConfigConstant.PERMISSION_TYPE_READY ?
                    DataPermissionConfigConstant.SCHEDULE_READ_API_ID : DataPermissionConfigConstant.SCHEDULE_WRITE_API_ID;
            boolean hasPermission = dataPermissionConfigInternalService.verifyDataPermissionStatus(propertyDTO.getTenantId(),
                    config.getPropertyId(), permissionApiIds, config.getTargetId(), config.getTargetType());

            ScheduleDepartmentPermissionConfig updateContent = new ScheduleDepartmentPermissionConfig();
            updateContent.setStatus(hasPermission ? DataPermissionConfigConstant.STATUS_NORMAL : DataPermissionConfigConstant.STATUS_INVALID);
            updateContent.setId(config.getId());
            updateById(updateContent);

            config.setStatus(updateContent.getStatus());

            scheduleEmailConfigService.sendPassEmail(config, propertyDTO);
        }

        /**
         * 刷新权限配置状态
         *
         * @param propertyId 资产 id
         * @author yyt
         * @date 2023/7/3
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void flushPermissionConfigStatus(Integer propertyId) {
            // 查询状态是 有效、无效的 权限配置信息
            List<ScheduleDepartmentPermissionConfig> permissionConfigs = list(new QueryWrapper<ScheduleDepartmentPermissionConfig>()
                    .lambda()
                    .eq(ScheduleDepartmentPermissionConfig::getPropertyId, propertyId)
                    .ne(ScheduleDepartmentPermissionConfig::getStatus, DataPermissionConfigConstant.STATUS_WAIT_PASS));
            if (permissionConfigs.isEmpty()) {
                return;
            }

            Integer tenantId = propertyI18nRedisService.get(propertyId).getTenantId();

            List<ScheduleDepartmentPermissionConfig> updateStatusList = Lists.newArrayListWithExpectedSize(permissionConfigs.size());

            Map<Integer, List<ScheduleDepartmentPermissionConfig>> configsByPermissionType = permissionConfigs.stream()
                    .collect(Collectors.groupingBy(ScheduleDepartmentPermissionConfig::getPermissionType));

            configsByPermissionType.forEach((permissionType, configs) -> {
                // 校验权限配置中的配置信息（角色、用户组、用户）当前时刻是否是有效状态
                Map<Integer, Set<Integer>> targetIdsByTargetType = configs.stream()
                        .collect(Collectors.groupingBy(ScheduleDepartmentPermissionConfig::getTargetType,
                                Collectors.mapping(ScheduleDepartmentPermissionConfig::getTargetId, Collectors.toSet())));
                List<Integer> apiIds = permissionType == DataPermissionConfigConstant.PERMISSION_TYPE_READY ?
                        DataPermissionConfigConstant.SCHEDULE_READ_API_ID : DataPermissionConfigConstant.SCHEDULE_WRITE_API_ID;
                Map<Integer, Map<Integer, Boolean>> targetIdHasPermissionByTargetType =
                        dataPermissionConfigInternalService.checkContainsApi(tenantId, propertyId, targetIdsByTargetType, apiIds);

                for (ScheduleDepartmentPermissionConfig config : configs) {
                    if (targetIdHasPermissionByTargetType.get(config.getTargetType()) != null) {
                        Boolean hasPermission = targetIdHasPermissionByTargetType.get(config.getTargetType())
                                .getOrDefault(config.getTargetId(), Boolean.FALSE);
                        int newStatus = hasPermission ? DataPermissionConfigConstant.STATUS_NORMAL : DataPermissionConfigConstant.STATUS_INVALID;
                        if (config.getStatus() != newStatus) {
                            ScheduleDepartmentPermissionConfig updateConfig = new ScheduleDepartmentPermissionConfig();
                            updateConfig.setId(config.getId());
                            updateConfig.setStatus(newStatus);
                            updateStatusList.add(updateConfig);
                        }
                    }
                }
            });

            if (CollectionUtils.isNotEmpty(updateStatusList)) {
                updateBatchById(updateStatusList);
            }
        }

        /**
         * 获取用户部门权限
         *
         * @param propertyId 资产 id
         * @param userId     操作人
         * @return 用户部门权限
         * @author yyt
         * @date 2025/12/31
         */
        @Override
        public List<UserDepartmentPermissionDTO> listUserDepartmentPermission(Integer propertyId, int userId) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            Integer tenantId = propertyDTO.getTenantId();
            Map<Integer, List<ScheduleDepartmentPermissionConfig>> permissionConfigsByDepartmentId =
                    getAllPermissionConfigs(tenantId, propertyId, userId, null)
                            .stream().collect(Collectors.groupingBy(ScheduleDepartmentPermissionConfig::getDepartmentId));

            List<UserDepartmentPermissionDTO> userDepartmentPermissionDTOs =
                    Lists.newArrayListWithExpectedSize(permissionConfigsByDepartmentId.size());

            Map<Integer, String> departmentNameById = Collections.emptyMap();
            if (!permissionConfigsByDepartmentId.isEmpty()) {
                departmentNameById = scheduleDepartmentService.listByIds(permissionConfigsByDepartmentId.keySet())
                        .stream().collect(Collectors.toMap(ScheduleDepartment::getId, ScheduleDepartment::getName));
            }

            Map<Integer, String> finalDepartmentNameById = departmentNameById;
            permissionConfigsByDepartmentId.forEach((id, configs) ->
                    userDepartmentPermissionDTOs.add(new UserDepartmentPermissionDTO(id, finalDepartmentNameById.get(id), true,
                            configs.stream().anyMatch(item -> item.getPermissionType() == DataPermissionConfigConstant.PERMISSION_TYPE_WRITE))));

            return userDepartmentPermissionDTOs;
        }

        /**
         * 删除部门权限配置
         *
         * @param configId 配置 id
         * @author yyt
         * @date 2025/12/31
         */
        @Override
        public void delete(int configId) {
            removeById(configId);
        }

    }