package com.ruoyi.account.service; import com.ruoyi.chargingPile.api.dto.GetSiteListDTO; import com.ruoyi.chargingPile.api.feignClient.SiteClient; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.order.api.feignClient.ChargingOrderClient; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysUserClient; import com.ruoyi.system.api.model.LoginUser; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * 合作商后台用户数据范围及只读权限控制。 */ @Slf4j @Service public class PartnerAppUserAccessService { private static final Integer PARTNER_ROLE_TYPE = 2; private static final Integer COMPANY_ROLE_TYPE = 5; private static final Long IMPOSSIBLE_USER_ID = -1L; @Resource private TokenService tokenService; @Resource private SysUserClient sysUserClient; @Resource private SiteClient siteClient; @Resource private ChargingOrderClient chargingOrderClient; /** * 非合作商返回null,合作商返回允许查看的用户ID;空权限始终返回不可命中的ID。 */ public List getVisibleUserIdsForCurrentPartner() { SysUser sysUser = getCurrentSysUser(); if (!isPartner(sysUser)) { return null; } if (sysUser.getObjectId() == null || sysUser.getUserId() == null) { return impossibleUserIds(); } R> siteResult = siteClient.getSiteListByUserId(sysUser.getUserId()); if (siteResult == null || !R.isSuccess(siteResult) || siteResult.getData() == null) { return impossibleUserIds(); } List siteIds = siteResult.getData().stream() .filter(Objects::nonNull) .map(GetSiteListDTO::getId) .filter(Objects::nonNull) .filter(siteId -> siteId > 0) .distinct() .sorted() .collect(Collectors.toList()); if (siteIds.isEmpty()) { return impossibleUserIds(); } R> userResult = chargingOrderClient.getAppUserIdsBySiteIds(siteIds); if (userResult == null || !R.isSuccess(userResult) || userResult.getData() == null) { log.warn("查询合作商充电用户失败,partnerId={}", sysUser.getObjectId()); return impossibleUserIds(); } List userIds = userResult.getData().stream() .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); return userIds.isEmpty() ? impossibleUserIds() : userIds; } public void assertUserVisible(Long userId) { List visibleUserIds = getVisibleUserIdsForCurrentPartner(); if (visibleUserIds != null && (userId == null || !visibleUserIds.contains(userId))) { throw new ServiceException("无权查看该用户信息"); } } public void assertUsersVisible(Collection userIds) { List visibleUserIds = getVisibleUserIdsForCurrentPartner(); if (visibleUserIds == null) { return; } if (userIds == null || userIds.isEmpty()) { throw new ServiceException("无权操作所选用户"); } for (Long userId : userIds) { if (userId == null || !visibleUserIds.contains(userId)) { throw new ServiceException("无权操作所选用户"); } } } /** * 当前登录账号若为公司账号(roleType=5 且已绑定公司),返回其所属公司ID;非公司账号返回null。 */ public Integer getCurrentCompanyId() { SysUser sysUser = getCurrentSysUser(); if (!isCompany(sysUser)) { return null; } return sysUser.getObjectId(); } /** * 数据范围强制:公司账号只允许查询本公司数据,覆盖前端传入的公司筛选条件;非公司账号保持原值。 */ public Integer resolveCompanyFilter(Integer requestCompanyId) { Integer currentCompanyId = getCurrentCompanyId(); return currentCompanyId != null ? currentCompanyId : requestCompanyId; } /** * 公司账号数据归属校验:记录不属于本公司时拒绝操作;非公司账号不做限制。 */ public void assertCompanyVisible(Integer recordCompanyId) { Integer currentCompanyId = getCurrentCompanyId(); if (currentCompanyId == null) { return; } if (!Objects.equals(currentCompanyId, recordCompanyId)) { throw new ServiceException("无权操作其他公司的数据"); } } private boolean isPartner(SysUser sysUser) { return sysUser != null && Objects.equals(PARTNER_ROLE_TYPE, sysUser.getRoleType()); } private boolean isCompany(SysUser sysUser) { return sysUser != null && Objects.equals(COMPANY_ROLE_TYPE, sysUser.getRoleType()) && sysUser.getObjectId() != null; } private List impossibleUserIds() { return Collections.singletonList(IMPOSSIBLE_USER_ID); } private SysUser getCurrentSysUser() { LoginUser loginUser = null; try { loginUser = tokenService.getLoginUser(); } catch (Exception ignored) { // 尝试从安全上下文继续获取。 } if (loginUser == null) { try { loginUser = SecurityUtils.getLoginUser(); } catch (Exception ignored) { // 当前请求不是管理后台登录上下文。 } } if (loginUser == null) { return null; } if (loginUser.getSysUser() != null && loginUser.getSysUser().getRoleType() != null) { return loginUser.getSysUser(); } if (loginUser.getUserid() == null) { return loginUser.getSysUser(); } R userResult = sysUserClient.getSysUser(loginUser.getUserid()); return userResult != null && userResult.getData() != null ? userResult.getData() : loginUser.getSysUser(); } }