|
@@ -10,6 +10,7 @@ import com.sckw.auth.model.vo.res.LoginResVo1;
|
|
|
import com.sckw.auth.service.IAuthService;
|
|
import com.sckw.auth.service.IAuthService;
|
|
|
import com.sckw.auth.util.AsyncFactory;
|
|
import com.sckw.auth.util.AsyncFactory;
|
|
|
import com.sckw.core.common.enums.enums.DictEnum;
|
|
import com.sckw.core.common.enums.enums.DictEnum;
|
|
|
|
|
+import com.sckw.core.common.enums.enums.DictTypeEnum;
|
|
|
import com.sckw.core.exception.SystemException;
|
|
import com.sckw.core.exception.SystemException;
|
|
|
import com.sckw.core.model.constant.Global;
|
|
import com.sckw.core.model.constant.Global;
|
|
|
import com.sckw.core.model.constant.NumberConstant;
|
|
import com.sckw.core.model.constant.NumberConstant;
|
|
@@ -56,6 +57,20 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
|
private RemoteFleetService fleetService;
|
|
private RemoteFleetService fleetService;
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * APP模块权限逻辑菜单关键字,仅用于 {@link #applyAppModulePermissionsByConfig} 控制模块显隐,
|
|
|
|
|
+ * 不应出现在底部导航 TabBar 中。
|
|
|
|
|
+ */
|
|
|
|
|
+ private static final String[] APP_MODULE_LOGIC_MENU_KEYWORDS = {
|
|
|
|
|
+ "\u5c55\u793a\u8ba2\u5355\u7edf\u8ba1", "orderStatistics", "order-statistics", "order_statistics",
|
|
|
|
|
+ "\u5c55\u793a\u9500\u552e\u7edf\u8ba1", "salesStatistics", "sales-statistics", "sales_statistics",
|
|
|
|
|
+ "\u5c55\u793a\u94b1\u5305", "wallet",
|
|
|
|
|
+ "\u5c55\u793a\u5730\u5740", "address",
|
|
|
|
|
+ "\u5c55\u793a\u5f85\u5c65\u7ea6\u4fdd\u8bc1\u91d1", "PENDING_PERFORMANCE_BALANCE", "pendingPerformanceBalance", "pending-performance-balance",
|
|
|
|
|
+ "\u5c55\u793a\u9884\u4ed8\u4f59\u989d", "PREPAY_BALANCE", "prepayBalance", "prepay-balance",
|
|
|
|
|
+ "\u5c55\u793a\u5f85\u4ed8\u8fd0\u8d39", "PENDING_FREIGHT", "pendingFreight", "pending-freight"
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public HttpResult login(LoginBase loginBase) {
|
|
public HttpResult login(LoginBase loginBase) {
|
|
|
if (StringUtils.isNotBlank(loginBase.getCaptcha())) {
|
|
if (StringUtils.isNotBlank(loginBase.getCaptcha())) {
|
|
@@ -168,11 +183,11 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
loginRes.setClientType(loginBase.getClientType());
|
|
loginRes.setClientType(loginBase.getClientType());
|
|
|
loginRes.setSystemType(loginBase.getSystemType());
|
|
loginRes.setSystemType(loginBase.getSystemType());
|
|
|
loginRes.setToken(token);
|
|
loginRes.setToken(token);
|
|
|
- List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes, loginBase, null, 1, loginRes.getEntTypes());
|
|
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBar = buildAppTabBarByConfig(loginRes, loginBase, null, 1, loginRes.getEntTypes());
|
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
|
loginRes.setTabBar(tabBar);
|
|
loginRes.setTabBar(tabBar);
|
|
|
}
|
|
}
|
|
|
- applyAppModulePermissions(loginRes, loginBase, null);
|
|
|
|
|
|
|
+ applyAppModulePermissionsByConfig(loginRes, loginBase);
|
|
|
loginRes.setRefreshToken(refreshToken);
|
|
loginRes.setRefreshToken(refreshToken);
|
|
|
return HttpResult.ok(loginRes);
|
|
return HttpResult.ok(loginRes);
|
|
|
}
|
|
}
|
|
@@ -262,11 +277,11 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
loginRes.setDriverId(user.getDriverId());
|
|
loginRes.setDriverId(user.getDriverId());
|
|
|
loginRes.setRoleName(user.getRoleName());
|
|
loginRes.setRoleName(user.getRoleName());
|
|
|
loginRes.setRoleList(user.getRoleInfoDto());
|
|
loginRes.setRoleList(user.getRoleInfoDto());
|
|
|
- List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes, loginBase, user.getRoleName(), 0, loginRes.getEntTypes());
|
|
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBar = buildAppTabBarByConfig(loginRes, loginBase, user.getRoleName(), 0, loginRes.getEntTypes());
|
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
|
loginRes.setTabBar(tabBar);
|
|
loginRes.setTabBar(tabBar);
|
|
|
}
|
|
}
|
|
|
- applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
|
|
|
|
|
|
|
+ applyAppModulePermissionsByConfig(loginRes, loginBase);
|
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
|
loginRes.setValid(true);
|
|
loginRes.setValid(true);
|
|
|
} else {
|
|
} else {
|
|
@@ -352,12 +367,12 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
loginRes.setRoleId(user.getRoleId());
|
|
loginRes.setRoleId(user.getRoleId());
|
|
|
loginRes.setRoleName(user.getRoleName());
|
|
loginRes.setRoleName(user.getRoleName());
|
|
|
loginRes.setRoleList(user.getRoleInfoDto());
|
|
loginRes.setRoleList(user.getRoleInfoDto());
|
|
|
- List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes, loginBase, user.getRoleName(), 0, loginRes.getEntTypes());
|
|
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBar = buildAppTabBarByConfig(loginRes, loginBase, user.getRoleName(), 0, loginRes.getEntTypes());
|
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
|
loginRes.setTabBar(tabBar);
|
|
loginRes.setTabBar(tabBar);
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
- applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
|
|
|
|
|
|
|
+ applyAppModulePermissionsByConfig(loginRes, loginBase);
|
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
|
loginRes.setValid(true);
|
|
loginRes.setValid(true);
|
|
|
} else {
|
|
} else {
|
|
@@ -523,7 +538,7 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
loginRes.setRoleId(user.getRoleId());
|
|
loginRes.setRoleId(user.getRoleId());
|
|
|
LoginBase loginBase = new LoginBase();
|
|
LoginBase loginBase = new LoginBase();
|
|
|
loginBase.setClientType(clientType);
|
|
loginBase.setClientType(clientType);
|
|
|
- applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
|
|
|
|
|
|
|
+ applyAppModulePermissionsByConfig(loginRes, loginBase);
|
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
|
loginRes.setValid(true);
|
|
loginRes.setValid(true);
|
|
|
} else {
|
|
} else {
|
|
@@ -859,11 +874,11 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
loginRes.setToken(newToken);
|
|
loginRes.setToken(newToken);
|
|
|
loginRes.setRefreshToken(newRefreshToken);
|
|
loginRes.setRefreshToken(newRefreshToken);
|
|
|
loginRes.setDriverId(driver.getId());
|
|
loginRes.setDriverId(driver.getId());
|
|
|
- List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes, loginBase, null, 1, loginRes.getEntTypes());
|
|
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBar = buildAppTabBarByConfig(loginRes, loginBase, null, 1, loginRes.getEntTypes());
|
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
|
loginRes.setTabBar(tabBar);
|
|
loginRes.setTabBar(tabBar);
|
|
|
}
|
|
}
|
|
|
- applyAppModulePermissions(loginRes, loginBase, null);
|
|
|
|
|
|
|
+ applyAppModulePermissionsByConfig(loginRes, loginBase);
|
|
|
return loginRes;
|
|
return loginRes;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -897,11 +912,11 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
loginRes.setDriverId(user.getDriverId());
|
|
loginRes.setDriverId(user.getDriverId());
|
|
|
loginRes.setRoleName(user.getRoleName());
|
|
loginRes.setRoleName(user.getRoleName());
|
|
|
loginRes.setRoleList(user.getRoleInfoDto());
|
|
loginRes.setRoleList(user.getRoleInfoDto());
|
|
|
- List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes, loginBase, user.getRoleName(), 1, loginRes.getEntTypes());
|
|
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBar = buildAppTabBarByConfig(loginRes, loginBase, user.getRoleName(), 1, loginRes.getEntTypes());
|
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
|
|
|
loginRes.setTabBar(tabBar);
|
|
loginRes.setTabBar(tabBar);
|
|
|
}
|
|
}
|
|
|
- applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
|
|
|
|
|
|
|
+ applyAppModulePermissionsByConfig(loginRes, loginBase);
|
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
|
|
|
loginRes.setValid(true);
|
|
loginRes.setValid(true);
|
|
|
} else {
|
|
} else {
|
|
@@ -917,6 +932,492 @@ public class AuthServiceImpl implements IAuthService {
|
|
|
|| Objects.equals(clientType, ClientTypeEnum.android.getValue())
|
|
|| Objects.equals(clientType, ClientTypeEnum.android.getValue())
|
|
|
|| Objects.equals(clientType, ClientTypeEnum.mobile.getValue());
|
|
|| Objects.equals(clientType, ClientTypeEnum.mobile.getValue());
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据角色ID字典配置控制APP模块权限。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 该方法主要用于在登录或刷新Token时,根据当前用户的角色配置,动态设置APP端需要展示的模块(如订单统计、销售统计、钱包、地址管理等)。
|
|
|
|
|
+ * 仅在APP端登录时生效,PC/H5端不展示这些特定模块配置。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param loginRes 登录返回信息对象,用于设置模块显示状态及钱包子项
|
|
|
|
|
+ * @param loginBase 登录请求基础信息,用于判断客户端类型
|
|
|
|
|
+ */
|
|
|
|
|
+ private void applyAppModulePermissionsByConfig(LoginResVo1 loginRes, LoginBase loginBase) {
|
|
|
|
|
+ // 1. 参数非空校验:若登录结果或登录参数为空,直接返回,避免NPE
|
|
|
|
|
+ if (Objects.isNull(loginRes) || Objects.isNull(loginBase)) {
|
|
|
|
|
+ log.debug("登录返回对象或登录参数为空,跳过APP模块权限配置");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 初始化默认状态:默认隐藏所有APP工作台模块,遵循“最小权限原则”,避免无菜单权限时前端误展示。
|
|
|
|
|
+ loginRes.setShowOrderStatisticsModule(Boolean.FALSE);
|
|
|
|
|
+ loginRes.setShowSalesStatisticsModule(Boolean.FALSE);
|
|
|
|
|
+ loginRes.setShowWalletModule(Boolean.FALSE);
|
|
|
|
|
+ loginRes.setShowAddressModule(Boolean.FALSE);
|
|
|
|
|
+ loginRes.setWalletModuleItems(Collections.emptyList());
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 客户端类型校验:仅对APP端(iOS/Android/Mobile)进行模块权限配置,PC/H5端直接返回
|
|
|
|
|
+ if (!isAppLogin(loginBase)) {
|
|
|
|
|
+ log.debug("非APP端登录,跳过APP模块权限配置。clientType: {}", loginBase.getClientType());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 获取角色ID并加载对应的APP菜单配置
|
|
|
|
|
+ Long roleId = loginRes.getRoleId();
|
|
|
|
|
+ log.debug("开始加载APP模块权限配置,userId: {}, roleId: {}", loginRes.getId(), roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 通过远程服务查询该角色在APP端的菜单权限列表
|
|
|
|
|
+ List<AppTabBarMenuResDto> appMenus = loadAppRoleMenus(roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 逐项判断模块权限:
|
|
|
|
|
+ // 使用多关键字匹配(中文名、英文名、下划线格式、驼峰格式等),提高匹配的兼容性和健壮性。
|
|
|
|
|
+
|
|
|
|
|
+ // 5.1 订单统计模块:检查菜单中是否包含“展示订单统计”或相关标识(orderStatistics等),决定前端是否显示该模块
|
|
|
|
|
+ boolean hasOrderStatistics = hasAppModuleMenu(appMenus, "\u5c55\u793a\u8ba2\u5355\u7edf\u8ba1", "orderStatistics", "order-statistics", "order_statistics");
|
|
|
|
|
+ log.debug("订单统计模块权限判断结果: {}", hasOrderStatistics);
|
|
|
|
|
+
|
|
|
|
|
+ // 5.2 销售统计模块:检查菜单中是否包含“展示销售统计”或相关标识(salesStatistics等),决定前端是否显示该模块
|
|
|
|
|
+ boolean hasSalesStatistics = hasAppModuleMenu(appMenus, "\u5c55\u793a\u9500\u552e\u7edf\u8ba1", "salesStatistics", "sales-statistics", "sales_statistics");
|
|
|
|
|
+ log.debug("销售统计模块权限判断结果: {}", hasSalesStatistics);
|
|
|
|
|
+
|
|
|
|
|
+ // 5.3 钱包模块:检查菜单中是否包含“展示钱包”或相关标识(wallet),决定前端是否显·示钱包入口
|
|
|
|
|
+ boolean hasWallet = hasAppModuleMenu(appMenus, "\u5c55\u793a\u94b1\u5305", "wallet");
|
|
|
|
|
+ log.debug("钱包模块权限判断结果: {}", hasWallet);
|
|
|
|
|
+
|
|
|
|
|
+ // 5.4 地址管理模块:检查菜单中是否包含“展示地址”或相关标识(address),决定前端是否显示地址管理入口
|
|
|
|
|
+ boolean hasAddress = hasAppModuleMenu(appMenus, "\u5c55\u793a\u5730\u5740", "address");
|
|
|
|
|
+ log.debug("地址管理模块权限判断结果: {}", hasAddress);
|
|
|
|
|
+
|
|
|
|
|
+ // 5.5 钱包子项 - 待履约保证金:检查菜单中是否包含“展示待履约保证金”或相关标识,用于控制钱包内子项显示
|
|
|
|
|
+ boolean hasPendingPerformance = hasAppModuleMenu(appMenus, "\u5c55\u793a\u5f85\u5c65\u7ea6\u4fdd\u8bc1\u91d1", "PENDING_PERFORMANCE_BALANCE", "pendingPerformanceBalance", "pending-performance-balance");
|
|
|
|
|
+ log.debug("待履约保证金子项权限判断结果: {}", hasPendingPerformance);
|
|
|
|
|
+
|
|
|
|
|
+ // 5.6 钱包子项 - 预付余额:检查菜单中是否包含“展示预付余额”或相关标识,用于控制钱包内子项显示
|
|
|
|
|
+ boolean hasPrepayBalance = hasAppModuleMenu(appMenus, "\u5c55\u793a\u9884\u4ed8\u4f59\u989d", "PREPAY_BALANCE", "prepayBalance", "prepay-balance");
|
|
|
|
|
+ log.debug("预付余额子项权限判断结果: {}", hasPrepayBalance);
|
|
|
|
|
+
|
|
|
|
|
+ // 5.7 钱包子项 - 待付运费:检查菜单中是否包含“展示待付运费”或相关标识,用于控制钱包内子项显示
|
|
|
|
|
+ boolean hasPendingFreight = hasAppModuleMenu(appMenus, "\u5c55\u793a\u5f85\u4ed8\u8fd0\u8d39", "PENDING_FREIGHT", "pendingFreight", "pending-freight");
|
|
|
|
|
+ log.debug("待付运费子项权限判断结果: {}", hasPendingFreight);
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 应用权限配置到返回对象
|
|
|
|
|
+ loginRes.setShowOrderStatisticsModule(hasOrderStatistics);
|
|
|
|
|
+ loginRes.setShowSalesStatisticsModule(hasSalesStatistics);
|
|
|
|
|
+ loginRes.setShowWalletModule(hasWallet);
|
|
|
|
|
+ loginRes.setShowAddressModule(hasAddress);
|
|
|
|
|
+
|
|
|
|
|
+ // 若拥有钱包模块权限,则进一步构建钱包内部的子项列表
|
|
|
|
|
+ if (hasWallet) {
|
|
|
|
|
+ List<String> walletItems = buildWalletModuleItems(hasPendingPerformance, hasPrepayBalance, hasPendingFreight);
|
|
|
|
|
+ loginRes.setWalletModuleItems(walletItems);
|
|
|
|
|
+ log.debug("钱包模块开启,子项配置: {}", walletItems);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 记录最终配置结果日志,便于后续排查权限问题
|
|
|
|
|
+ log.info("APP模块权限配置完成 - userId: {}, roleId: {}, orderStats: {}, salesStats: {}, wallet: {}, address: {}",
|
|
|
|
|
+ loginRes.getId(), roleId, hasOrderStatistics, hasSalesStatistics, hasWallet, hasAddress);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据菜单授权结果构建钱包模块子项。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param hasPendingPerformance 是否包含待履约保证金菜单
|
|
|
|
|
+ * @param hasPrepayBalance 是否包含预付余额菜单
|
|
|
|
|
+ * @param hasPendingFreight 是否包含待付运费菜单
|
|
|
|
|
+ * @return 钱包模块子项编码列表
|
|
|
|
|
+ */
|
|
|
|
|
+ List<String> buildWalletModuleItems(boolean hasPendingPerformance, boolean hasPrepayBalance, boolean hasPendingFreight) {
|
|
|
|
|
+ List<String> walletItems = new ArrayList<>();
|
|
|
|
|
+ if (hasPendingPerformance) {
|
|
|
|
|
+ walletItems.add("PENDING_PERFORMANCE_BALANCE");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (hasPrepayBalance) {
|
|
|
|
|
+ walletItems.add("PREPAY_BALANCE");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (hasPendingFreight || hasPendingPerformance || hasPrepayBalance) {
|
|
|
|
|
+ walletItems.add("PENDING_FREIGHT");
|
|
|
|
|
+ }
|
|
|
|
|
+ return walletItems;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 加载角色APP菜单。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param roleId 角色ID
|
|
|
|
|
+ * @return APP菜单列表
|
|
|
|
|
+ */
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 加载指定角色的APP底部导航菜单配置。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 该方法通过远程服务查询角色对应的APP TabBar菜单权限,用于动态构建APP端底部导航栏。
|
|
|
|
|
+ * 若角色ID为空、查询结果为空或发生异常,均返回空列表,确保前端展示默认状态或不展示导航栏,避免影响登录流程。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param roleId 角色ID,用于查询对应的APP底部导航配置
|
|
|
|
|
+ * @return APP底部导航菜单项列表,若无配置或查询失败则返回空列表
|
|
|
|
|
+ */
|
|
|
|
|
+ List<AppTabBarMenuResDto> loadAppRoleMenus(Long roleId) {
|
|
|
|
|
+ // 1. 参数校验:若角色ID为空,直接返回空列表,避免无效远程调用
|
|
|
|
|
+ if (Objects.isNull(roleId)) {
|
|
|
|
|
+ log.debug("角色ID为空,跳过APP角色菜单查询");
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 2. 记录开始查询日志,便于追踪性能和问题
|
|
|
|
|
+ log.debug("开始查询APP角色菜单,roleId: {}", roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 远程调用系统服务,获取角色对应的APP底部导航菜单配置
|
|
|
|
|
+ List<AppTabBarMenuResDto> menus = remoteUserService.queryAppTabBarMenuByRoleId(roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 结果校验:若返回结果为空或无数据,记录调试日志并返回空列表
|
|
|
|
|
+ if (org.apache.commons.collections4.CollectionUtils.isEmpty(menus)) {
|
|
|
|
|
+ log.debug("角色未配置APP底部导航菜单,roleId: {}", roleId);
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 记录成功查询日志,包含菜单数量信息
|
|
|
|
|
+ log.info("APP角色菜单查询成功,roleId: {}, 菜单数量: {}", roleId, menus.size());
|
|
|
|
|
+ return menus;
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 6. 异常处理:记录错误日志,防止因远程服务异常导致登录流程中断
|
|
|
|
|
+ // 返回空列表,前端可根据此情况展示默认导航或隐藏导航栏
|
|
|
|
|
+ log.error("查询APP角色菜单失败,roleId: {}", roleId, e);
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断角色菜单中是否包含指定APP模块。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param menus APP菜单列表
|
|
|
|
|
+ * @param keywords 模块关键字
|
|
|
|
|
+ * @return true-包含,false-不包含
|
|
|
|
|
+ */
|
|
|
|
|
+ boolean hasAppModuleMenu(List<AppTabBarMenuResDto> menus, String... keywords) {
|
|
|
|
|
+ if (org.apache.commons.collections4.CollectionUtils.isEmpty(menus) || Objects.isNull(keywords)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return menus.stream()
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .anyMatch(menu -> matchesAppModuleMenuKeywords(menu, keywords));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断菜单是否为模块权限逻辑菜单(仅控制模块显隐,不作为 TabBar 展示项)。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 该方法通过检查菜单的名称、权限标识或URL是否包含预定义的“逻辑菜单关键字”,
|
|
|
|
|
+ * 来识别该菜单是否属于仅用于控制APP端特定模块(如订单统计、钱包等)显示/隐藏的辅助菜单。
|
|
|
|
|
+ * 此类菜单不应出现在底部导航栏(TabBar)中。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param menu APP菜单对象
|
|
|
|
|
+ * @return true-是逻辑菜单(不展示在TabBar),false-非逻辑菜单(可展示在TabBar)
|
|
|
|
|
+ */
|
|
|
|
|
+ boolean isAppModuleLogicMenu(AppTabBarMenuResDto menu) {
|
|
|
|
|
+ // 1. 空值校验:若菜单对象为空,直接返回false
|
|
|
|
|
+ if (Objects.isNull(menu)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 关键字匹配:检查菜单是否命中预定义的逻辑菜单关键字集合
|
|
|
|
|
+ boolean isLogicMenu = matchesAppModuleMenuKeywords(menu, APP_MODULE_LOGIC_MENU_KEYWORDS);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 记录调试日志,便于排查哪些菜单被识别为逻辑菜单
|
|
|
|
|
+ if (isLogicMenu) {
|
|
|
|
|
+ log.debug("识别到APP模块逻辑菜单 - 菜单名称: {}, URL: {}", menu.getName(), menu.getUrl());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return isLogicMenu;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断菜单是否匹配指定的关键字列表。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 该方法会遍历给定的关键字数组,检查菜单的名称(name)、权限标识(perms)或URL(url)
|
|
|
|
|
+ * 是否包含任意一个非空关键字(忽略大小写)。只要有一个字段匹配成功,即返回true。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param menu APP菜单对象
|
|
|
|
|
+ * @param keywords 待匹配的关键字数组
|
|
|
|
|
+ * @return true-匹配成功,false-未匹配
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean matchesAppModuleMenuKeywords(AppTabBarMenuResDto menu, String... keywords) {
|
|
|
|
|
+ // 1. 参数校验:若菜单对象或关键字数组为空,直接返回false
|
|
|
|
|
+ if (Objects.isNull(menu) || Objects.isNull(keywords)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 流式处理关键字进行匹配
|
|
|
|
|
+ return Arrays.stream(keywords)
|
|
|
|
|
+ // 过滤掉空白关键字,避免无效匹配
|
|
|
|
|
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
|
|
|
|
|
+ // 只要有一个关键字在菜单的 name、perms 或 url 中出现(忽略大小写),即判定为匹配
|
|
|
|
|
+ .anyMatch(keyword -> containsIgnoreCase(menu.getName(), keyword)
|
|
|
|
|
+ || containsIgnoreCase(menu.getPerms(), keyword)
|
|
|
|
|
+ || containsIgnoreCase(menu.getUrl(), keyword));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean containsIgnoreCase(String source, String keyword) {
|
|
|
|
|
+ return org.apache.commons.lang3.StringUtils.isNotBlank(source)
|
|
|
|
|
+ && org.apache.commons.lang3.StringUtils.containsIgnoreCase(source, keyword);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private List<LoginResVo1.TabBarItem> buildAppTabBarByConfig(LoginResVo1 loginRes, LoginBase loginBase,
|
|
|
|
|
+ String roleName, int flag, String entTypeNames) {
|
|
|
|
|
+ // 优先使用登录结果中的角色名称,若为空则使用传入的参数
|
|
|
|
|
+ if (Objects.isNull(loginRes)) {
|
|
|
|
|
+ log.debug("登录返回对象为空,跳过APP底部导航菜单查询");
|
|
|
|
|
+ return List.of();
|
|
|
|
|
+ }
|
|
|
|
|
+ roleName = org.apache.commons.lang3.StringUtils.defaultIfBlank(loginRes.getRoleName(), roleName);
|
|
|
|
|
+
|
|
|
|
|
+ // 记录关键上下文信息,便于排查角色匹配问题
|
|
|
|
|
+ log.info("构建APP TabBar - 角色ID:{},角色名称:{},企业类型:{}", loginRes.getRoleId(), roleName, entTypeNames);
|
|
|
|
|
+
|
|
|
|
|
+ // 非APP端登录(如PC、H5等)不展示底部导航
|
|
|
|
|
+ // 校验客户端类型:仅对APP端(iOS/Android/Mobile)构建底部导航,PC/H5端返回空列表
|
|
|
|
|
+ if (!isAppLogin(loginBase)) {
|
|
|
|
|
+ log.debug("非APP端登录(clientType: {}),跳过APP底部导航构建", loginBase.getClientType());
|
|
|
|
|
+ return List.of();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Long roleId = loginRes.getRoleId();
|
|
|
|
|
+ log.info("开始构建APP底部导航 - userId: {}, roleId: {}", loginRes.getId(), roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 从角色菜单权限加载APP底部导航,替代原有的硬编码字典配置,实现动态配置
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBarItems = buildAppTabBarByRoleMenus(roleId);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("APP底部导航构建完成 - userId: {}, roleId: {}, 菜单数量: {}",
|
|
|
|
|
+ loginRes.getId(), roleId, tabBarItems != null ? tabBarItems.size() : 0);
|
|
|
|
|
+
|
|
|
|
|
+ return tabBarItems;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据角色ID查询并构建APP底部导航栏菜单项。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 该方法通过远程服务获取指定角色配置的APP底部导航菜单数据,
|
|
|
|
|
+ * 并将其转换为前端所需的TabBarItem对象列表。
|
|
|
|
|
+ * 若角色ID为空、未配置菜单或查询异常,则返回空列表,确保前端展示默认状态或不展示底部导航。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param roleId 角色ID,用于查询对应的APP底部导航配置
|
|
|
|
|
+ * @return APP底部导航菜单项列表,若无配置或查询失败则返回空列表
|
|
|
|
|
+ */
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> buildAppTabBarByRoleMenus(Long roleId) {
|
|
|
|
|
+ // 1. 参数校验:若角色ID为空,直接返回空列表,避免无效远程调用
|
|
|
|
|
+ if (Objects.isNull(roleId)) {
|
|
|
|
|
+ log.debug("角色ID为空,跳过APP底部导航菜单查询");
|
|
|
|
|
+ return List.of();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 2. 记录开始查询日志,便于追踪性能和问题
|
|
|
|
|
+ log.debug("开始查询APP底部导航菜单,roleId: {}", roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 远程调用系统服务,获取角色对应的APP底部导航菜单配置
|
|
|
|
|
+ List<AppTabBarMenuResDto> menus = remoteUserService.queryAppTabBarMenuByRoleId(roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 结果校验:若返回结果为空或无数据,记录调试日志并返回空列表
|
|
|
|
|
+ if (org.apache.commons.collections4.CollectionUtils.isEmpty(menus)) {
|
|
|
|
|
+ log.debug("角色未配置APP底部导航菜单,roleId: {}", roleId);
|
|
|
|
|
+ return List.of();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 数据转换:将DTO列表转换为前端所需的TabBarItem对象列表
|
|
|
|
|
+ // 过滤掉null对象及模块权限逻辑菜单(仅用于控制模块显隐,不作为底部导航展示)
|
|
|
|
|
+ List<LoginResVo1.TabBarItem> tabBarItems = menus.stream()
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .filter(menu -> !isAppModuleLogicMenu(menu))
|
|
|
|
|
+ .map(menu -> buildTabBarItem(
|
|
|
|
|
+ // 菜单名称,若为空则默认为空字符串
|
|
|
|
|
+ org.apache.commons.lang3.StringUtils.defaultString(menu.getName()),
|
|
|
|
|
+ // 选中图标路径,若为空则默认为空字符串
|
|
|
|
|
+ org.apache.commons.lang3.StringUtils.defaultString(menu.getIcon()),
|
|
|
|
|
+ // 未选中图标路径,若为空则默认为空字符串
|
|
|
|
|
+ org.apache.commons.lang3.StringUtils.defaultString(menu.getNotSelectedIconPath()),
|
|
|
|
|
+ // 页面路由地址,若为空则默认为空字符串
|
|
|
|
|
+ org.apache.commons.lang3.StringUtils.defaultString(menu.getUrl())))
|
|
|
|
|
+ .toList();
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 记录成功构建日志,包含菜单数量信息
|
|
|
|
|
+ log.info("APP底部导航菜单构建成功,roleId: {}, 菜单数量: {}", roleId, tabBarItems.size());
|
|
|
|
|
+ return tabBarItems;
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 7. 异常处理:记录错误日志,防止因远程服务异常导致登录流程中断
|
|
|
|
|
+ // 返回空列表,前端可根据此情况展示默认导航或隐藏导航栏
|
|
|
|
|
+ log.error("查询APP底部导航菜单失败,roleId: {}", roleId, e);
|
|
|
|
|
+ return List.of();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 加载APP模块权限角色配置。
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param roleId 角色ID
|
|
|
|
|
+ * @return APP角色配置
|
|
|
|
|
+ */
|
|
|
|
|
+ private AppRoleConfig loadAppRoleConfig(Long roleId) {
|
|
|
|
|
+ // 1. 参数校验:若角色ID为空,直接返回空配置,避免无效查询
|
|
|
|
|
+ if (Objects.isNull(roleId)) {
|
|
|
|
|
+ log.debug("角色ID为空,返回空APP角色配置");
|
|
|
|
|
+ return AppRoleConfig.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 2. 记录开始加载日志,便于追踪性能和问题
|
|
|
|
|
+ log.debug("开始加载APP角色权限配置,roleId: {}", roleId);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 远程调用系统服务,获取APP角色权限相关的字典数据
|
|
|
|
|
+ // 字典类型由 DictTypeEnum.APP_ROLE_PERMISSION 定义:value 存角色ID列表,label 存 AppRoleType 枚举名。
|
|
|
|
|
+ List<SysDictResDto> dictList = systemService.queryDictDbByType(DictTypeEnum.APP_ROLE_PERMISSION.getType());
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 数据预处理与转换
|
|
|
|
|
+ // 过滤掉 null 对象及 value 为空的无效字典项
|
|
|
|
|
+ // 将 List 转换为 Map,Key 为字典项的 value (即 AppRoleType 枚举名),Value 为字典对象本身
|
|
|
|
|
+ // 注意:若存在重复 Key,保留第一个出现的值 (first, second) -> first
|
|
|
|
|
+ Map<String, SysDictResDto> dictMap = dictList.stream()
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .filter(item -> org.apache.commons.lang3.StringUtils.isNotBlank(item.getLabel()))
|
|
|
|
|
+ .collect(Collectors.toMap(SysDictResDto::getLabel, item -> item, (first, second) -> first));
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 构建并返回角色配置对象
|
|
|
|
|
+ AppRoleConfig config = AppRoleConfig.fromDict(roleId, dictMap);
|
|
|
|
|
+ log.debug("APP角色权限配置加载完成,roleId: {}, 匹配到的角色类型: {}", roleId, config.roleTypes);
|
|
|
|
|
+ return config;
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 6. 异常处理:记录警告日志并返回空配置,确保登录流程不因配置加载失败而中断
|
|
|
|
|
+ // 使用 warn 级别是因为这属于非核心业务异常,但需要运维关注
|
|
|
|
|
+ log.warn("读取APP角色权限字典配置失败,roleId: {},错误信息: {}", roleId, e.getMessage(), e);
|
|
|
|
|
+ return AppRoleConfig.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * APP端角色类型枚举。
|
|
|
|
|
+ * 用于定义APP底部导航栏(TabBar)及模块权限控制的角色标识,
|
|
|
|
|
+ * 对应字典表 app_role_permission 中的 value 值。
|
|
|
|
|
+ */
|
|
|
|
|
+ enum AppRoleType {
|
|
|
|
|
+ /** 销售/供应商 */
|
|
|
|
|
+ SELLER,
|
|
|
|
|
+ /** 财务 */
|
|
|
|
|
+ FINANCE,
|
|
|
|
|
+ /** 采购 */
|
|
|
|
|
+ PURCHASE,
|
|
|
|
|
+ /** 门卫 */
|
|
|
|
|
+ DOOR_KEEPER,
|
|
|
|
|
+ /** 叉车司机 */
|
|
|
|
|
+ FORKLIFT_DRIVER,
|
|
|
|
|
+ /** 买家 */
|
|
|
|
|
+ BUYER,
|
|
|
|
|
+ /** 司机 */
|
|
|
|
|
+ DRIVER,
|
|
|
|
|
+ /** 物流人员 */
|
|
|
|
|
+ LOGISTICS,
|
|
|
|
|
+ /** 供应商管理员 */
|
|
|
|
|
+ SUPPLIER_ADMIN,
|
|
|
|
|
+ /** 物流商管理员 */
|
|
|
|
|
+ LOGISTICS_ADMIN,
|
|
|
|
|
+ /** 采购商管理员 */
|
|
|
|
|
+ PURCHASE_ADMIN
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static class AppRoleConfig {
|
|
|
|
|
+ private final Set<AppRoleType> roleTypes;
|
|
|
|
|
+
|
|
|
|
|
+ private AppRoleConfig(Set<AppRoleType> roleTypes) {
|
|
|
|
|
+ this.roleTypes = roleTypes;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static AppRoleConfig empty() {
|
|
|
|
|
+ return new AppRoleConfig(Collections.emptySet());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据角色ID和字典映射构建APP角色配置。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 该方法遍历字典项,查找value字段中包含当前roleId的配置项,
|
|
|
|
|
+ * 并将其label字段解析为对应的AppRoleType枚举值。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param roleId 当前用户的角色ID
|
|
|
|
|
+ * @param dictMap APP角色权限字典映射,Key为AppRoleType枚举名,Value为字典对象
|
|
|
|
|
+ * @return {@link AppRoleConfig} 包含匹配到的角色类型集合
|
|
|
|
|
+ */
|
|
|
|
|
+ static AppRoleConfig fromDict(Long roleId, Map<String, SysDictResDto> dictMap) {
|
|
|
|
|
+ // 1. 参数校验:若角色ID为空或字典数据为空,直接返回空配置
|
|
|
|
|
+ if (Objects.isNull(roleId) || dictMap == null || dictMap.isEmpty()) {
|
|
|
|
|
+ log.debug("构建APP角色配置失败:roleId为空或字典数据为空");
|
|
|
|
|
+ return empty();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String roleIdValue = String.valueOf(roleId);
|
|
|
|
|
+ log.debug("开始构建APP角色配置,roleId: {}", roleIdValue);
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 流式处理字典数据,提取匹配的角色类型
|
|
|
|
|
+ Set<AppRoleType> roleTypes = dictMap.values().stream()
|
|
|
|
|
+ // 过滤掉null对象
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ // 核心逻辑:判断字典项的value(角色ID列表字符串)是否包含当前roleId
|
|
|
|
|
+ .filter(item -> {
|
|
|
|
|
+ boolean matched = matchRoleId(roleIdValue, item.getValue());
|
|
|
|
|
+ if (matched) {
|
|
|
|
|
+ log.debug("字典项匹配成功 - Label: {}, Value: {}", item.getLabel(), item.getValue());
|
|
|
|
|
+ }
|
|
|
|
|
+ return matched;
|
|
|
|
|
+ })
|
|
|
|
|
+ // 获取字典项的Label,即AppRoleType的枚举名称
|
|
|
|
|
+ .map(SysDictResDto::getLabel)
|
|
|
|
|
+ // 将字符串转换为AppRoleType枚举对象
|
|
|
|
|
+ .map(AppRoleConfig::parseRoleType)
|
|
|
|
|
+ // 过滤掉转换失败的Optional.empty()
|
|
|
|
|
+ .filter(Optional::isPresent)
|
|
|
|
|
+ // 解包Optional获取枚举值
|
|
|
|
|
+ .map(Optional::get)
|
|
|
|
|
+ // 收集为Set集合,去重
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+
|
|
|
|
|
+ log.info("APP角色配置构建完成,roleId: {}, 匹配到的角色类型数量: {}, 类型列表: {}",
|
|
|
|
|
+ roleIdValue, roleTypes.size(), roleTypes);
|
|
|
|
|
+
|
|
|
|
|
+ return new AppRoleConfig(roleTypes);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ boolean match(AppRoleType roleType) {
|
|
|
|
|
+ return roleTypes.contains(roleType);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static boolean matchRoleId(String roleId, String roleIds) {
|
|
|
|
|
+ if (org.apache.commons.lang3.StringUtils.isBlank(roleId) || org.apache.commons.lang3.StringUtils.isBlank(roleIds)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return Arrays.stream(roleIds.split(","))
|
|
|
|
|
+ .map(String::trim)
|
|
|
|
|
+ .filter(org.apache.commons.lang3.StringUtils::isNotBlank)
|
|
|
|
|
+ .anyMatch(roleId::equals);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static Optional<AppRoleType> parseRoleType(String roleType) {
|
|
|
|
|
+ if (org.apache.commons.lang3.StringUtils.isBlank(roleType)) {
|
|
|
|
|
+ return Optional.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ return Optional.of(AppRoleType.valueOf(roleType.trim().toUpperCase(Locale.ROOT)));
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("APP角色权限字典value配置错误,value:{}", roleType);
|
|
|
|
|
+ return Optional.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
private void applyAppModulePermissions(LoginResVo1 loginRes, LoginBase loginBase, String roleName) {
|
|
private void applyAppModulePermissions(LoginResVo1 loginRes, LoginBase loginBase, String roleName) {
|
|
|
roleName = loginRes.getRoleName();
|
|
roleName = loginRes.getRoleName();
|