Kaynağa Gözat

1、邀请码管理搜索自定义查询用户角色租户包装分页
2、加入租户联查方法(注册、获取用户信息、获取用户角色)
3、处理角色web平台权限bug

liyanbo 2 ay önce
ebeveyn
işleme
a07711ce16

+ 4 - 1
byzs-framework/byzs-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/byzs/framework/tenant/core/security/TenantDataSecurityFilter.java

@@ -89,7 +89,10 @@ public class TenantDataSecurityFilter extends OncePerRequestFilter {
      */
     private boolean isExcludedPath(HttpServletRequest request) {
         String requestURI = request.getRequestURI();
-        if (requestURI.contains("bjdxWeb/web/getRoleRoute")) {
+        if (requestURI.contains("bjdxWeb/web/getRoleRoute") ||
+                requestURI.contains("/bjdxWeb/web/getUserInfo") ||
+                requestURI.contains("/bjdxWeb/web/register") ||
+                requestURI.contains("/bjdxWeb/web/activateInviteCode") ) {
             return false;
         }
         return EXCLUDED_METHOD_PATHS.stream().anyMatch(path -> requestURI.contains(path));

+ 5 - 5
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/controller/admin/invitecode/vo/InviteCodePageReqVO.java

@@ -17,7 +17,7 @@ public class InviteCodePageReqVO extends PageParam {
     private String code;
 
     @Schema(description = "绑定角色")
-    private String roleIds;
+    private String roleName;
 
     @Schema(description = "有效期(天)")
     private Integer validTime;
@@ -30,11 +30,11 @@ public class InviteCodePageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] expireTime;
 
-    @Schema(description = "使用用户id")
-    private Long useUserId;
+    @Schema(description = "使用用户")
+    private String useUserName;
 
-    @Schema(description = "使用用户租户id")
-    private Long useUserTenantId;
+    @Schema(description = "使用用户租户")
+    private String useUserTenantName;
 
     @Schema(description = "状态")
     private String status;

+ 5 - 0
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/controller/admin/permission/vo/role/RoleRespVO.java

@@ -53,6 +53,11 @@ public class RoleRespVO {
     @Schema(description = "数据范围(指定部门数组)", example = "1")
     private Set<Long> dataScopeDeptIds;
 
+
+    @Schema(description = "平台范围(web平台数组)", example = "1")
+    private Set<String> dataScopeWebRoute;
+
+
     @Schema(description = "课程范围(指定课程数组)", example = "1")
     private Set<Long> dataScopeCourseIds;
 

+ 3 - 3
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/dal/mysql/invitecode/InviteCodeMapper.java

@@ -18,11 +18,11 @@ public interface InviteCodeMapper extends BaseMapperX<InviteCodeDO> {
     default PageResult<InviteCodeDO> selectPage(InviteCodePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<InviteCodeDO>()
                 .eqIfPresent(InviteCodeDO::getCode, reqVO.getCode())
-                .eqIfPresent(InviteCodeDO::getRoleIds, reqVO.getRoleIds())
+//                .eqIfPresent(InviteCodeDO::getRoleIds, reqVO.getRoleName())
                 .eqIfPresent(InviteCodeDO::getValidTime, reqVO.getValidTime())
                 .betweenIfPresent(InviteCodeDO::getExpireTime, reqVO.getExpireTime())
-                .eqIfPresent(InviteCodeDO::getUseUserId, reqVO.getUseUserId())
-                .eqIfPresent(InviteCodeDO::getUseUserTenantId, reqVO.getUseUserTenantId())
+//                .eqIfPresent(InviteCodeDO::getUseUserId, reqVO.getUseUserName())
+//                .eqIfPresent(InviteCodeDO::getUseUserTenantId, reqVO.getUseUserTenantName())
                 .eqIfPresent(InviteCodeDO::getStatus, reqVO.getStatus())
                 .betweenIfPresent(InviteCodeDO::getCreateTime, reqVO.getCreateTime())
                 .eqIfPresent(InviteCodeDO::getTenantId, reqVO.getTenantId())

+ 76 - 6
byzs-module-system/src/main/java/cn/iocoder/byzs/module/system/service/invitecode/InviteCodeServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.iocoder.byzs.module.system.service.invitecode;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.byzs.framework.common.pojo.PageParam;
 import cn.iocoder.byzs.framework.common.pojo.PageResult;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
 import cn.iocoder.byzs.framework.common.util.string.StrUtils;
@@ -163,24 +164,37 @@ public class InviteCodeServiceImpl implements InviteCodeService {
 
     @Override
     public PageResult<InviteCodeRespVO> getInviteCodePage(InviteCodePageReqVO pageReqVO) {
+        // 1. 首先查询所有符合条件的数据(不分页),因为需要进行内存筛选
+        // 临时保存分页参数,查询完后恢复
+        Integer originalPageSize = pageReqVO.getPageSize();
+        Integer originalPageNo = pageReqVO.getPageNo();
+        
+        // 设置不分页,查询所有数据
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         PageResult<InviteCodeDO> inviteCodeDOPageResult = inviteCodeMapper.selectPage(pageReqVO);
         List<InviteCodeDO> list = inviteCodeDOPageResult.getList();
+        
+        // 恢复分页参数
+        pageReqVO.setPageSize(originalPageSize);
+        pageReqVO.setPageNo(originalPageNo);
 
-        //取list的roleIds集合,按逗号分割并转换为Long类型
+        // 2. 转换为RespVO并填充关联数据
+        // 取所有角色ID
         Set<Long> roleIdSet = list.stream().map(InviteCodeDO::getRoleIds).filter(Objects::nonNull).flatMap(roleIds -> StrUtils.splitToLongSet(roleIds).stream()).collect(Collectors.toSet());
         List<RoleDO> roleList = roleIdSet.isEmpty() ? Collections.emptyList() : roleMapper.selectBatchIds(roleIdSet);
         Map<Long, String> roleMap = roleList.stream().collect(Collectors.toMap(RoleDO::getId, RoleDO::getName));
 
-        //取list的userId集合
-        Set<Long> userIdSet = list.stream().map(InviteCodeDO::getUseUserId).collect(Collectors.toSet());
+        // 取所有用户ID
+        Set<Long> userIdSet = list.stream().map(InviteCodeDO::getUseUserId).filter(Objects::nonNull).collect(Collectors.toSet());
         List<AdminUserDO> userList = userIdSet.isEmpty() ? Collections.emptyList() : userMapper.selectBatchIds(userIdSet);
         Map<Long, String> userMap = userList.stream().collect(Collectors.toMap(AdminUserDO::getId, AdminUserDO::getNickname));
 
-        //取list的tenantIds集合
-        Set<Long> userTenantIdSet = list.stream().map(InviteCodeDO::getUseUserTenantId).collect(Collectors.toSet());
+        // 取所有租户ID
+        Set<Long> userTenantIdSet = list.stream().map(InviteCodeDO::getUseUserTenantId).filter(Objects::nonNull).collect(Collectors.toSet());
         List<TenantDO> tenantList = userTenantIdSet.isEmpty() ? Collections.emptyList() : tenantMapper.selectBatchIds(userTenantIdSet);
         Map<Long, String> tenantMap = tenantList.stream().collect(Collectors.toMap(TenantDO::getId, TenantDO::getName));
 
+        // 转换为RespVO
         List<InviteCodeRespVO> respVOList = list.stream().map(inviteCode -> {
             InviteCodeRespVO respVO = BeanUtils.toBean(inviteCode, InviteCodeRespVO.class);
 
@@ -207,7 +221,63 @@ public class InviteCodeServiceImpl implements InviteCodeService {
             return respVO;
         }).collect(Collectors.toList());
 
-        return new PageResult<InviteCodeRespVO>().setList(respVOList).setTotal(inviteCodeDOPageResult.getTotal());
+        // 3. 进行内存筛选
+        List<InviteCodeRespVO> filteredRespVOList = respVOList;
+
+        // 按角色名称筛选
+        if (pageReqVO.getRoleName() != null && !pageReqVO.getRoleName().isEmpty()) {
+            Set<String> roleNameFilters = Arrays.stream(pageReqVO.getRoleName().split(",")).map(String::trim).collect(Collectors.toSet());
+            filteredRespVOList = filteredRespVOList.stream()
+                    .filter(respVO -> {
+                        if (respVO.getRoleNames() == null || respVO.getRoleNames().isEmpty()) {
+                            return false;
+                        }
+                        // 只要角色名称集合中有一个匹配筛选条件,就保留该记录
+                        return roleNameFilters.stream()
+                                .anyMatch(filter -> respVO.getRoleNames().stream()
+                                        .anyMatch(roleName -> roleName.contains(filter)));
+                    })
+                    .collect(Collectors.toList());
+        }
+
+        // 按用户名筛选
+        if (pageReqVO.getUseUserName() != null && !pageReqVO.getUseUserName().isEmpty()) {
+            filteredRespVOList = filteredRespVOList.stream()
+                    .filter(respVO -> {
+                        if (respVO.getUseUserName() == null) {
+                            return false;
+                        }
+                        return respVO.getUseUserName().contains(pageReqVO.getUseUserName());
+                    })
+                    .collect(Collectors.toList());
+        }
+
+        // 按租户名称筛选
+        if (pageReqVO.getUseUserTenantName() != null && !pageReqVO.getUseUserTenantName().isEmpty()) {
+            filteredRespVOList = filteredRespVOList.stream()
+                    .filter(respVO -> {
+                        if (respVO.getUseUserTenantName() == null) {
+                            return false;
+                        }
+                        return respVO.getUseUserTenantName().contains(pageReqVO.getUseUserTenantName());
+                    })
+                    .collect(Collectors.toList());
+        }
+
+        // 4. 对筛选后的结果进行分页
+        int pageNo = pageReqVO.getPageNo();
+        int pageSize = pageReqVO.getPageSize();
+        int total = filteredRespVOList.size();
+        
+        // 计算分页起始位置
+        int start = (pageNo - 1) * pageSize;
+        int end = Math.min(start + pageSize, total);
+        
+        // 截取当前页数据
+        List<InviteCodeRespVO> pagedList = (start < end) ? filteredRespVOList.subList(start, end) : Collections.emptyList();
+
+        // 5. 返回正确的分页结果
+        return new PageResult<>(pagedList, (long) total);
     }
 
 }

+ 20 - 4
byzs-web/src/main/java/cn/iocoder/byzs/module/web/controller/admin/user/vo/WebUserVO.java

@@ -1,10 +1,11 @@
 package cn.iocoder.byzs.module.web.controller.admin.user.vo;
 
 import cn.iocoder.byzs.module.system.enums.common.SexEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.Set;
 
 /**
  * 用户 DO
@@ -50,12 +51,27 @@ public class WebUserVO {
      */
     private String avatar;
 
-    @Schema(description = "课程权限过期时间")
+    /**
+     * 是否是注册用户
+     * 是:权限有效期
+     * 否:针对平台权限
+     */
+    private Boolean isRegister;
+
+    /**
+     * 角色路由
+     */
+    private Set<String> roleRouteSet;
+
+    //课程权限过期时间
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime courseExpireTime;
 
-    @Schema(description = "编程课权限过期时间")
+    //编程课权限过期时间
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime blocklyExpireTime;
 
-    @Schema(description = "AI实验课权限过期时间")
+    //AI实验课权限过期时间
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime aiCourseExpireTime;
 }

+ 20 - 18
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/login/WebLoginServiceImpl.java

@@ -2,14 +2,15 @@ package cn.iocoder.byzs.module.web.service.login;
 
 import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
+import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthLoginRespVO;
 import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
 import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodeSaveReqVO;
 import cn.iocoder.byzs.module.system.controller.admin.userwebexpiretime.vo.UserWebExpireTimeSaveReqVO;
 import cn.iocoder.byzs.module.system.dal.dataobject.dict.DictDataDO;
 import cn.iocoder.byzs.module.system.dal.dataobject.invitecode.InviteCodeDO;
 import cn.iocoder.byzs.module.system.dal.dataobject.permission.RoleDO;
-import cn.iocoder.byzs.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.byzs.module.system.dal.dataobject.userwebexpiretime.UserWebExpireTimeDO;
+import cn.iocoder.byzs.module.system.service.auth.AdminAuthService;
 import cn.iocoder.byzs.module.system.service.dict.DictDataService;
 import cn.iocoder.byzs.module.system.service.invitecode.InviteCodeService;
 import cn.iocoder.byzs.module.system.service.permission.PermissionService;
@@ -44,6 +45,8 @@ public class WebLoginServiceImpl {
     private InviteCodeService inviteCodeService;
     @Resource
     private UserWebExpireTimeService userWebExpireTimeService;
+    @Resource
+    private AdminAuthService authService;
 
 
     @Transactional(rollbackFor = Exception.class)
@@ -58,8 +61,12 @@ public class WebLoginServiceImpl {
         // 注册
         AuthRegisterReqVO registerReqVo = new AuthRegisterReqVO();
         BeanUtils.copyProperties(registerVO, registerReqVo);
-        Long userId = userService.registerUser(registerReqVo);
-        AdminUserDO user = userService.getUser(userId);
+//        Long userId = userService.registerUser(registerReqVo);
+        AuthLoginRespVO register = authService.register(registerReqVo);
+        Long userId = register.getUserId();
+
+        //租户id有问题
+//        AdminUserDO user = userService.getUser(userId);
         Set<Long> roleIds = Arrays.stream(inviteCode.getRoleIds().split(","))
                 .map(s ->Long.parseLong(s.trim())).collect(Collectors.toSet());
         permissionService.assignUserRole(userId, roleIds);
@@ -68,10 +75,10 @@ public class WebLoginServiceImpl {
         inviteCodeService.updateInviteCode(new InviteCodeSaveReqVO()
                         .setId(inviteCode.getId())
                         .setUseUserId(userId)
-                        .setUseUserTenantId(user.getTenantId())
+                        .setUseUserTenantId(null)
                         .setUseTime(LocalDateTime.now())
                         .setExpireTime(LocalDateTime.now().plusDays(inviteCode.getValidTime()))
-                        .setStatus("2"));
+                        .setStatus("1"));
 
 
         List<RoleDO> roleList = roleService.getRoleList(roleIds);
@@ -112,7 +119,6 @@ public class WebLoginServiceImpl {
             }
             userWebExpireTimeService.createUserWebExpireTime(userWebExpireTimeDO);
         }
-
         // 用户id
         return userId;
     }
@@ -137,26 +143,22 @@ public class WebLoginServiceImpl {
         }
 
         // 获得用户激活的邀请码
-//        List<InviteCodeDO> inviteCodes = inviteCodeService.getInviteCodeByUserId(userId);
-//        inviteCodes.removeIf(inviteCode -> "1".equals(inviteCode.getStatus()));
-//        Set<Long> codeRoleIds = new HashSet<>();
-//        inviteCodes.forEach(role -> {
-//            codeRoleIds.addAll(Arrays.stream(role.getRoleIds().split(","))
-//                    .map(s ->Long.parseLong(s.trim())).collect(Collectors.toSet()));
-//        });
-
-        //处理邀请码过期内容
+        List<InviteCodeDO> inviteCodes = inviteCodeService.getInviteCodeByUserId(userId);
+        if (inviteCodes.isEmpty()) {
+            return roleRouteSet;
+        }
+
         //当前用户web过期时间
         UserWebExpireTimeDO userWebExpireTime = userWebExpireTimeService.getUserWebExpireTime(userId);
         if (userWebExpireTime != null) {
             LocalDateTime now = LocalDateTime.now();
-            if(userWebExpireTime.getCourseExpireTime() != null && userWebExpireTime.getCourseExpireTime().isBefore(now)){
+            if(userWebExpireTime.getCourseExpireTime() == null || userWebExpireTime.getCourseExpireTime().isBefore(now)){
                 roleRouteSet.remove("course");
             }
-            if(userWebExpireTime.getBlocklyExpireTime() != null && userWebExpireTime.getBlocklyExpireTime().isBefore(now)){
+            if(userWebExpireTime.getBlocklyExpireTime() == null || userWebExpireTime.getBlocklyExpireTime().isBefore(now)){
                 roleRouteSet.remove("blockly");
             }
-            if(userWebExpireTime.getAiCourseExpireTime() != null && userWebExpireTime.getAiCourseExpireTime().isBefore(now)){
+            if(userWebExpireTime.getAiCourseExpireTime() == null || userWebExpireTime.getAiCourseExpireTime().isBefore(now)){
                 roleRouteSet.remove("aiCourse");
             }
         }

+ 67 - 13
byzs-web/src/main/java/cn/iocoder/byzs/module/web/service/user/WebUserInfoServiceImpl.java

@@ -1,14 +1,19 @@
 package cn.iocoder.byzs.module.web.service.user;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.byzs.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
 import cn.iocoder.byzs.framework.web.core.util.WebFrameworkUtils;
 import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodeSaveReqVO;
 import cn.iocoder.byzs.module.system.controller.admin.userwebexpiretime.vo.UserWebExpireTimeSaveReqVO;
 import cn.iocoder.byzs.module.system.dal.dataobject.invitecode.InviteCodeDO;
 import cn.iocoder.byzs.module.system.dal.dataobject.permission.RoleDO;
+import cn.iocoder.byzs.module.system.dal.dataobject.permission.UserRoleDO;
 import cn.iocoder.byzs.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.byzs.module.system.dal.dataobject.userwebexpiretime.UserWebExpireTimeDO;
+import cn.iocoder.byzs.module.system.dal.mysql.permission.UserRoleMapper;
 import cn.iocoder.byzs.module.system.service.invitecode.InviteCodeService;
 import cn.iocoder.byzs.module.system.service.permission.PermissionService;
 import cn.iocoder.byzs.module.system.service.permission.RoleService;
@@ -21,13 +26,12 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.byzs.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.USER_CODE_FAILURE;
 
 @Service
@@ -44,6 +48,10 @@ public class WebUserInfoServiceImpl {
     private RoleService roleService;
     @Resource
     private UserWebExpireTimeService userWebExpireTimeService;
+    @Resource
+    private WebLoginServiceImpl webLoginServiceImpl;
+    @Resource
+    private UserRoleMapper userRoleMapper;
 
 
     @Transactional(rollbackFor = Exception.class)
@@ -60,7 +68,20 @@ public class WebUserInfoServiceImpl {
         //补充用户角色
         Long userId = WebFrameworkUtils.getLoginUserId();
         AdminUserDO user = userService.getUser(userId);
-        permissionService.assignUserRole(userId, codeRoleIds);
+//        permissionService.assignUserRole(userId, codeRoleIds);
+
+        // 获得角色拥有角色编号
+        Set<Long> dbRoleIds = convertSet(userRoleMapper.selectListByUserId(userId),
+                UserRoleDO::getRoleId);
+        Collection<Long> createRoleIds = CollUtil.subtract(codeRoleIds, dbRoleIds);
+        if (!CollectionUtil.isEmpty(createRoleIds)) {
+            userRoleMapper.insertBatch(CollectionUtils.convertList(createRoleIds, roleId -> {
+                UserRoleDO entity = new UserRoleDO();
+                entity.setUserId(userId);
+                entity.setRoleId(roleId);
+                return entity;
+            }));
+        }
 
         // 更新邀请码为已使用
         inviteCodeService.updateInviteCode(new InviteCodeSaveReqVO()
@@ -69,7 +90,7 @@ public class WebUserInfoServiceImpl {
                 .setUseUserTenantId(user.getTenantId())
                 .setUseTime(LocalDateTime.now())
                 .setExpireTime(LocalDateTime.now().plusDays(inviteCodeDo.getValidTime()))
-                .setStatus("2"));
+                .setStatus("1"));
 
         // 更新用户web过期时间
         List<RoleDO> roleList = roleService.getRoleList(codeRoleIds);
@@ -85,13 +106,25 @@ public class WebUserInfoServiceImpl {
         UserWebExpireTimeDO userWebExpireTime = userWebExpireTimeService.getUserWebExpireTime(userId);
         if (userWebExpireTime != null) {
             if(roleWebMap.contains("course")){
-                userWebExpireTime.setCourseExpireTime(userWebExpireTime.getCourseExpireTime().plusDays(inviteCodeDo.getValidTime()));
+                LocalDateTime courseExpireTime = userWebExpireTime.getCourseExpireTime();
+                if(courseExpireTime == null){
+                    courseExpireTime = LocalDateTime.now();
+                }
+                userWebExpireTime.setCourseExpireTime(courseExpireTime.plusDays(inviteCodeDo.getValidTime()));
             }
             if(roleWebMap.contains("blockly")){
-                userWebExpireTime.setBlocklyExpireTime(userWebExpireTime.getBlocklyExpireTime().plusDays(inviteCodeDo.getValidTime()));
+                LocalDateTime blocklyExpireTime = userWebExpireTime.getBlocklyExpireTime();
+                if(blocklyExpireTime == null){
+                    blocklyExpireTime = LocalDateTime.now();
+                }
+                userWebExpireTime.setBlocklyExpireTime(blocklyExpireTime.plusDays(inviteCodeDo.getValidTime()));
             }
             if (roleWebMap.contains("aiCourse")){
-                userWebExpireTime.setAiCourseExpireTime(userWebExpireTime.getAiCourseExpireTime().plusDays(inviteCodeDo.getValidTime()));
+                LocalDateTime aiCourseExpireTime = userWebExpireTime.getAiCourseExpireTime();
+                if(aiCourseExpireTime == null){
+                    aiCourseExpireTime = LocalDateTime.now();
+                }
+                userWebExpireTime.setAiCourseExpireTime(aiCourseExpireTime.plusDays(inviteCodeDo.getValidTime()));
             }
 
             // 更新用户web过期时间
@@ -115,18 +148,39 @@ public class WebUserInfoServiceImpl {
         return true;
     }
 
+    // 中文年月日格式
+    private static final DateTimeFormatter CHINESE_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
+
     public WebUserVO getUserInfo(Long userId) {
         AdminUserDO user = userService.getUser(userId);
         WebUserVO webUserVO = BeanUtils.toBean(user, WebUserVO.class);
 
+        //平台角色路由
+        Set<String> roleRouteSet = webLoginServiceImpl.getRoleRoute(userId);
+        webUserVO.setRoleRouteSet(roleRouteSet);
+
+        //是否是注册用户
+        List<InviteCodeDO> inviteCodes = inviteCodeService.getInviteCodeByUserId(userId);
+        webUserVO.setIsRegister(!inviteCodes.isEmpty());
+        if (inviteCodes.isEmpty()) {
+            return webUserVO;
+        }
+
         UserWebExpireTimeDO userWebExpireTime = userWebExpireTimeService.getUserWebExpireTime(userId);
         if (userWebExpireTime != null) {
-            webUserVO.setCourseExpireTime(userWebExpireTime.getCourseExpireTime());
-            webUserVO.setBlocklyExpireTime(userWebExpireTime.getBlocklyExpireTime());
-            webUserVO.setAiCourseExpireTime(userWebExpireTime.getAiCourseExpireTime());
+            // 将LocalDateTime格式化为中文年月日字符串
+            if (userWebExpireTime.getCourseExpireTime() != null) {
+                webUserVO.setCourseExpireTime(userWebExpireTime.getCourseExpireTime());
+            }
+            if (userWebExpireTime.getBlocklyExpireTime() != null) {
+                webUserVO.setBlocklyExpireTime(userWebExpireTime.getBlocklyExpireTime());
+            }
+            if (userWebExpireTime.getAiCourseExpireTime() != null) {
+                webUserVO.setAiCourseExpireTime(userWebExpireTime.getAiCourseExpireTime());
+            }
         }
 
         // 用户id
         return webUserVO;
     }
-}
+}