# ServiceRequestCenterCheckServiceImpl.java

    package cloud.wconnect.it.service.servicerequestcenter.impl;

    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.it.cons.servicerequestcenter.ServiceRequestCenterDepartmentEnum;
    import cloud.wconnect.it.cons.servicerequestcenter.ServiceRequestCenterIdentityCons;
    import cloud.wconnect.it.cons.servicerequestcenter.ServiceRequestCenterStatusEnum;
    import cloud.wconnect.it.cons.servicerequestcenter.ServiceRequestCenterTypeEnum;
    import cloud.wconnect.it.entity.servicerequestcenter.ServiceRequestCenter;
    import cloud.wconnect.it.pojo.dto.servicerequestcenter.PropertyBasicDTO;
    import cloud.wconnect.it.service.servicerequestcenter.IServiceRequestCenterCheckService;
    import cloud.wconnect.it.service.servicerequestcenter.IServiceRequestCenterPropertyService;
    import cloud.wconnect.it.service.servicerequestcenter.IServiceRequestCenterService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;

    /**
     * <p>
     *  服务实现类
     * </p>
     *
     * @author yyt
     * @since 2025-12-16
     */
    @Service
    @DS("it_manage")
    public class ServiceRequestCenterCheckServiceImpl implements IServiceRequestCenterCheckService {

        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private IServiceRequestCenterService serviceRequestCenterService;
        @Autowired
        private IServiceRequestCenterPropertyService serviceRequestCenterPropertyService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 校验用户有功能权限
         *
         * @param tenantId    租户 id
         * @param properties  选择资产
         * @param functionIds 功能id
         * @param userId      用户id
         * @author yyt
         * @date 2025/12/16
         */
        @Override
        public void checkHasFunctionPermission(Integer tenantId, String properties, String functionIds, int userId) {
            if (StringUtils.isBlank(functionIds) || StringUtils.isBlank(properties)) return;

            List<Integer> propertyIds = JsonUtils.convertStringToList(objectMapper, properties, PropertyBasicDTO.class)
                    .stream().map(PropertyBasicDTO::getId).toList();
            List<Integer> hasPermissionFunctionIds = userInternalService.listUserFunctionIds(tenantId, propertyIds, userId);
            if (Arrays.stream(functionIds.split(",")).anyMatch(functionId -> !hasPermissionFunctionIds.contains(Integer.parseInt(functionId)))) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "No permission for this function;functionIds:" + functionIds);
            }
        }

        /**
         * 校验资产是否属于当前用户
         *
         * @param currentUserPropertyIds 当前用户资产
         * @param properties             选择的资产
         * @author yyt
         * @date 2025/12/16
         */
        @Override
        public void checkPropertyBelongToUser(List<Integer> currentUserPropertyIds, String properties) {
            if (StringUtils.isEmpty(properties)) return;

            List<Integer> propertyIds = JsonUtils.convertStringToList(objectMapper, properties, PropertyBasicDTO.class)
                    .stream().map(PropertyBasicDTO::getId).toList();
            if (propertyIds.stream().anyMatch(item -> !currentUserPropertyIds.contains(item))) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property is not belong to user");
            }
        }

        /**
         * 校验是否存在
         *
         * @param id request id
         * @return request
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public ServiceRequestCenter checkExist(int id) {
            ServiceRequestCenter request = serviceRequestCenterService.getById(id);
            if (Objects.isNull(request)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_EXIST,
                        i18nMessageUtils.getErrorParamMapNotNeedTranslate("request"),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "request not found;id:" + id);
            }
            return request;
        }

        /**
         * 校验资产
         *
         * @param tenantId    租户 id
         * @param request     request
         * @param propertyIds 资产id
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public void checkProperty(int tenantId, ServiceRequestCenter request, List<Integer> propertyIds) {
            // 若财务类型，则检查request 是当前租户下的单据
            if(request.getType() == ServiceRequestCenterTypeEnum.ACCOUNT.getCode()){
                if(request.getTenantId() != tenantId){
                    throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                            BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the request is not belong to current tenant");
                }
            } else {
                // 若非财务类型，则检查 request 资产是否是当前用户有权限的资产
                boolean effective = false;
                List<Integer> requestPropertyIds = serviceRequestCenterPropertyService.listPropertyIds(request.getId());
                for (Integer requestPropertyId : requestPropertyIds) {
                    if (propertyIds.contains(requestPropertyId)) {
                        effective = true;
                        break;
                    }
                }
                if (!effective) {
                    throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                            BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "no permission for this property");
                }
            }
        }

        /**
         * 校验用户是否是员工
         *
         * @param tenantId       租户id
         * @param userId         用户id
         * @param departmentType 部门类型
         * @return true/false
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public boolean checkUserIsStaff(int tenantId, int userId, int departmentType) {
            UserDTO user = userInternalService.getOne(tenantId, userId);
            // 部门对称
            ServiceRequestCenterDepartmentEnum department = ServiceRequestCenterDepartmentEnum.getDepartment(user.getDepartment(), departmentType);
            if (Objects.isNull(department)) return false;

            // 职位对称
            return department.getStaffPositions().contains(user.getPosition());
        }

        /**
         * 校验用户是否是员工
         *
         * @param tenantId 租户id
         * @param userId   用户id
         * @return true/false
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public boolean checkUserIsStaff(int tenantId, int userId) {
            UserDTO user = userInternalService.getOne(tenantId, userId);
            // 部门对称
            ServiceRequestCenterDepartmentEnum department = ServiceRequestCenterDepartmentEnum.getDepartment(user.getDepartment());
            if (Objects.isNull(department)) return false;

            // 职位对称
            return department.getStaffPositions().contains(user.getPosition());
        }

        /**
         * 校验用户是否是管理员
         *
         * @param tenantId       租户id
         * @param userId         用户id
         * @param departmentType 部门类型
         * @return true/false
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public boolean checkUserIsManager(int tenantId, int userId, int departmentType) {
            UserDTO user = userInternalService.getOne(tenantId, userId);
            // 部门对称
            ServiceRequestCenterDepartmentEnum department = ServiceRequestCenterDepartmentEnum.getDepartment(user.getDepartment(), departmentType);
            if (Objects.isNull(department)) return false;

            // 职位对称
            return department.getManagerPositions().contains(user.getPosition());
        }

        /**
         * 校验用户是否是管理员
         *
         * @param tenantId 租户id
         * @param userId   用户id
         * @return true/false
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public boolean checkUserIsManager(int tenantId, int userId) {
            UserDTO user = userInternalService.getOne(tenantId, userId);
            // 部门对称
            ServiceRequestCenterDepartmentEnum department = ServiceRequestCenterDepartmentEnum.getDepartment(user.getDepartment());
            if (Objects.isNull(department)) return false;

            // 职位对称
            return department.getManagerPositions().contains(user.getPosition());
        }

        /**
         * 校验用户是否是当前部门下的员工 / 管理员
         *
         * @param tenantId       租户id
         * @param userId         用户id
         * @param departmentType 部门类型
         * @return 1-员工 2-管理员
         * @author yyt
         * @date 2025/12/17
         **/
        @Override
        public int checkUserIsStaffOrManager(int tenantId, int userId, int departmentType) {
            boolean isEmployee = checkUserIsStaff(tenantId, userId, departmentType);
            if (!isEmployee) {
                boolean isManger = checkUserIsManager(tenantId, userId, departmentType);
                if (!isManger) {
                    throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                            BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "you are not a staff or manager");
                }
            }
            return isEmployee ? ServiceRequestCenterIdentityCons.STAFF : ServiceRequestCenterIdentityCons.MANAGER;
        }

        /**
         * 校验用户是否是当前部门下的员工 / 管理员
         *
         * @param tenantId 租户id
         * @param userId   用户id
         * @return 1-员工 2-管理员
         * @author yyt
         * @date 2025/12/17
         **/
        @Override
        public int checkUserIsStaffOrManager(int tenantId, int userId) {
            boolean isEmployee = checkUserIsStaff(tenantId, userId);
            if (!isEmployee) {
                boolean isManger = checkUserIsManager(tenantId, userId);
                if (!isManger) {
                    throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                            BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "you are not a staff or manager");
                }
            }
            return isEmployee ? ServiceRequestCenterIdentityCons.STAFF : ServiceRequestCenterIdentityCons.MANAGER;
        }

        /**
         * 校验不能是指定状态
         *
         * @param requestStatus request 状态
         * @param targetStatus  指定状态
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public void checkStatusMustNotBe(Integer requestStatus, List<Integer> targetStatus) {
            List<String> i18nCodes = Lists.newArrayListWithExpectedSize(targetStatus.size());
            for (Integer status : targetStatus) {
                i18nCodes.add(ServiceRequestCenterStatusEnum.getI18nCode(status));
            }
            if (targetStatus.contains(requestStatus)) {
                throw new BadRequestException(CommonErrorI18nConstant.STATUS_CANNOT_BE,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(i18nCodes),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "status error");
            }
        }

        /**
         * 校验必须指定状态
         *
         * @param requestStatus request 状态
         * @param targetStatus  指定状态
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public void checkStatusMustBe(Integer requestStatus, Integer targetStatus) {
            if(!Objects.equals(requestStatus, targetStatus)){
                throw new BadRequestException(CommonErrorI18nConstant.STATUS_MUST_BE,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(ServiceRequestCenterStatusEnum.getI18nCode(targetStatus)),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "status error");
            }
        }

        /**
         * 校验必须指定状态
         *
         * @param requestStatus request 状态
         * @param targetStatus  指定状态
         * @author yyt
         * @date 2026/4/1
         */
        @Override
        public void checkStatusMustBe(Integer requestStatus, List<Integer> targetStatus) {
            List<String> i18nCodes = Lists.newArrayListWithExpectedSize(targetStatus.size());
            for (Integer status : targetStatus) {
                i18nCodes.add(ServiceRequestCenterStatusEnum.getI18nCode(status));
            }
            if(!targetStatus.contains(requestStatus)){
                throw new BadRequestException(CommonErrorI18nConstant.STATUS_MUST_BE,
                        i18nMessageUtils.getErrorParamMapNeedTranslate(i18nCodes),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "status error");
            }
        }

        /**
         * 校验用户是否是 request 的责任人
         *
         * @param dutyUserId 责任人id
         * @param userId     用户id
         * @author yyt
         * @date 2025/12/17
         */
        @Override
        public void checkUserIsDutyUser(Integer dutyUserId, int userId) {
            if (dutyUserId != userId) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "you are not the duty user");
            }
        }

        /**
         * 校验资产是否属于当前用户
         *
         * @param selectPropertyIds        选择的资产
         * @param hasPermissionPropertyIds 当前用户资产
         * @author yyt
         * @date 2026/1/8
         */
        @Override
        public void checkPropertyIds(List<Integer> selectPropertyIds, List<Integer> hasPermissionPropertyIds) {
            if (CollectionUtils.isEmpty(selectPropertyIds)) {
                throw new BadRequestException(CommonErrorI18nConstant.CANNOT_EMPTY,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the propertyIds is empty");
            }
            if (selectPropertyIds.stream().anyMatch(propertyId -> !hasPermissionPropertyIds.contains(propertyId))) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "No access to this property");
            }
        }

    }