Browse Source

feat 角色权限接口以及权限完善

classic_blue 1 month ago
parent
commit
8aa3ed8ccd
51 changed files with 1897 additions and 379 deletions
  1. 15 0
      edu-travel-common/edu-travel-common-constant/src/main/java/edu/travel/RedisKeyConstant.java
  2. 5 0
      edu-travel-common/edu-travel-common-core/pom.xml
  3. 40 0
      edu-travel-common/edu-travel-common-core/src/main/java/edu/travel/utils/tree/MyTreeUtil.java
  4. 0 7
      edu-travel-common/edu-travel-common-core/src/main/java/edu/travel/web/BaseController.java
  5. 6 2
      edu-travel-common/edu-travel-common-datasource/src/main/java/edu/travel/config/FieldMetaObjectHandler.java
  6. 21 6
      edu-travel-gateway/src/main/java/edu/travel/filter/GateWayFilter.java
  7. 5 5
      edu-travel-oauth/src/main/java/edu/travel/entity/SysUserRole.java
  8. 16 2
      edu-travel-oauth/src/main/java/edu/travel/service/impl/UserServiceImpl.java
  9. 23 0
      edu-travel-remote/edu-travel-remote-tenant/pom.xml
  10. 15 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/RemoteApplication.java
  11. 33 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AddMenuDto.java
  12. 45 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AddOrUpdateRoleDto.java
  13. 104 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AddOrUpdateTenantDto.java
  14. 8 2
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AssignRolesOrMenusDto.java
  15. 3 2
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/EduTenantPageDto.java
  16. 48 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/SysMenuExtraDataDto.java
  17. 3 4
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/SysMenuPageDto.java
  18. 1 1
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/SysRolePageDto.java
  19. 27 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/AddMenuVo.java
  20. 34 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/AdminInfoRoleMenuVo.java
  21. 11 4
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/EduTenantVo.java
  22. 84 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/MenuTreeVo.java
  23. 51 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/SysMenuExtraDataVo.java
  24. 69 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/SysMenuVo.java
  25. 34 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/SysRoleVo.java
  26. 55 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/SysMenuRemoteController.java
  27. 72 0
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/SysRoleRemoteController.java
  28. 108 2
      edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/TenantRemoteController.java
  29. 7 0
      edu-travel-remote/pom.xml
  30. 10 5
      edu-travel-service/edu-travel-service-tenement/pom.xml
  31. 18 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/EduTenant.java
  32. 17 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/SysMenu.java
  33. 10 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/SysMenuExtraData.java
  34. 17 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/EnableDict.java
  35. 29 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/IsCacheDict.java
  36. 30 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/MenuTypeDict.java
  37. 29 0
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/UserStatusDict.java
  38. 0 22
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/enums/UserStatus.java
  39. 7 4
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/exception/GlobalExceptionHandler.java
  40. 11 3
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/ISysMenuService.java
  41. 6 9
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/ISysRoleService.java
  42. 20 6
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/ITenantService.java
  43. 108 18
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ISysMenuServiceImpl.java
  44. 1 2
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ISysRoleMenuServiceImpl.java
  45. 107 49
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ISysRoleServiceImpl.java
  46. 263 107
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ITenantServiceImpl.java
  47. 40 27
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysMenuController.java
  48. 55 39
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysRoleController.java
  49. 1 1
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysRoleMenuController.java
  50. 1 1
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysUserRoleController.java
  51. 174 49
      edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/TenantController.java

+ 15 - 0
edu-travel-common/edu-travel-common-constant/src/main/java/edu/travel/RedisKeyConstant.java

@@ -0,0 +1,15 @@
+package edu.travel;
+
+/**
+ * RedisKeyConstant 。
+ * <p>
+ * 描述:
+ *
+ * @author huangwenwen
+ * @date 2025/2/10
+ */
+public interface RedisKeyConstant {
+    /**
+     *
+     */
+}

+ 5 - 0
edu-travel-common/edu-travel-common-core/pom.xml

@@ -44,6 +44,11 @@
             <artifactId>jakarta.validation-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>6.0.13.Final</version>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jaxb</groupId>
             <artifactId>jaxb-runtime</artifactId>
         </dependency>

+ 40 - 0
edu-travel-common/edu-travel-common-core/src/main/java/edu/travel/utils/tree/MyTreeUtil.java

@@ -0,0 +1,40 @@
+package edu.travel.utils.tree;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 树形菜单构建工具
+ *
+ * @author Zee
+ * @date 2023/7/20 0020 9:48
+ */
+public class MyTreeUtil {
+    /**
+     * 构建树形工具
+     *
+     * @param resource 数据源
+     * @param <T>      node
+     * @return 树形
+     */
+    public static <T extends TreeNode> List<T> buildTree(List<T> resource) {
+        Map<String, List<TreeNode>> groups = ifNullDefault(resource)
+                .stream()
+                .collect(Collectors.groupingBy(TreeNode::getParentId, LinkedHashMap::new, Collectors.toList()));
+        return resource.stream()
+                .filter(Objects::nonNull)
+                .peek(node -> node.setChildren(groups.get(node.getId())))
+                .filter(TreeNode::getRootNode)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 防止空指针异常处理
+     *
+     * @param list 集合数据
+     * @return 如果为空返
+     */
+    private static <L> List<L> ifNullDefault(List<L> list) {
+        return Optional.ofNullable(list).orElseGet(Collections::emptyList);
+    }
+}

+ 0 - 7
edu-travel-common/edu-travel-common-core/src/main/java/edu/travel/web/BaseController.java

@@ -22,13 +22,6 @@ public class BaseController<T> {
     @Lazy
     private IService<T> service;
 
-
-    /**
-     * 通用根据updateById 更新
-     * @param entity
-     * @param errors
-     * @return
-     */
     @PostMapping("/updateById")
     @Transactional
     public BaseResponse<T> updateTargetById(@Validated(UpdateGroups.class) @RequestBody T entity, Errors errors) {

+ 6 - 2
edu-travel-common/edu-travel-common-datasource/src/main/java/edu/travel/config/FieldMetaObjectHandler.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 import org.apache.ibatis.reflection.MetaObject;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
@@ -25,8 +26,11 @@ public class FieldMetaObjectHandler implements MetaObjectHandler {
     @Override
     public void insertFill(MetaObject metaObject) {
         HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
-        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(principal));
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication == null) return;
+        Object principal = authentication.getPrincipal();
+        String jsonString = JSON.toJSONString(principal);
+        JSONObject jsonObject = JSON.parseObject(jsonString);
         if (metaObject.hasSetter(CREATE_USER_ID)) {
             this.strictInsertFill(metaObject, CREATE_USER_ID, String.class, jsonObject.getLong("id").toString());
         }

+ 21 - 6
edu-travel-gateway/src/main/java/edu/travel/filter/GateWayFilter.java

@@ -1,6 +1,7 @@
 package edu.travel.filter;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.nimbusds.jose.JWSObject;
 import edu.travel.EncryptUtil;
@@ -32,18 +33,32 @@ public class GateWayFilter implements GlobalFilter, Ordered {
             JWSObject jwsObject = JWSObject.parse(realToken);
             String userStr = jwsObject.getPayload().toString();
             JSONObject jsonObject = JSON.parseObject(userStr);
+//            Object object = jsonObject.get(FinalParam.AUTHORITY_CLAIM_NAME);
+//            List<String> authorities = new ArrayList<String>();
+//            if (object != null){
+//                String all = jsonObject.get(FinalParam.AUTHORITY_CLAIM_NAME).toString().replaceAll("\"", "");
+//                String[] split = all.substring(all.indexOf("[") + 1, all.length() - 1).split(",");
+//                authorities = new ArrayList<String>(Arrays.asList(split));
+//            }
             Object object = jsonObject.get(FinalParam.AUTHORITY_CLAIM_NAME);
-            List<String> authorities = null;
-            if (object != null){
-                String all = jsonObject.get(FinalParam.AUTHORITY_CLAIM_NAME).toString().replaceAll("\"", "");
-                String[] split = all.substring(all.indexOf("[") + 1, all.length() - 1).split(",");
-                authorities = new ArrayList<String>(Arrays.asList(split));
+            List<String> authorities = new ArrayList<>();
+
+            if (object != null) {
+                // 如果权限字段是 JSONArray 类型
+                if (object instanceof JSONArray) {
+                    authorities = ((JSONArray) object).toJavaList(String.class);
+                } else {
+                    // 如果权限字段是字符串类型
+                    String authoritiesStr = object.toString();
+                    JSONArray authoritiesArray = JSON.parseArray(authoritiesStr);
+                    authorities = authoritiesArray.toJavaList(String.class);
+                }
             }
-            authorities = new ArrayList<String>();
             String principal = jsonObject.getObject("user_name", String.class);
             String client_id = jsonObject.getObject("client_id", String.class);
             Map<String, Object> map = new HashMap<>();
             //获取权限
+            System.out.println("Authorities: " + authorities);
             map.put("authorities", authorities);
             //获取客户端
             map.put("client_id", client_id);

+ 5 - 5
edu-travel-oauth/src/main/java/edu/travel/entity/SysUserRole.java

@@ -35,9 +35,9 @@ public class SysUserRole implements Serializable {
     @TableField(value = "role_id")
     private Long roleId;
 
-    /**
-     * 项目code
-     */
-    @TableField(value = "project")
-    private String project;
+//    /**
+//     * 项目code
+//     */
+//    @TableField(value = "project")
+//    private String project;
 }

+ 16 - 2
edu-travel-oauth/src/main/java/edu/travel/service/impl/UserServiceImpl.java

@@ -1,5 +1,6 @@
 package edu.travel.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import edu.travel.entity.EduTenant;
@@ -22,6 +23,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 @Service
 public class UserServiceImpl implements UserDetailsService {
@@ -29,6 +32,8 @@ public class UserServiceImpl implements UserDetailsService {
     private EduTenantMapper eduTenantMapper;
     @Autowired
     private RedisTemplate redisTemplate;
+    @Autowired
+    private SysRoleService sysRoleService;
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
         if (StringUtils.isBlank(username)) {
@@ -40,7 +45,8 @@ public class UserServiceImpl implements UserDetailsService {
             throw new UsernameNotFoundException("username not found");
         }
         if ("admin".equals(request.getParameter("loginFrom"))) {
-            return new User(tenant.getTenantPhone(),null,new ArrayList<>());
+            redisTemplate.opsForValue().set(username+"_info", JSON.toJSONString(tenant));
+
         }else {
             String code = request.getParameter("password");
             if (StringUtils.isBlank(code)) {
@@ -52,10 +58,18 @@ public class UserServiceImpl implements UserDetailsService {
             }
             if (code.equals(object.toString())){
                 redisTemplate.opsForValue().set(username+"_info", JSON.toJSONString(tenant));
-                return new User(tenant.getTenantPhone(),code, new ArrayList<>());
+
+                return new User(tenant.getTenantPhone(),code,new ArrayList<>() );
             }
             throw new UsernameNotFoundException("验证码错误");
         }
 
+        List<SysRole> roleList = sysRoleService.getRoleListByUserId(tenant.getId());
+        request.setAttribute("authorities", roleList);
+        Set<String> collect = roleList.stream().map(SysRole::getName).collect(Collectors.toSet());
+        String[] arr = new String[collect.size()];
+        String[] array = collect.toArray(arr);
+        return User.builder().username(tenant.getTenantPhone()).password(tenant.getPassword()).roles(array).build();
+
     }
 }

+ 23 - 0
edu-travel-remote/edu-travel-remote-tenant/pom.xml

@@ -28,5 +28,28 @@
             <artifactId>edu-travel-common-openfeign</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-model-base</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.validation</groupId>
+            <artifactId>jakarta.validation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>6.0.13.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-common-core</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 </project>

+ 15 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/RemoteApplication.java

@@ -0,0 +1,15 @@
+package edu.travel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@EnableDiscoveryClient
+@SpringBootApplication
+public class RemoteApplication
+{
+    public static void main( String[] args )
+    {
+       SpringApplication.run(RemoteApplication.class, args);
+    }
+}

+ 33 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AddMenuDto.java

@@ -0,0 +1,33 @@
+package edu.travel.remote.feign.mode.dto.tenant;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * AddMenuDto 类。
+ * <p>
+ * 描述:
+ *
+ * @author huangwenwen
+ * @date 2025/2/11
+ */
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AddMenuDto {
+
+    /**
+     * 菜单信息
+     */
+    private SysMenuPageDto sysMenu;
+
+    /**
+     * 菜单附加信息
+     */
+    private SysMenuExtraDataDto sysMenuExtraData;
+
+
+}

+ 45 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AddOrUpdateRoleDto.java

@@ -0,0 +1,45 @@
+package edu.travel.remote.feign.mode.dto.tenant;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * AddOrUpdateRoleDto 类。
+ * <p>
+ * 描述:新建角色+分配菜单
+ *
+ * @author huangwenwen
+ * @date 2025/2/14
+ */
+
+@Data
+public class AddOrUpdateRoleDto {
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 角色名称
+     */
+    @NotNull(message = "角色名称不能为空")
+    private String name;
+
+    /**
+     * 角色描述
+     */
+    private String remark;
+
+    /**
+     * 菜单id集合
+     */
+    private List<Long> menuIds;
+
+
+
+}

+ 104 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AddOrUpdateTenantDto.java

@@ -0,0 +1,104 @@
+package edu.travel.remote.feign.mode.dto.tenant;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * AddTenantDto 类。
+ * <p>
+ * 描述:添加用户dto
+ *
+ * @author huangwenwen
+ * @date 2025/2/12
+ */
+
+@Data
+public class AddOrUpdateTenantDto {
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 姓
+     */
+    @NotNull(message = "用户姓不能为空")
+    private String tenantSurname;
+
+    /**
+     * 名
+     */
+    @NotNull(message = "用户名不能为空")
+    private String tenantName;
+
+    /**
+     * 性别 0男 1女
+     */
+    @NotNull(message = "用户性别不能为空")
+    private Integer tenantSex;
+
+    /**
+     * 头像
+     */
+    private String tenantAvatar;
+
+    /**
+     * 手机号
+     */
+    @NotNull(message = "用户手机号不能为空")
+    private String tenantPhone;
+
+    /**
+     * 密码
+     */
+    @NotNull(message = "用户密码不能为空")
+    private String password;
+
+    /**
+     * 地区区号
+     */
+    private String tenantArea;
+
+    /**
+     * 生日日期
+     */
+    private Date tenantBirthday;
+
+    /**
+     * 微信小程序openid
+     */
+    @TableField(value = "tenant_open_id")
+    private String tenantOpenId;
+
+    /**
+     * 微信小程序unionid
+     */
+    @TableField(value = "tenant_unionid")
+    private String tenantUnionid;
+
+    /**
+     * 现实名
+     */
+    @TableField(value = "show_name")
+    private String showName;
+
+    /**
+     * 用户状态
+     */
+    @TableField(value = "user_status")
+    private Integer userStatus;
+
+    /**
+     * 角色列表
+     */
+    private List<Long> roleIds;
+
+
+}

+ 8 - 2
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/dto/AssignRolesOrMenus.java → edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/AssignRolesOrMenusDto.java

@@ -1,6 +1,9 @@
-package edu.travel.tenant.dto;
+package edu.travel.remote.feign.mode.dto.tenant;
 
+import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.List;
 
@@ -15,7 +18,10 @@ import java.util.List;
 
 
 @Data
-public class AssignRolesOrMenus {
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class AssignRolesOrMenusDto {
     /**
      * 角色ids/菜单ids
      */

+ 3 - 2
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/dto/EduTenantPageDto.java → edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/EduTenantPageDto.java

@@ -1,6 +1,7 @@
-package edu.travel.tenant.dto;
+package edu.travel.remote.feign.mode.dto.tenant;
 
 import edu.travel.model.PageDto;
+import lombok.Data;
 
 import java.util.Date;
 
@@ -13,7 +14,7 @@ import java.util.Date;
  * @date 2025/2/10
  */
 
-
+@Data
 public class EduTenantPageDto extends PageDto {
 
     /**

+ 48 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/SysMenuExtraDataDto.java

@@ -0,0 +1,48 @@
+package edu.travel.remote.feign.mode.dto.tenant;
+
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * SysMenuExtraDataDto 类。
+ * <p>
+ * 描述:
+ *
+ * @author huangwenwen
+ * @date 2025/2/15
+ */
+
+@Data
+public class SysMenuExtraDataDto {
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 菜单id
+     */
+    private Long menuId;
+
+    /**
+     * 菜单图标名称
+     */
+    private String icon;
+
+    /**
+     * 菜单显示名称
+     */
+    private String title;
+
+    /**
+     * 是否缓存 0不缓存 1缓存
+     */
+    private Boolean noCache;
+
+    /**
+     * 是否缓存字典
+     */
+    private Map codeIsCacheDict;
+
+}

+ 3 - 4
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/dto/SysMenuPageDto.java → edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/SysMenuPageDto.java

@@ -1,5 +1,6 @@
-package edu.travel.tenant.dto;
+package edu.travel.remote.feign.mode.dto.tenant;
 import edu.travel.model.PageDto;
+import lombok.Data;
 
 /**
  * SysRolePageDto 类。
@@ -10,11 +11,9 @@ import edu.travel.model.PageDto;
  * @date 2025/2/11
  */
 
-
+@Data
 public class SysMenuPageDto extends PageDto {
 
-
-
     /**
      * 主键id
      */

+ 1 - 1
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/dto/SysRolePageDto.java → edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/dto/tenant/SysRolePageDto.java

@@ -1,4 +1,4 @@
-package edu.travel.tenant.dto;
+package edu.travel.remote.feign.mode.dto.tenant;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;

+ 27 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/AddMenuVo.java

@@ -0,0 +1,27 @@
+package edu.travel.remote.feign.mode.vo.tenant;
+
+import lombok.Data;
+
+/**
+ * AddMenuVo 类。
+ * <p>
+ * 描述:新增菜单回显
+ *
+ * @author huangwenwen
+ * @date 2025/2/14
+ */
+
+@Data
+public class AddMenuVo {
+
+    /**
+     * 菜单信息
+     */
+    private SysMenuVo sysMenu;
+
+    /**
+     * 菜单附加信息
+     */
+    private SysMenuExtraDataVo sysMenuExtraData;
+
+}

+ 34 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/AdminInfoRoleMenuVo.java

@@ -0,0 +1,34 @@
+package edu.travel.remote.feign.mode.vo.tenant;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * AdminInfoRoleMenuVo 类。
+ * <p>
+ * 描述:管理用户的信息角色菜单信息
+ *
+ * @author huangwenwen
+ * @date 2025/2/13
+ */
+
+@Data
+public class AdminInfoRoleMenuVo {
+
+    /**
+     * 管理员信息
+     */
+    private EduTenantVo tenantVo;
+
+    /**
+     * 角色信息
+     */
+    private List<SysRoleVo> roleVoList;
+
+    /**
+     * 菜单信息
+     */
+    private List<MenuTreeVo> menuTreeVo;
+
+}

+ 11 - 4
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/vo/EduTenantVo.java → edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/EduTenantVo.java

@@ -1,9 +1,10 @@
-package edu.travel.tenant.vo;
+package edu.travel.remote.feign.mode.vo.tenant;
 
 import edu.travel.entity.BaseEntity;
 import lombok.Data;
 
 import java.util.Date;
+import java.util.Map;
 
 /**
  * TenantVo 类。
@@ -19,7 +20,7 @@ public class EduTenantVo extends BaseEntity {
     /**
      * 主键
      */
-    private Long id;
+    private String id;
 
     /**
      * 姓
@@ -77,7 +78,13 @@ public class EduTenantVo extends BaseEntity {
     private Integer userStatus;
 
     /**
-     * 用户所有状态 1正常 2冻结 2已删除
+     * 用户性别字典
      */
-    private Integer status;
+    private Map codeSexDict;
+
+    /**
+     * 用户状态字典
+     */
+    private Map codeUserStatusDict;
+
 }

+ 84 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/MenuTreeVo.java

@@ -0,0 +1,84 @@
+package edu.travel.remote.feign.mode.vo.tenant;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import edu.travel.entity.BaseEntity;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * MenuTree 类。
+ * <p>
+ * 描述:菜单树
+ *
+ * @author huangwenwen
+ * @date 2025/2/11
+ */
+
+@Data
+public class MenuTreeVo extends BaseEntity {
+    /**
+     * 主键id
+     */
+    private String id;
+
+    /**
+     * 父菜单id,目录菜单的父菜单为null
+     */
+    private String parentId;
+
+    /**
+     * 前端表单路由名称,仅用于menu_type为1的菜单类型
+     */
+    private String title;
+
+    /**
+     * (0: 目录 1: 菜单 2: 按钮 )
+     */
+    private Integer type;
+
+    /**
+     * 组件路径
+     */
+    private String component;
+
+    /**
+     * 页面路由
+     */
+    private String path;
+
+    /**
+     * 组件名称
+     */
+    private String name;
+
+    /**
+     * 菜单状态 0禁用1启用
+     */
+    private Byte status;
+
+    /**
+     * 附加信息
+     */
+    private SysMenuExtraDataVo extraData;
+
+    /**
+     * 子菜单
+     */
+    private List<MenuTreeVo> children = new ArrayList<>();
+
+    /**
+     * 是否启用字典
+     */
+    private Map codeEnableDict;
+
+    /**
+     * 是否缓存字典
+     */
+    private Map codeMenuTypeDict;
+
+}

+ 51 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/SysMenuExtraDataVo.java

@@ -0,0 +1,51 @@
+package edu.travel.remote.feign.mode.vo.tenant;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * SysMenuExtraDataVo 类。
+ * <p>
+ * 描述:
+ *
+ * @author huangwenwen
+ * @date 2025/2/15
+ */
+
+@Data
+public class SysMenuExtraDataVo {
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 菜单id
+     */
+    private Long menuId;
+
+    /**
+     * 菜单图标名称
+     */
+    private String icon;
+
+    /**
+     * 菜单显示名称
+     */
+    private String title;
+
+    /**
+     * 是否缓存 0不缓存 1缓存
+     */
+    private Boolean noCache;
+
+    /**
+     * 是否缓存字典
+     */
+    private Map codeIsCacheDict;
+
+}

+ 69 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/SysMenuVo.java

@@ -0,0 +1,69 @@
+package edu.travel.remote.feign.mode.vo.tenant;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import edu.travel.entity.BaseEntity;
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * SysMenuVo 类。
+ * <p>
+ * 描述:
+ *
+ * @author huangwenwen
+ * @date 2025/2/12
+ */
+
+@Data
+public class SysMenuVo extends BaseEntity {
+    /**
+     * 主键id
+     */
+    private String id;
+
+    /**
+     * 父菜单id,目录菜单的父菜单为null
+     */
+    private String parentId;
+
+    /**
+     * 前端表单路由名称,仅用于menu_type为1的菜单类型
+     */
+    private String title;
+
+    /**
+     * (0: 目录 1: 菜单 2: 按钮 )
+     */
+    private Integer type;
+
+    /**
+     * 组件路径
+     */
+    private String component;
+
+    /**
+     * 页面路由
+     */
+    private String path;
+
+    /**
+     * 组件名称
+     */
+    private String name;
+
+    /**
+     * 菜单状态 0禁用1启用
+     */
+    private Byte status;
+
+    /**
+     * 是否启用字典
+     */
+    private Map codeEnableDict;
+
+    /**
+     * 是否缓存字典
+     */
+    private Map codeMenuTypeDict;
+}

+ 34 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/remote/feign/mode/vo/tenant/SysRoleVo.java

@@ -0,0 +1,34 @@
+package edu.travel.remote.feign.mode.vo.tenant;
+
+import edu.travel.entity.BaseEntity;
+import lombok.Data;
+
+/**
+ * SysRoloVo 类。
+ * <p>
+ * 描述:
+ *
+ * @author huangwenwen
+ * @date 2025/2/12
+ */
+
+@Data
+public class SysRoleVo extends BaseEntity {
+    /**
+     * 主键id
+     */
+    private String id;
+
+    /**
+     * 角色名称
+     */
+    private String name;
+
+    /**
+     * 角色描述
+     */
+    private String remark;
+
+}
+
+

+ 55 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/SysMenuRemoteController.java

@@ -0,0 +1,55 @@
+package edu.travel.tenant;
+
+import edu.travel.remote.feign.mode.dto.tenant.AddMenuDto;
+import edu.travel.remote.feign.mode.dto.tenant.SysMenuPageDto;
+import edu.travel.remote.feign.mode.vo.tenant.AddMenuVo;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
+import edu.travel.resp.BaseResponse;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(name = "tenant",path = "/sysMenu")
+public interface SysMenuRemoteController {
+
+    /**
+     * 新增菜单
+     */
+    @PostMapping("/addMenu")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<AddMenuVo> addMenu(@RequestBody AddMenuDto addMenuDto);
+
+    /**
+     * 删除菜单单个
+     */
+
+    @PostMapping("/deleteMenuById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteMenuById(@RequestParam Long id) ;
+
+    /**
+     * 删除菜单多个
+     */
+    @PostMapping("/deleteMenuByIds")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteMenuByIds(@RequestBody List<Long> ids );
+
+    /**
+     * 获取菜单分页树形列表
+     */
+    @GetMapping("/getMenuTreeListAll")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<MenuTreeVo>> getMenuTreeListAll(SysMenuPageDto sysMenuPageDto);
+
+    /**
+     * 通过菜单id修改菜单
+     */
+    @PostMapping("/updateMenuById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateMenuById( @RequestBody AddMenuDto updateMenuDto);
+
+}

+ 72 - 0
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/SysRoleRemoteController.java

@@ -0,0 +1,72 @@
+package edu.travel.tenant;
+
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateRoleDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
+import edu.travel.remote.feign.mode.dto.tenant.SysRolePageDto;
+import edu.travel.remote.feign.mode.vo.tenant.SysRoleVo;
+import edu.travel.resp.BaseResponse;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(name = "tenant",path = "/sysRole")
+public interface SysRoleRemoteController {
+    /**
+     * 新增管理角色并分配菜单
+     */
+    @PostMapping("/addRoleAndAssignMenus")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<SysRoleVo> addRoleAndAssignMenus(@RequestBody AddOrUpdateRoleDto addOrUpdateRoleDto);
+
+    /**
+     * 删除角色多个
+     */
+    @PostMapping("/deleteRoleByIds")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteRoleByIds(@RequestBody List<Long> ids);
+
+    /**
+     * 删除角色单个
+     */
+    @PostMapping("/deleteRoleById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteRoleById(@RequestParam Long id);
+
+    /**
+     * 更新角色和角色下菜单
+     */
+    @PostMapping("/updateRoleAndMenusById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateRoleAndMenusById( @RequestBody AddOrUpdateRoleDto addOrUpdateRoleDto);
+
+    /**
+     * 为角色分配菜单
+     * @param dto
+     * @return
+     */
+    @PostMapping("/assignMenusToRole")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> assignMenusToRole(@RequestBody AssignRolesOrMenusDto dto);
+
+    /**
+     * 更新角色菜单
+     * @param assignRolesOrMenusDto
+     * @return
+     */
+    @PostMapping("/updateMenusToRole")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateMenusToRole(@RequestBody AssignRolesOrMenusDto assignRolesOrMenusDto);
+
+    /**
+     * 分页查询角色列表
+     * @param sysRolePageDto
+     * @return
+     */
+    @GetMapping("/getRolePageList")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<SysRoleVo>> getRolePageList(SysRolePageDto sysRolePageDto);
+}

+ 108 - 2
edu-travel-remote/edu-travel-remote-tenant/src/main/java/edu/travel/tenant/TenantRemoteController.java

@@ -1,11 +1,117 @@
 package edu.travel.tenant;
 
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateTenantDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
+import edu.travel.remote.feign.mode.dto.tenant.EduTenantPageDto;
+import edu.travel.remote.feign.mode.vo.tenant.AdminInfoRoleMenuVo;
+import edu.travel.remote.feign.mode.vo.tenant.EduTenantVo;
+import edu.travel.remote.feign.mode.vo.tenant.SysRoleVo;
 import edu.travel.resp.BaseResponse;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import java.util.List;
 
-@FeignClient
+@FeignClient(value = "/tenant",path = "/user")
 public interface TenantRemoteController {
+
     @GetMapping("/getTenantByPhoneNumber")
-    public BaseResponse getTenantByPhoneNumber();
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<EduTenantVo> getTenantByPhoneNumber();
+
+    /**
+     * 新增用户
+     */
+    @PostMapping("/addTenant")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<EduTenantVo> addTenant(@RequestBody AddOrUpdateTenantDto addOrUpdateTenantDto);
+
+    /**
+     * 通过ids删除用户
+     */
+    @PostMapping("/deleteTenantByIds")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteTenant(@RequestBody List<Long> ids);
+    /**
+     * 通过id删除用户
+     */
+    @PostMapping("/deleteTenantById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteTenant(Long id);
+
+    /**
+     * 修改用户信息
+     */
+    @PostMapping("/updateTenantById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateTenant(@RequestBody AddOrUpdateTenantDto addOrUpdateTenantDto);
+    /**
+     * 通过id查询商城用户信息
+     */
+    @GetMapping("/getTenantById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<SysRoleVo> getTenantById(Long id);
+
+
+    /**
+     * 获取用户分页列表
+     */
+    @GetMapping("/getTenantPageList")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<EduTenantVo>> getTenantList(EduTenantPageDto tenantDto);
+
+    /**
+     * 根据用户id获取用户角色列表(未分页)
+     */
+    @GetMapping("/getRoleListByUserId")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<SysRoleVo>> getRoleListByUserId();
+
+    /**
+     * 根据用户id给用户分配角色(可以多个角色)
+     */
+    @PostMapping("/assignRolesToUser")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> assignRolesToUser(@RequestBody AssignRolesOrMenusDto assignRolesOrMenusDto);
+
+    /**
+     * 根据用户id给用户修改角色(可以多个角色)
+     */
+    @PostMapping("updateRolesToUser")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateRolesToUser(@RequestBody AssignRolesOrMenusDto assignRolesOrMenusDto);
+
+    /**
+     * 获取管理用户的信息、角色列表、菜单树形
+     */
+    @GetMapping("/getTenantInfoRoleListMenuTree")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<AdminInfoRoleMenuVo> getTenantInfoRoleListMenuTree();
+    /**
+     * 单个禁用用户
+     */
+    @PostMapping("/disableTenantById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> disableTenantById(Long id);
+
+    /**
+     * 单个启用用户
+     */
+    @PostMapping("/enableTenantById")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> enableTenantById(Long id);
+    /**
+     * 批量启用用户
+     */
+    @PostMapping("/enableTenantByIds")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> enableTenantByIds(@RequestBody List<Long> ids);
+
+    /**
+     * 批量禁用用户
+     */
+    @PostMapping("/disableTenantByIds")
+//    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> disableTenantByIds(@RequestBody List<Long> ids);
 }

+ 7 - 0
edu-travel-remote/pom.xml

@@ -19,5 +19,12 @@
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
+    <dependencies>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-model-base</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
 
 </project>

+ 10 - 5
edu-travel-service/edu-travel-service-tenement/pom.xml

@@ -90,11 +90,11 @@
             <groupId>com.alibaba.csp</groupId>
             <artifactId>sentinel-web-servlet</artifactId>
         </dependency>
-                <dependency>
-                    <groupId>edu.travel</groupId>
-                    <artifactId>edu-travel-remote-tenant</artifactId>
-                    <version>1.0-SNAPSHOT</version>
-                </dependency>
+        <dependency>
+            <groupId>edu.travel</groupId>
+            <artifactId>edu-travel-remote-tenant</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>edu.travel</groupId>
             <artifactId>edu-travel-common-util</artifactId>
@@ -131,6 +131,11 @@
             <version>1.2.6</version>
             <scope>compile</scope>
         </dependency>
+<!--        <dependency>-->
+<!--            <groupId>jakarta.validation</groupId>-->
+<!--            <artifactId>jakarta.validation-api</artifactId>-->
+<!--        </dependency>-->
+
     </dependencies>
     <profiles>
         <profile>

+ 18 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/EduTenant.java

@@ -5,8 +5,12 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import java.util.Date;
+import java.util.Map;
 
+import edu.travel.annotation.LinkConst;
 import edu.travel.entity.BaseEntity;
+import edu.travel.tenant.entity.dict.SexDict;
+import edu.travel.tenant.entity.dict.UserStatusDict;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -93,4 +97,18 @@ public class EduTenant extends BaseEntity {
      */
     @TableField(value = "user_status")
     private Integer userStatus;
+
+    /**
+     * 性别字典
+     */
+    @TableField(exist = false)
+    @LinkConst(fieldName = "tenantSex",clazz = SexDict.class)
+    private Map codeSexDict;
+
+    /**
+     * 用户状态字典
+     */
+    @TableField(exist = false)
+    @LinkConst(fieldName = "userStatus",clazz = UserStatusDict.class)
+    private Map codeUserStatusDict;
 }

+ 17 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/SysMenu.java

@@ -7,8 +7,11 @@ import com.baomidou.mybatisplus.annotation.TableName;
 
 import java.io.Serializable;
 import java.util.Date;
+import java.util.Map;
 
+import edu.travel.annotation.LinkConst;
 import edu.travel.entity.BaseEntity;
+import edu.travel.tenant.entity.dict.EnableDict;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -69,4 +72,18 @@ public class SysMenu extends BaseEntity implements Serializable {
     @TableField(value = "`status`")
     private Byte status;
 
+    /**
+     * 菜单是否启用
+     */
+    @TableField(exist = false)
+    @LinkConst(fieldName = "status",clazz = EnableDict.class)
+    private Map codeEnableDict;
+
+    /**
+     * 是否缓存字典
+     */
+    @TableField(exist = false)
+    @LinkConst(fieldName = "type",clazz = EnableDict.class)
+    private Map codeMenuTypeDict;
+
 }

+ 10 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/SysMenuExtraData.java

@@ -7,8 +7,11 @@ import com.baomidou.mybatisplus.annotation.TableName;
 
 import java.io.Serializable;
 import java.util.Date;
+import java.util.Map;
 
+import edu.travel.annotation.LinkConst;
 import edu.travel.entity.BaseEntity;
+import edu.travel.tenant.entity.dict.IsCacheDict;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -51,4 +54,11 @@ public class SysMenuExtraData extends BaseEntity implements Serializable {
     @TableField(value = "no_cache")
     private Boolean noCache;
 
+    /**
+     * 是否缓存字典
+     */
+    @TableField(exist = false)
+    @LinkConst(fieldName = "noCache",clazz = IsCacheDict.class)
+    private Map codeIsCacheDict;
+
 }

+ 17 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/EnableDict.java

@@ -0,0 +1,17 @@
+package edu.travel.tenant.entity.dict;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EnableDict {
+
+    private final  Map<Integer,String> EnableDict = new HashMap<Integer,String>();
+
+    public EnableDict(){
+        EnableDict.put(0,"禁用");
+        EnableDict.put(1,"启用");
+    }
+    public String getValue(Integer key){
+        return EnableDict.containsKey(key) ?  EnableDict.get(key) : null;
+    }
+}

+ 29 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/IsCacheDict.java

@@ -0,0 +1,29 @@
+package edu.travel.tenant.entity.dict;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * IsCacheDict 类。
+ * <p>
+ * 描述:是否缓存 (0: 不缓存  1:缓存)
+ *
+ * @author huangwenwen
+ * @date 2025/2/14
+ */
+
+
+public class IsCacheDict {
+
+    private final Map<Integer,String> IsCacheDict = new HashMap<>();
+
+    public IsCacheDict(){
+        IsCacheDict.put(0,"不缓存");
+        IsCacheDict.put(1,"缓存");
+    }
+
+    public String getValue(Integer key){
+        return IsCacheDict.containsKey(key) ? IsCacheDict.get(key):null;
+    }
+
+}

+ 30 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/MenuTypeDict.java

@@ -0,0 +1,30 @@
+package edu.travel.tenant.entity.dict;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * MenuTypeDict 类。
+ * <p>
+ * 描述:后台管理菜单类型 (0: 目录 1: 菜单 2: 按钮 )
+ *
+ * @author huangwenwen
+ * @date 2025/2/14
+ */
+
+
+public class MenuTypeDict {
+
+    private final Map<Integer,String> menuTypeDict = new HashMap<>();
+
+    public MenuTypeDict(){
+        menuTypeDict.put(0,"目录");
+        menuTypeDict.put(1,"菜单");
+        menuTypeDict.put(2,"按钮");
+    }
+
+    public String getValue(Integer key){
+        return menuTypeDict.containsKey(key) ? menuTypeDict.get(key):null;
+    }
+
+}

+ 29 - 0
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/entity/dict/UserStatusDict.java

@@ -0,0 +1,29 @@
+package edu.travel.tenant.entity.dict;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * UserStatusDict 类。
+ * <p>
+ * 描述:用户状态常量字典
+ *
+ * @author huangwenwen
+ * @date 2025/2/14
+ */
+
+
+public class UserStatusDict {
+
+    private final Map<Integer,String> userStatusMap = new HashMap<>();
+
+    public UserStatusDict(){
+        userStatusMap.put(0,"禁用");
+        userStatusMap.put(1,"启用");
+    }
+
+    public String getValue(Integer key){
+        return userStatusMap.containsKey(key)?userStatusMap.get(key):null;
+    }
+
+}

+ 0 - 22
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/enums/UserStatus.java

@@ -1,22 +0,0 @@
-package edu.travel.tenant.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-
-
-/**
- * 用户状态
- */
-
-@Getter
-@AllArgsConstructor
-public enum UserStatus {
-    USER_STATUS_NORMAL(1,"正常"),
-    USER_STATUS_DISABLED(2,"禁用"),
-    USER_STATUS_DELETED(3,"删除");
-
-    private Integer code;
-    private String message;
-
-}

+ 7 - 4
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/exception/GlobalExceptionHandler.java

@@ -4,7 +4,9 @@ import edu.travel.emun.ResponseCode;
 import edu.travel.exception.BaseException;
 import edu.travel.resp.BaseResponse;
 import edu.travel.resp.PageResponse;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
 
 /**
  * GlobalExceptionHandler 类。
@@ -15,7 +17,8 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
  * @date 2025/2/11
  */
 
-
+@RestControllerAdvice
+@Slf4j
 public class GlobalExceptionHandler {
 
     @ExceptionHandler(BaseException.class)
@@ -24,15 +27,15 @@ public class GlobalExceptionHandler {
         return  PageResponse.out(e.getCode(),e.getMessage(),null);
     }
 
-    @ExceptionHandler(IllegalAccessException.class)
-    public BaseResponse<Object> handleException(IllegalAccessException e){
+    @ExceptionHandler(IllegalArgumentException.class)
+    public BaseResponse<Object> handleException(IllegalArgumentException e){
         e.printStackTrace();
         return PageResponse.out(ResponseCode.LOGIC_ERROR.getCode(), e.getMessage(),null);
     }
 
     @ExceptionHandler(Throwable.class)
     public BaseResponse<Object> handleException(Exception e){
-                e.printStackTrace();
+        e.printStackTrace();
         return PageResponse.out(ResponseCode.ERROR.getCode(),e.getMessage(),null);
     }
 

+ 11 - 3
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/ISysMenuService.java

@@ -1,16 +1,24 @@
 package edu.travel.tenant.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
+import edu.travel.remote.feign.mode.dto.tenant.AddMenuDto;
+import edu.travel.remote.feign.mode.vo.tenant.AddMenuVo;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
+import edu.travel.remote.feign.mode.vo.tenant.SysMenuExtraDataVo;
 import edu.travel.tenant.entity.SysMenu;
+import edu.travel.tenant.entity.SysMenuExtraData;
 
 import java.util.List;
+import java.util.Set;
 
 public interface ISysMenuService extends IService<SysMenu> {
 
-    void addMenu(SysMenu sysMenu);
+    AddMenuVo addMenu(AddMenuDto addMenuDto );
 
-    void deleteMenuByIds(List<Long> ids);
+    void deleteMenuByIds(Set<Long> ids);
 
+    List<MenuTreeVo> getMenuTreeListAll(List<SysMenu> records);
 
+    void updateMenuById(AddMenuDto updateMenuDto);
+     List<MenuTreeVo> buildMenuTree(List<SysMenu> sysMenuList, List<SysMenuExtraDataVo> menuExtraDataList) ;
 }

+ 6 - 9
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/ISysRoleService.java

@@ -1,26 +1,23 @@
 package edu.travel.tenant.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import edu.travel.resp.BaseResponse;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateRoleDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
 import edu.travel.tenant.entity.EduTenant;
 import edu.travel.tenant.entity.SysRole;
 
-import java.util.List;
 import java.util.Set;
 
 
 public interface ISysRoleService extends IService<SysRole> {
 
-    Boolean add(SysRole sysRole, EduTenant principal);
+    SysRole addRoleAndAssignMenus(AddOrUpdateRoleDto addOrUpdateRoleDto, EduTenant principal);
 
     void deleteByIds(Set<Long> ids);
 
-    void updateRoleById(SysRole sysRole);
+    void updateRoleAndMenusById( AddOrUpdateRoleDto addOrUpdateRoleDto);
 
-    void deleteById(Long id);
+    void assignMenusToRole(AssignRolesOrMenusDto dto, EduTenant principal);
 
-    List<SysRole> getRoleByUserId(Long userId);
-
-    void assignMenusToRole(AssignRolesOrMenus dto);
+    void updateMenusToRole(AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal);
 }

+ 20 - 6
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/ITenantService.java

@@ -1,22 +1,26 @@
 package edu.travel.tenant.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateTenantDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
 import edu.travel.tenant.entity.EduTenant;
 import edu.travel.tenant.entity.SysMenu;
 import edu.travel.tenant.entity.SysRole;
 
 import java.util.List;
+import java.util.Set;
 
 public interface ITenantService extends IService<EduTenant> {
     public EduTenant getTenantByPhoneNumber(String tenantID);
 
-    void addTenant(EduTenant tenant);
+    EduTenant addTenant(AddOrUpdateTenantDto addOrUpdateTenantDto);
 
-    void deleteByIds(List<Long> ids);
-
-    void updateTenant(EduTenant tenant);
+    void deleteByIds(Set<Long> ids);
 
+    void updateTenant(AddOrUpdateTenantDto addOrUpdateTenantDto);
 
     EduTenant getTenantById(Long id);
 
@@ -24,5 +28,15 @@ public interface ITenantService extends IService<EduTenant> {
 
     List<SysRole> getRoleListByUserId(EduTenant principal);
 
-    void assignRolesToUser(AssignRolesOrMenus assignRolesOrMenus);
+    void assignRolesToUser(AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal);
+
+    List<MenuTreeVo> getTenantPageTreeList(EduTenant principal);
+
+    void updateRolesToUser(AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal);
+
+    void enableTenantByIds(Set<Long> ids);
+
+    void disableTenantByIds(Set<Long> ids);
+
+    IPage<EduTenant> dictMapPage(IPage<EduTenant> page, LambdaQueryWrapper<EduTenant> queryWrapper);
 }

+ 108 - 18
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ISysMenuServiceImpl.java

@@ -1,19 +1,25 @@
 package edu.travel.tenant.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import edu.travel.remote.feign.mode.dto.tenant.AddMenuDto;
+import edu.travel.remote.feign.mode.vo.tenant.AddMenuVo;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
+import edu.travel.remote.feign.mode.vo.tenant.SysMenuExtraDataVo;
+import edu.travel.remote.feign.mode.vo.tenant.SysMenuVo;
 import edu.travel.service.SysServiceImpl;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
-import edu.travel.tenant.entity.EduTenant;
-import edu.travel.tenant.entity.SysMenu;
+import edu.travel.tenant.entity.*;
 import edu.travel.tenant.mapper.SysMenuMapper;
 import edu.travel.tenant.service.*;
-import org.checkerframework.checker.units.qual.A;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.util.HashSet;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * ISysRoleServiceImpl 类。
@@ -28,28 +34,42 @@ import java.util.List;
 public class ISysMenuServiceImpl extends SysServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
 
     @Autowired
-    private ISysUserRoleService sysUserRoleService;
+    private ISysMenuExtraDataService sysMenuExtraDataService;
     @Autowired
     private ISysRoleMenuService sysRoleMenuService;
     @Autowired
-    private ISysMenuService sysMenuService;
-    @Autowired
     private ISysRoleService sysRoleService;
-    @Autowired
-    private ITenantService tenantService;
 
     @Override
-    public void addMenu(SysMenu sysMenu) {
+    @Transactional
+    public AddMenuVo addMenu(AddMenuDto addMenuDto) {
         //参数校验
-        Assert.isTrue(ObjectUtil.isNotEmpty(sysMenu),"参数不能为空");
-        Assert.isTrue(ObjectUtil.isNotEmpty(sysMenu.getPath()),"页面路由不能为空");
-        Assert.isTrue(ObjectUtil.isNotEmpty(sysMenu.getComponent()),"组件路径不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(addMenuDto),"参数不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(addMenuDto.getSysMenu()),"参数不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(addMenuDto.getSysMenu().getPath()),"页面路由不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(addMenuDto.getSysMenu().getComponent()),"组件路径不能为空");
         //保存菜单
-        super.save(sysMenu);
+        super.save(BeanUtil.copyProperties(addMenuDto.getSysMenu(),SysMenu.class));
+        addMenuDto.getSysMenuExtraData().setMenuId(addMenuDto.getSysMenu().getId());
+        sysMenuExtraDataService.save(BeanUtil.copyProperties(addMenuDto.getSysMenuExtraData(), SysMenuExtraData.class));
+
+        //将菜单分配给超级管理员
+        EduTenant principal =(EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        SysRoleMenu sysRoleMenu = new SysRoleMenu();
+        sysRoleMenu.setRoleId(sysRoleService.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getName,"超级管理员")).getId());
+        sysRoleMenu.setMenuId(addMenuDto.getSysMenuExtraData().getMenuId());
+        sysRoleMenu.setProject(principal.getProject());
+        sysRoleMenuService.save(sysRoleMenu);
+
+        AddMenuVo addMenuVo = new AddMenuVo();
+        addMenuVo.setSysMenu(BeanUtil.copyProperties(addMenuDto.getSysMenu(), SysMenuVo.class));
+        addMenuVo.setSysMenuExtraData(BeanUtil.copyProperties(addMenuDto.getSysMenuExtraData(), SysMenuExtraDataVo.class));
+        return addMenuVo;
     }
 
     @Override
-    public void deleteMenuByIds(List<Long> ids) {
+    @Transactional
+    public void deleteMenuByIds(Set<Long> ids) {
         //参数校验
         Assert.isTrue(ObjectUtil.isNotEmpty(ids),"请选择想要删除的菜单");
         List<SysMenu> sysMenus = super.listByIds(ids);
@@ -58,8 +78,78 @@ public class ISysMenuServiceImpl extends SysServiceImpl<SysMenuMapper, SysMenu>
         sysMenus.forEach(sysMenu -> {
             sysMenu.setDeleteFlag(1);
         });
-        this.updateBatchById(sysMenus);
+        SysMenuExtraData sysMenuExtraData = new SysMenuExtraData();
+        sysMenuExtraData.setDeleteFlag(1);
+        sysMenuExtraDataService.remove(new LambdaQueryWrapper<SysMenuExtraData>().in(SysMenuExtraData::getMenuId, ids));
+        this.removeByIds(ids);
+    }
+
+    @Override
+    public void updateMenuById(AddMenuDto updateMenuDto) {
+        Assert.isTrue(ObjectUtil.isNotEmpty(updateMenuDto),"参数不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(updateMenuDto.getSysMenu().getId()),"id不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(updateMenuDto.getSysMenuExtraData().getId()),"id不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(updateMenuDto.getSysMenu().getPath()),"页面路由不能为空");
+        Assert.isTrue(ObjectUtil.isNotEmpty(updateMenuDto.getSysMenu().getComponent()),"组件路径不能为空");
+        SysMenuExtraData extraData = sysMenuExtraDataService.getById(updateMenuDto.getSysMenuExtraData().getId());
+        Assert.isTrue(Objects.equals(extraData.getId(), updateMenuDto.getSysMenuExtraData().getId()),"该附加信息与菜单不匹配");
+        //保存菜单
+        super.updateById(BeanUtil.copyProperties(updateMenuDto.getSysMenu(),SysMenu.class));
+        sysMenuExtraDataService.updateById(BeanUtil.copyProperties(updateMenuDto.getSysMenuExtraData(), SysMenuExtraData.class));
     }
 
+    @Override
+    public List<MenuTreeVo> getMenuTreeListAll(List<SysMenu> records) {
+        // 获取菜单ID集合
+        List<Long> menuIdList = records.stream()
+                .map(SysMenu::getId)
+                .collect(Collectors.toList());
+
+        // 获取菜单附加信息
+        List<SysMenuExtraData> menuExtraDataList = sysMenuExtraDataService.list(new LambdaQueryWrapper<SysMenuExtraData>()
+                .in(SysMenuExtraData::getMenuId, menuIdList));
+
+        // 构建菜单树 菜单list 附加list
+        List<MenuTreeVo> treeList = buildMenuTree(records, BeanUtil.copyToList(menuExtraDataList, SysMenuExtraDataVo.class));
+
+        return treeList;
+    }
+
+    /**
+     * 构建菜单树
+     */
+    @Override
+    public List<MenuTreeVo> buildMenuTree(List<SysMenu> sysMenuList, List<SysMenuExtraDataVo> menuExtraDataList) {
+        Map<Long, MenuTreeVo> menuMap = new HashMap<>();
+        List<MenuTreeVo> rootMenus = new ArrayList<>();
+
+        // 构建每个菜单的 MenuTreeVo
+        sysMenuList.forEach(sysMenu -> {
+            MenuTreeVo menuTreeVo = BeanUtil.copyProperties(sysMenu, MenuTreeVo.class);
+            menuMap.put(sysMenu.getId(), menuTreeVo);
+        });
+
+        // 给每个菜单节点加子菜单
+        sysMenuList.forEach(sysMenu -> {
+            if (sysMenu.getParentId() == null) {
+                rootMenus.add(menuMap.get(sysMenu.getId()));  // 根节点
+            } else {
+                MenuTreeVo parentMenu = menuMap.get(sysMenu.getParentId());
+                if (parentMenu != null) {
+                    parentMenu.getChildren().add(menuMap.get(sysMenu.getId()));
+                }
+            }
+        });
+
+        // 给菜单附加额外数据
+        menuExtraDataList.forEach(extraData -> {
+            MenuTreeVo menuTreeVo = menuMap.get(extraData.getMenuId());
+            if (menuTreeVo != null) {
+                menuTreeVo.setExtraData(extraData);
+            }
+        });
+
+        return rootMenus;
+    }
 
 }

+ 1 - 2
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ISysRoleMenuServiceImpl.java

@@ -1,9 +1,8 @@
 package edu.travel.tenant.service.impl;
 
+
 import edu.travel.service.SysServiceImpl;
-import edu.travel.tenant.entity.SysMenuExtraData;
 import edu.travel.tenant.entity.SysRoleMenu;
-import edu.travel.tenant.mapper.SysMenuExtraDataMapper;
 import edu.travel.tenant.mapper.SysRoleMenuMapper;
 import edu.travel.tenant.service.ISysRoleMenuService;
 import org.springframework.stereotype.Service;

+ 107 - 49
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ISysRoleServiceImpl.java

@@ -1,22 +1,24 @@
 package edu.travel.tenant.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateRoleDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
 import edu.travel.tenant.entity.SysMenu;
-import edu.travel.tenant.entity.SysRoleMenu;
+import edu.travel.tenant.service.ISysMenuService;
 import edu.travel.tenant.service.ISysRoleMenuService;
-import edu.travel.tenant.service.ITenantService;
-import org.apache.commons.lang3.StringUtils;
 import edu.travel.tenant.entity.EduTenant;
 import edu.travel.tenant.entity.SysRole;
 import edu.travel.tenant.service.ISysRoleService;
 import edu.travel.service.SysServiceImpl;
 import edu.travel.tenant.mapper.SysRoleMapper;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import edu.travel.tenant.entity.SysRoleMenu;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -34,91 +36,147 @@ import java.util.stream.Collectors;
 public class ISysRoleServiceImpl extends SysServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
 
     @Autowired
-    private ITenantService tenantService;
-    @Autowired
     private ISysRoleMenuService iSysRoleMenuService;
     @Autowired
-    private ISysRoleServiceImpl sysRoleService;
+    private ISysMenuService sysMenuService;
 
     @Override
     @Transactional
-    public Boolean add(SysRole sysRole, EduTenant principal) {
-        if (principal == null) {
-            throw new RuntimeException("身份验证失败");
-        }
-        if (sysRole != null && StringUtils.isNotEmpty(sysRole.getName())) {
-            int count = this.count(new LambdaQueryWrapper<SysRole>()
-                    .eq(SysRole::getName, sysRole.getName()));
-            if (count != 0) {
-                throw new RuntimeException("该角色已存在");
-            }
-            boolean save = this.save(sysRole);
-            if (!save) throw new RuntimeException("角色添加失败");
-            return true;
-        }
-        return false;
-    }
+    public SysRole addRoleAndAssignMenus(AddOrUpdateRoleDto addOrUpdateRoleDto, EduTenant principal) {
 
-    @Override
-    @Transactional
-    public void deleteById(Long id) {
+        //参数验证
+        Assert.isFalse(addOrUpdateRoleDto==null||addOrUpdateRoleDto.getName()==null,"参数不能为空");
+
+        AssignRolesOrMenusDto assignRolesOrMenusDto = new AssignRolesOrMenusDto();
+
+        //角色
+        Assert.isFalse(Objects.equals(querySuperRoleId(), addOrUpdateRoleDto.getId()),"不能操作超级管理员角色");
+        SysRole role = this.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getName, addOrUpdateRoleDto.getName()));
+        Assert.isFalse(role!=null && !Objects.equals(addOrUpdateRoleDto.getId(), role.getId()), "该角色已存在");
+        assignRolesOrMenusDto.setId(addOrUpdateRoleDto.getId());
+
+        //菜单
+        List<Long> list = validateMenus(addOrUpdateRoleDto);
+        assignRolesOrMenusDto.setIds(list);
+
+        //保存角色并分配菜单
+        SysRole sysRole = BeanUtil.copyProperties(addOrUpdateRoleDto, SysRole.class);
+        Assert.isFalse(!this.save(sysRole), "角色添加失败");
+        assign(assignRolesOrMenusDto, principal);
+
+        return sysRole;
 
     }
 
     @Override
     @Transactional
     public void deleteByIds(Set<Long> ids) {
-        List<SysRole> listLink = super.getListLink(new LambdaQueryWrapper<SysRole>()
-                .in(SysRole::getId, ids));
-        if (listLink==null){
-            throw new RuntimeException("角色不存在");
-        }
-        if (listLink.size() != ids.size()) {
-            throw new RuntimeException("包含不存在的角色");
-        }
+        Assert.isFalse(ids.contains(querySuperRoleId()),"不能操作超级管理员角色");
+        List<SysRole> listLink = super.list(new LambdaQueryWrapper<SysRole>().in(SysRole::getId, ids));
+        Assert.isFalse(listLink == null || listLink.size() != ids.size(), "包含不存在的角色");
         listLink.forEach(sysRole -> {
-            if (sysRole.getDeleteFlag() == 1) {
-                throw new RuntimeException("包含已删除角色");
-            }
+            Assert.isFalse(sysRole.getDeleteFlag() == 1, "包含已删除角色");
         });
         this.removeByIds(ids);
     }
 
     @Override
-    public void updateRoleById(SysRole sysRole) {
+    @Transactional
+    public void updateRoleAndMenusById(AddOrUpdateRoleDto addOrUpdateRoleDto) {
 
-    }
+        //参数验证
+        Assert.isFalse(addOrUpdateRoleDto==null||addOrUpdateRoleDto.getId()==null || addOrUpdateRoleDto.getName()==null,"参数不能为空");
 
+        AssignRolesOrMenusDto assignRolesOrMenusDto = new AssignRolesOrMenusDto();
 
+        //角色
+        Assert.isTrue(ObjectUtil.isNotEmpty(this.getById(addOrUpdateRoleDto.getId())),"该角色不存在");
+        Assert.isFalse(querySuperRoleId().equals(addOrUpdateRoleDto.getId()),"不能操作超级管理员角色");
+        SysRole role = this.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getName, addOrUpdateRoleDto.getName()));
+        Assert.isFalse(role!=null && !Objects.equals(addOrUpdateRoleDto.getId(), role.getId()), "该角色已存在");
+        assignRolesOrMenusDto.setId(addOrUpdateRoleDto.getId());
 
-    @Override
-    public List<SysRole> getRoleByUserId(Long userId) {
-        if (userId != null) return null;
-        EduTenant tenant = tenantService.getTenantById(userId);
-        if (tenant != null) return null;
+        //菜单
+        List<Long> list = validateMenus(addOrUpdateRoleDto);
+        assignRolesOrMenusDto.setIds(list);
 
-        return null;
+        //保存角色并分配菜单
+        Assert.isFalse(!this.saveOrUpdate(BeanUtil.copyProperties(addOrUpdateRoleDto,SysRole.class)), "角色添加失败");
+        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        deleteRoleMenu(addOrUpdateRoleDto.getId(),principal);
+        assign(assignRolesOrMenusDto, principal);
     }
 
     @Override
-    public void assignMenusToRole(AssignRolesOrMenus dto) {
+    @Transactional
+    public void assignMenusToRole(AssignRolesOrMenusDto dto, EduTenant principal) {
+        assignRolesToUserValidate(dto);
+        assign(dto,principal);
+    }
+
+    @Override
+    @Transactional
+    public void updateMenusToRole(AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal) {
+        assignRolesToUserValidate(assignRolesOrMenusDto);
+        deleteRoleMenu(assignRolesOrMenusDto.getId(),principal);
+        assign(assignRolesOrMenusDto,principal);
+    }
+
+    /**
+     * 添加或修改角色参数验证 菜单验证
+     */
+    public List<Long> validateMenus(AddOrUpdateRoleDto addOrUpdateRoleDto){
+        List<Long> menuIds = addOrUpdateRoleDto.getMenuIds();
+        if (ObjectUtil.isEmpty(menuIds)) return new ArrayList<>();
+        Set<Long> menuIdsSet = new HashSet<>(menuIds);
+        List<SysMenu> roleList = sysMenuService.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getDeleteFlag, 0).in(SysMenu::getId, menuIdsSet));
+        Assert.isFalse(roleList.isEmpty()||menuIdsSet.size() != roleList.size(), "包含不存在的菜单或重复菜单");
+        return menuIds;
+    }
+
+    /**
+     * 分配角色参数验证
+     */
+    private void assignRolesToUserValidate(AssignRolesOrMenusDto dto) {
         Assert.isTrue(ObjectUtil.isNotEmpty(dto),"参数不能为空");
         Assert.isTrue(ObjectUtil.isNotEmpty(dto.getId()),"请选择需分配菜单的角色");
         Assert.isTrue(ObjectUtil.isNotEmpty(dto.getIds()),"请选择菜单");
         HashSet<Long> longs = new HashSet<>(dto.getIds());
         Assert.isTrue(longs.size()== dto.getIds().size(),"包含重复的菜单");
         //查询角色
-        SysRole sysRole = sysRoleService.getById(dto.getId());
+        SysRole sysRole = this.getById(dto.getId());
         Assert.isTrue(ObjectUtil.isNotEmpty(sysRole),"所选角色不存在");
+        Assert.isFalse(querySuperRoleId().equals(dto.getId()),"不能操作超级管理员角色");
         //查询菜单列表
         List<SysRole> sysMenuList = super.listByIds(dto.getIds());
-        Assert.isTrue(sysMenuList!=null&&sysMenuList.size()== dto.getIds().size(),"包含重复的菜单或菜单不存在");
-        //给用户分配菜单
+        Assert.isTrue(sysMenuList==null||sysMenuList.size()!= dto.getIds().size(),"包含重复的菜单或菜单不存在");
+    }
+
+    /**
+     * 分配菜单
+     */
+    private void assign (AssignRolesOrMenusDto dto, EduTenant principal) {
         iSysRoleMenuService.saveOrUpdateBatch(dto.getIds().stream().map(menuId -> {
             SysRoleMenu sysRoleMenu = new SysRoleMenu();
             sysRoleMenu.setRoleId(dto.getId());
             sysRoleMenu.setMenuId(menuId);
+            sysRoleMenu.setProject(principal.getProject());
             return sysRoleMenu;
         }).collect(Collectors.toList()));
     }
+
+    /**
+     * 删除该角色已有的菜单
+     */
+    private void deleteRoleMenu(Long roleId,EduTenant principal) {
+        iSysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>()
+                .eq(SysRoleMenu::getRoleId, roleId));
+    }
+
+    /**
+     * 超级管理员的id
+     */
+    public Long querySuperRoleId(){
+        return this.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getName,"超级管理员")).getId();
+    }
 }

+ 263 - 107
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/service/impl/ITenantServiceImpl.java

@@ -5,17 +5,20 @@ import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateTenantDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
+import edu.travel.remote.feign.mode.vo.tenant.SysMenuExtraDataVo;
 import edu.travel.tenant.entity.*;
-import edu.travel.tenant.enums.UserStatus;
 import edu.travel.tenant.service.*;
 import edu.travel.service.SysServiceImpl;
 import edu.travel.tenant.mapper.EduTenantMapper;
-import edu.travel.tenant.vo.EduTenantVo;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -30,6 +33,10 @@ public class ITenantServiceImpl extends SysServiceImpl<EduTenantMapper, EduTenan
     private ISysMenuService sysMenuService;
     @Autowired
     private ISysRoleService sysRoleService;
+    @Autowired
+    private ISysMenuExtraDataService extraDataService;
+    @Autowired
+    private ISysMenuExtraDataService sysMenuExtraDataService;
     @Override
     public EduTenant getTenantByPhoneNumber(String tenantID) {
         return super.getOneLink(new QueryWrapper<EduTenant>().eq("tenant_phone",tenantID));
@@ -37,64 +44,81 @@ public class ITenantServiceImpl extends SysServiceImpl<EduTenantMapper, EduTenan
 
     @Override
     @Transactional
-    public void addTenant(EduTenant tenant) {
-        if (tenant == null) {
-            throw new RuntimeException("参数为空");
-        }
-        if (tenant.getTenantPhone() == null){
-            throw new RuntimeException("手机号为空");
-        }
-        EduTenant eduTenant = super.getOneLink(new QueryWrapper<EduTenant>().eq("tenant_phone", tenant.getTenantPhone()));
-        if (eduTenant != null&&eduTenant.getUserStatus()==0) {
-            throw new RuntimeException("该手机号已注册,用户状态为禁用");
-        }
-        if (eduTenant != null&&eduTenant.getUserStatus()==1) {
-            throw new RuntimeException("该手机号已注册,用户状态正常");
-        }
-        if (eduTenant == null){
-            this.save(tenant);
-        }
+    public EduTenant addTenant(AddOrUpdateTenantDto addOrUpdateTenantDto) {
+
+        //参数validate
+        validateParamsForAddTenant(addOrUpdateTenantDto);
+
+        //用户手机号重复validate
+        EduTenant eduTenant = super.getOneLink(new QueryWrapper<EduTenant>().eq("tenant_phone", addOrUpdateTenantDto.getTenantPhone()));
+        Assert.isFalse(eduTenant != null && eduTenant.getUserStatus()==0, "该手机号已注册,用户状态为禁用");
+        Assert.isFalse(eduTenant != null && eduTenant.getUserStatus()==1, "该手机号已注册,用户状态正常");
+        EduTenant tenant = BeanUtil.copyProperties(addOrUpdateTenantDto, EduTenant.class);
+
+        //角色列表验证
+        validateRoleForAddTenant(addOrUpdateTenantDto);
+
+        //保存用户
+        this.save(tenant);
+
+        //分配角色
+        if (addOrUpdateTenantDto.getRoleIds().isEmpty()) return tenant;
+        AssignRolesOrMenusDto assignRolesOrMenusDto = new AssignRolesOrMenusDto();
+        assignRolesOrMenusDto.setIds(addOrUpdateTenantDto.getRoleIds());
+        assignRolesOrMenusDto.setId(tenant.getId());
+        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        assign(assignRolesOrMenusDto, principal);
+
+        return tenant;
     }
 
     @Override
     @Transactional
-    public void deleteByIds(List<Long> ids) {
-        HashSet<Long> set = new HashSet<>(ids);
-        if (set==null || set.isEmpty()) {
-            throw new RuntimeException("参数为空");
-        }
-        List<EduTenant> tenants = this.listByIds(set);
-        if (tenants == null || tenants.isEmpty()) {
-            throw new RuntimeException("用户不存在或已注销");
+    public void updateTenant(AddOrUpdateTenantDto addOrUpdateTenantDto) {
+        //参数validate
+        validateParamsForAddTenant(addOrUpdateTenantDto);
+
+        //phone重复validate
+        if (addOrUpdateTenantDto.getTenantPhone() != null){
+            EduTenant eduTenant = super.getOneLink(new QueryWrapper<EduTenant>().eq("tenant_phone", addOrUpdateTenantDto.getTenantPhone()));
+            Assert.isFalse(eduTenant != null && eduTenant.getUserStatus()==0 && !eduTenant.getId().equals(addOrUpdateTenantDto.getId()), "该手机号已注册,用户状态为禁用");
+            Assert.isFalse(eduTenant != null && eduTenant.getUserStatus()==1 && !eduTenant.getId().equals(addOrUpdateTenantDto.getId()), "该手机号已注册,用户状态正常");
         }
-        List<EduTenantVo> eduTenantVos = fillStatus(tenants);
-        ArrayList<Long> longs = new ArrayList<>();
-        eduTenantVos.forEach(eduTenantVo -> {
-            if (Objects.equals(eduTenantVo.getStatus(), UserStatus.USER_STATUS_DELETED.getCode())) {
-                throw new RuntimeException("包含已删除用户");
-            } else if (Objects.equals(eduTenantVo.getStatus(), UserStatus.USER_STATUS_DISABLED.getCode())) {
-                throw new RuntimeException("包含已禁用用户");
-            } else {
-                longs.add(eduTenantVo.getId());
-            }
-            this.removeByIds(longs);
-        });
+
+        //用户validate
+        EduTenant ed = super.getOne(new QueryWrapper<EduTenant>().eq("id", addOrUpdateTenantDto.getId()));
+        Assert.isTrue(ObjectUtil.isNotEmpty(ed), "用户不存在");
+        Assert.isFalse(ed.getDeleteFlag() == 1, "用户已注销");
+        Assert.isFalse(ed.getUserStatus() == 0, "用户已禁用");
+
+        EduTenant tenant = BeanUtil.copyProperties(addOrUpdateTenantDto, EduTenant.class);
+        this.updateById(tenant);
+
+        //角色列表验证
+        AssignRolesOrMenusDto assignRolesOrMenusDto = new AssignRolesOrMenusDto();
+        assignRolesOrMenusDto.setId(tenant.getId());
+        assignRolesOrMenusDto.setIds(addOrUpdateTenantDto.getRoleIds());
+        assignValidate(assignRolesOrMenusDto);
+
+        //删除已分配的角色
+        deleteUserRoles(tenant.getId());
+        assign(assignRolesOrMenusDto, ed);
+
     }
 
     @Override
     @Transactional
-    public void updateTenant(EduTenant tenant) {
-        if (tenant == null) throw new RuntimeException("参数为空");
-        if (tenant.getId() == null) throw new RuntimeException("参数为空");
-        EduTenant eduTenant = super.getOneLink(new QueryWrapper<EduTenant>().eq("id", tenant.getId()));
-        if (eduTenant == null) throw new RuntimeException("用户不存在");
-        if (eduTenant.getDeleteFlag() == 1)  throw new RuntimeException("用户已注销");
-        if (eduTenant.getUserStatus() == 0) throw new RuntimeException("用户已禁用");
-        if (tenant.getTenantPhone() != null){
-            EduTenant eduTenant1 = super.getOneLink(new QueryWrapper<EduTenant>().eq("tenant_phone", tenant.getTenantPhone()));
-            if (eduTenant1 != null) throw new RuntimeException("该手机号已注册");
-        }
-        this.updateById(tenant);
+    public void deleteByIds(Set<Long> set) {
+        Assert.isFalse(set==null || set.isEmpty(),"参数为空");
+        List<EduTenant> tenants = this.listByIds(set);
+        Assert.isFalse(tenants == null || tenants.isEmpty() || tenants.size() != set.size(),"包含用户不存在或已注销");
+        ArrayList<Long> longs = new ArrayList<>();
+        tenants.forEach(eduTenantVo -> {
+            Assert.isFalse(Objects.equals(eduTenantVo.getDeleteFlag(), 1),"包含已删除用户");
+            Assert.isFalse(Objects.equals(eduTenantVo.getUserStatus(), 1),"包含未禁用用户,请先禁用该账号");
+            longs.add(eduTenantVo.getId());
+            this.removeByIds(longs);
+        });
     }
 
     @Override
@@ -104,46 +128,93 @@ public class ITenantServiceImpl extends SysServiceImpl<EduTenantMapper, EduTenan
                 .eq(EduTenant::getUserStatus,1));
     }
 
-    @Override
-    public List<SysMenu> getMenuList(EduTenant principal) {
+    /**
+     *新增或修改用户参数验证
+     */
+    private void validateParamsForAddTenant(AddOrUpdateTenantDto addOrUpdateTenantDto) {
 
-        if (principal ==null) throw new RuntimeException("用户未登录");
-        EduTenant tenant = this.getTenantById(principal.getId());
-        if (tenant == null) throw new RuntimeException("用户不存在");
-        if (tenant.getUserStatus() == 0) throw new RuntimeException("用户已禁用");
-        if (tenant.getDeleteFlag() == 1) throw new RuntimeException("用户已注销");
-        if (tenant.getId() != null) {
-            //用户角色列表
-            List<Long> roleIdList = sysUserRoleService.getBaseMapper().selectList(new LambdaQueryWrapper<SysUserRole>()
-                            .eq(SysUserRole::getId, tenant.getId())).stream()
-                    .map(SysUserRole::getRoleId)
-                    .collect(Collectors.toList());
-            if (roleIdList.isEmpty()) return null;
-            //菜单列表
-            Set<Long> menuIdList = sysRoleMenuService.getBaseMapper().selectList(new LambdaQueryWrapper<SysRoleMenu>()
-                            .in(SysRoleMenu::getRoleId, roleIdList)).stream()
-                    .map(SysRoleMenu::getMenuId)
-                    .collect(Collectors.toSet());
-            //菜单列表内容
-            List<SysMenu> list = sysMenuService.list(new LambdaQueryWrapper<SysMenu>()
-                    .eq(SysMenu::getDeleteFlag, 0)
-                    .eq(SysMenu::getStatus, 1)
-                    .in(SysMenu::getId, menuIdList));
-            return list;
+//        Assert.isTrue(ObjectUtil.isNotEmpty(addOrUpdateTenantDto),"参数为空");
+//        Assert.isTrue(ObjectUtil.isNotEmpty(addOrUpdateTenantDto.getTenantPhone()),"手机号为空");
+//        Assert.isTrue(ObjectUtil.isNotEmpty(addOrUpdateTenantDto.getTenantSurname()),"姓为空");
+//        Assert.isTrue(ObjectUtil.isNotEmpty(addOrUpdateTenantDto.getTenantName()),"名为空");
+//        Assert.isTrue(ObjectUtil.isNotEmpty(addOrUpdateTenantDto.getTenantSex()),"性别为空");
+//        Assert.isTrue(ObjectUtil.isNotEmpty(addOrUpdateTenantDto.getPassword()),"密码为空");
+
+    }
+
+    /**
+     * 新增或修改用户角色验证
+     */
+    private void validateRoleForAddTenant(AddOrUpdateTenantDto addOrUpdateTenantDto) {
+        //角色validate
+        if (!addOrUpdateTenantDto.getRoleIds().isEmpty()){
+            List<SysRole> roleList = sysRoleService.list(new LambdaQueryWrapper<SysRole>().in(SysRole::getId, addOrUpdateTenantDto.getRoleIds()));
+            Assert.isFalse(roleList == null || roleList.size() != addOrUpdateTenantDto.getRoleIds().size(), "包含不存在的角色");
+            Assert.isFalse(addOrUpdateTenantDto.getRoleIds()!=null && BeanUtil.copyToList(roleList,Long.class).contains(querySuperAdmin()),"不能分配超级管理员");
         }
-        return null;
+    }
+
+
+    //根据用户信息查询用户所有菜单 不含附加信息
+    public List<SysMenu> getMenuList(EduTenant principal) {
+        //参数验证
+        Assert.isTrue(ObjectUtil.isNotEmpty(principal), "用户未登录");
+        EduTenant tenant = this.getTenantById(principal.getId());
+        Assert.isTrue(ObjectUtil.isNotEmpty(tenant), "用户不存在");
+        Assert.isFalse(tenant.getUserStatus() == 0, "用户已禁用");
+        Assert.isFalse(tenant.getDeleteFlag() == 1, "用户已注销");
+        Assert.isTrue(ObjectUtil.isNotEmpty(tenant.getId()), "用户不存在");
+
+        //用户角色列表
+        List<Long> roleIdList = sysUserRoleService.getBaseMapper().selectList(new LambdaQueryWrapper<SysUserRole>()
+                        .eq(SysUserRole::getUserId, tenant.getId())).stream()
+                .map(SysUserRole::getRoleId)
+                .collect(Collectors.toList());
+        if (roleIdList.isEmpty()) return new ArrayList<SysMenu>();
+
+        //用户菜单列表ids
+        Set<Long> menuIdList = sysRoleMenuService.getBaseMapper().selectList(new LambdaQueryWrapper<SysRoleMenu>()
+                        .in(SysRoleMenu::getRoleId, roleIdList)).stream()
+                .map(SysRoleMenu::getMenuId)
+                .collect(Collectors.toSet());
+        if (menuIdList.isEmpty()) return new ArrayList<SysMenu>();
+
+        //用户菜单列表
+
+        List<SysMenu> list = sysMenuService.list(new LambdaQueryWrapper<SysMenu>()
+                .eq(SysMenu::getDeleteFlag, 0)
+                .eq(SysMenu::getStatus, 1)
+                .in(SysMenu::getId, menuIdList));
+
+//        ArrayList<MenuTreeVo> menuTreeVos = new ArrayList<>(list.size());
+//        BeanUtils.copyProperties(list, menuTreeVos);
+//        //菜单附加信息
+//        List<SysMenuExtraData> menuExtraDataList = extraDataService.list(new LambdaQueryWrapper<SysMenuExtraData>()
+//                .in(SysMenuExtraData::getMenuId, menuIdList));
+//        menuTreeVos.forEach(menuTreeVo -> {
+//            menuExtraDataList.forEach(sysMenuExtraData -> {
+//                if (menuTreeVo.getId().equals(sysMenuExtraData.getMenuId())) {
+//                    menuTreeVo.setExtraData(sysMenuExtraData);
+//                }
+//            });
+//        });
+
+        return list;
     }
 
     @Override
     public List<SysRole> getRoleListByUserId(EduTenant principal) {
-        if (principal ==null) throw new RuntimeException("用户未登录");
-        if (principal.getId() == null)  throw new RuntimeException("用户不存在");
+
+        Assert.isTrue(ObjectUtil.isNotEmpty(principal), "用户未登录");
+        Assert.isTrue(ObjectUtil.isNotEmpty(principal.getId()), "用户不存在");
+
         //用户角色列表id
-        List<Long> roleIdList = sysUserRoleService.getBaseMapper().selectList(new LambdaQueryWrapper<SysUserRole>()
-                        .eq(SysUserRole::getId, principal.getId())).stream()
+        List<Long> roleIdList = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>()
+                .eq(SysUserRole::getUserId, principal.getId())).stream()
                 .map(SysUserRole::getRoleId)
                 .collect(Collectors.toList());
-        if (roleIdList.isEmpty()) return null;
+        if (roleIdList.isEmpty()) return new ArrayList<SysRole>();
+
         //角色列表内容
         List<SysRole> list = sysRoleService.list(new LambdaQueryWrapper<SysRole>()
                 .in(SysRole::getId, roleIdList)
@@ -152,38 +223,123 @@ public class ITenantServiceImpl extends SysServiceImpl<EduTenantMapper, EduTenan
     }
 
     @Override
-    public void assignRolesToUser(AssignRolesOrMenus assignRolesOrMenus) {
-        Assert.isTrue(ObjectUtil.isNotEmpty(assignRolesOrMenus),"请登录");
-        Assert.isTrue(ObjectUtil.isNotEmpty(assignRolesOrMenus.getId()),"请选择需分配角色的用户");
-        Assert.isTrue(ObjectUtil.isNotEmpty(assignRolesOrMenus.getIds()),"请选择角色");
-        List<SysRole> roleList = sysRoleService.listByIds(assignRolesOrMenus.getIds());
+    @Transactional
+    public void assignRolesToUser(AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal) {
+        assignValidate(assignRolesOrMenusDto);
+        assign(assignRolesOrMenusDto, principal);
+    }
+
+    @Override
+    @Transactional
+    public void updateRolesToUser(AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal) {
+        assignValidate(assignRolesOrMenusDto);
+        deleteUserRoles(principal.getId());
+        assign(assignRolesOrMenusDto,principal);
+    }
+
+    @Override
+    public void enableTenantByIds(Set<Long> ids) {
+        Assert.isTrue(ObjectUtil.isNotEmpty(ids),"请选择用户");
+        List<EduTenant> tenants = this.list(new LambdaQueryWrapper<EduTenant>()
+                .in(EduTenant::getId,ids));
+        Assert.isTrue(ObjectUtil.isNotEmpty(tenants)||tenants.size()== ids.size(),"包含已删除账号");
+        tenants.forEach(eduTenant -> {
+            Assert.isFalse(eduTenant.getDeleteFlag() == 1, "包含已删除账号");
+            Assert.isFalse(queryLoginUserId().equals(eduTenant.getId()),"不能操作超级管理员");
+        });
+        this.update(new LambdaUpdateWrapper<EduTenant>()
+                .set(EduTenant::getUserStatus,1)
+                .in(EduTenant::getId,ids));
+    }
+
+    @Override
+    public void disableTenantByIds(Set<Long> ids) {
+        Assert.isTrue(ObjectUtil.isNotEmpty(ids),"请选择用户");
+        List<EduTenant> tenants = this.list(new LambdaQueryWrapper<EduTenant>()
+                .in(EduTenant::getId,ids));
+        Assert.isTrue(ObjectUtil.isNotEmpty(tenants)||tenants.size()== ids.size(),"包含已删除账号");
+        tenants.forEach(eduTenant -> {
+            Assert.isFalse(eduTenant.getDeleteFlag() == 1, "包含已删除账号");
+            Assert.isFalse(eduTenant.getUserStatus() == 0, "该账号已禁用,操作失败");
+            Assert.isFalse(queryLoginUserId().equals(eduTenant.getId()),"不能操作超级管理员");
+        });
+        this.update(new LambdaUpdateWrapper<EduTenant>()
+                .set(EduTenant::getUserStatus,0)
+                .in(EduTenant::getId,ids));
+    }
+
+    @Override
+    public IPage<EduTenant> dictMapPage(IPage<EduTenant> page, LambdaQueryWrapper<EduTenant> queryWrapper) {
+        return super.getPageLink(queryWrapper,page);
+    }
+
+    /**
+     * 分配角色参数验证
+     */
+    private void assignValidate(AssignRolesOrMenusDto assignRolesOrMenusDto) {
+        Assert.isTrue(ObjectUtil.isNotEmpty(assignRolesOrMenusDto),"请登录");
+        Assert.isTrue(ObjectUtil.isNotEmpty(assignRolesOrMenusDto.getId()),"请选择需分配角色的用户");
+        Assert.isTrue(ObjectUtil.isNotEmpty(assignRolesOrMenusDto.getIds()),"请选择角色");
+        List<SysRole> roleList = sysRoleService.list(new LambdaQueryWrapper<SysRole>().in(SysRole::getId,assignRolesOrMenusDto.getIds()));
         Assert.isTrue(ObjectUtil.isNotEmpty(roleList),"选择的角色不存在");
-        Assert.isTrue(roleList.size() == assignRolesOrMenus.getIds().size(),"包含重复的角色或不存在的角色");
-        //分配角色
-        sysUserRoleService.saveOrUpdateBatch(assignRolesOrMenus.getIds().stream().map(roleId -> {
+        Assert.isTrue(roleList.size() == assignRolesOrMenusDto.getIds().size(),"包含重复的角色或不存在的角色");
+        Assert.isFalse(Objects.equals(queryLoginUserId(), assignRolesOrMenusDto.getId()),"不能为超级管理员分配角色");
+    }
+
+    /**
+     * 分配角色
+     */
+    private void assign (AssignRolesOrMenusDto assignRolesOrMenusDto, EduTenant principal) {
+        sysUserRoleService.saveBatch(assignRolesOrMenusDto.getIds().stream().map(roleId -> {
             SysUserRole sysUserRole = new SysUserRole();
-            sysUserRole.setUserId(assignRolesOrMenus.getId());
+            sysUserRole.setUserId(assignRolesOrMenusDto.getId());
             sysUserRole.setRoleId(roleId);
+            sysUserRole.setProject(principal.getProject());
             return sysUserRole;
         }).collect(Collectors.toList()));
     }
 
     /**
-     *
-     * 填充用户状态
+     * 删除用户已有角色
      */
-    private List<EduTenantVo> fillStatus(List<EduTenant> list) {
-        List<EduTenantVo> eduTenantVos = BeanUtil.copyToList(list, EduTenantVo.class);
-        eduTenantVos.forEach(eduTenantVo -> {
-            if (eduTenantVo.getDeleteFlag() == 1) {
-                eduTenantVo.setStatus(UserStatus.USER_STATUS_DELETED.getCode());
-            } else if (eduTenantVo.getUserStatus() == 0) {
-                eduTenantVo.setStatus(UserStatus.USER_STATUS_DISABLED.getCode());
-            } else {
-                eduTenantVo.setStatus(UserStatus.USER_STATUS_NORMAL.getCode());
-            }
-        });
-        return eduTenantVos;
+    private void deleteUserRoles(Long userId) {
+        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
+                .eq(SysUserRole::getUserId, userId));
     }
 
+    @Override
+    public List<MenuTreeVo> getTenantPageTreeList(EduTenant principal) {
+        // 获取菜单列表 不含附加信息
+        List<SysMenu> menuList = getMenuList(principal);
+        if (menuList == null) return new ArrayList<MenuTreeVo>();
+
+        // 获取菜单ID集合
+        List<Long> menuIdList = menuList.stream()
+                .map(SysMenu::getId)
+                .collect(Collectors.toList());
+        if (menuIdList.isEmpty()) return new ArrayList<MenuTreeVo>();
+
+        // 获取菜单附加信息
+        List<SysMenuExtraData> menuExtraDataList = sysMenuExtraDataService.list(new LambdaQueryWrapper<SysMenuExtraData>()
+                .in(SysMenuExtraData::getMenuId, menuIdList));
+
+        // 构建菜单树 菜单list 附加list
+        List<MenuTreeVo> treeList = sysMenuService.buildMenuTree(menuList, BeanUtil.copyToList(menuExtraDataList, SysMenuExtraDataVo.class));
+
+        return treeList;
+    }
+
+    /**
+     * 查询为 超级管理员的用户账号id
+     */
+    public Long querySuperAdmin(){
+        return sysRoleService.getOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getName,"超级管理员")).getId();
+    }
+
+    /**
+     * 登陆人员id
+     */
+    public Long queryLoginUserId(){
+        return ((EduTenant)SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
+    }
 }

+ 40 - 27
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysMenuController.java

@@ -2,22 +2,23 @@ package edu.travel.tenant.web;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import edu.travel.remote.feign.mode.dto.tenant.AddMenuDto;
+import edu.travel.remote.feign.mode.dto.tenant.SysMenuPageDto;
+import edu.travel.remote.feign.mode.vo.tenant.AddMenuVo;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
 import edu.travel.resp.BaseResponse;
 import edu.travel.resp.PageResponse;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
-import edu.travel.tenant.dto.SysMenuPageDto;
-import edu.travel.tenant.entity.EduTenant;
+import edu.travel.tenant.SysMenuRemoteController;
 import edu.travel.tenant.entity.SysMenu;
 import edu.travel.tenant.service.ISysMenuService;
-import edu.travel.tenant.service.ISysRoleService;
 import edu.travel.web.BaseController;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.validation.Errors;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 /**
  * SysMenuController 类。
@@ -30,20 +31,21 @@ import java.util.List;
 
 @RestController
 @RequestMapping("/sysMenu")
-public class SysMenuController extends BaseController<SysMenu> {
+public class SysMenuController extends BaseController<SysMenu> implements SysMenuRemoteController {
     @Autowired
     private ISysMenuService sysMenuService;
 
     /**
      * 新增菜单
-     * @param sysMenu
+     *
+     * @param addMenuDto
      * @return
      */
     @PostMapping("/addMenu")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> addMenu(@RequestBody SysMenu sysMenu) {
-        sysMenuService.addMenu(sysMenu);
-        return new BaseResponse<>(200,"sucess",true);
+@PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<AddMenuVo> addMenu(@RequestBody AddMenuDto addMenuDto) {
+        AddMenuVo addMenuVo = sysMenuService.addMenu(addMenuDto);
+        return new BaseResponse<>(200,"sucess", addMenuVo);
     }
 
     /**
@@ -53,9 +55,9 @@ public class SysMenuController extends BaseController<SysMenu> {
      */
 
     @PostMapping("/deleteMenuById")
-    //    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> deleteMenuById(Long id) {
-        List<Long> longs = new ArrayList<>();
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteMenuById(@RequestParam Long id) {
+        Set<Long> longs = new HashSet<>();
         longs.add(id);
         sysMenuService.deleteMenuByIds(longs);
         return new BaseResponse<>(200,"sucess",true);
@@ -67,26 +69,37 @@ public class SysMenuController extends BaseController<SysMenu> {
      * @return
      */
     @PostMapping("/deleteMenuByIds")
-    //    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> deleteMenuByIds(@RequestBody List<Long> ids) {
-        sysMenuService.deleteMenuByIds(ids);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteMenuByIds(@RequestBody List<Long> ids ){
+        HashSet<Long> set = new HashSet<>(ids);
+        sysMenuService.deleteMenuByIds(set);
         return new BaseResponse<>(200,"sucess",true);
     }
 
     /**
-     * 获取菜单分页列表
+     * 获取菜单分页树形列表
      * @param sysMenuPageDto
      * @return
      */
-
-    @GetMapping("/getMenuList")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<SysMenu>> getMenuList(SysMenuPageDto sysMenuPageDto) {
+    @GetMapping("/getMenuTreeListAll")
+@PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<MenuTreeVo>> getMenuTreeListAll(SysMenuPageDto sysMenuPageDto) {
         IPage<SysMenu> page = new Page<>(sysMenuPageDto.getPageNum(), sysMenuPageDto.getPageSize());
-        IPage<SysMenu> tenantIPage = sysMenuService.page(page, new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getDeleteFlag, 0));
-        return PageResponse.out(200,"success",tenantIPage.getRecords(),(int)tenantIPage.getTotal(),(int)tenantIPage.getSize());
+        IPage<SysMenu> sysMenuIPage = sysMenuService.page(page, new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getDeleteFlag, 0).like(StringUtils.isNotBlank(sysMenuPageDto.getName()),SysMenu::getName,sysMenuPageDto.getName()));
+        List<MenuTreeVo> treeList= sysMenuService.getMenuTreeListAll(sysMenuIPage.getRecords());
+        return PageResponse.out(200, "success", treeList, (int) sysMenuIPage.getTotal(), (int) sysMenuIPage.getSize());
     }
 
-
+    /**
+     * 通过菜单id修改菜单
+     * @param updateMenuDto
+     * @return
+     */
+    @PostMapping("/updateMenuById")
+@PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateMenuById( @RequestBody AddMenuDto updateMenuDto) {
+        sysMenuService.updateMenuById(updateMenuDto);
+        return new BaseResponse<>(200,"sucess",true);
+    }
 
 }

+ 55 - 39
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysRoleController.java

@@ -1,13 +1,16 @@
 package edu.travel.tenant.web;
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.cloud.commons.lang.StringUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import edu.travel.interfaces.InsertGroups;
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateRoleDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
+import edu.travel.remote.feign.mode.dto.tenant.SysRolePageDto;
+import edu.travel.remote.feign.mode.vo.tenant.SysRoleVo;
 import edu.travel.resp.BaseResponse;
 import edu.travel.resp.PageResponse;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
-import edu.travel.tenant.dto.EduTenantPageDto;
-import edu.travel.tenant.dto.SysRolePageDto;
+import edu.travel.tenant.SysRoleRemoteController;
 import edu.travel.tenant.entity.EduTenant;
 import edu.travel.tenant.entity.SysRole;
 import edu.travel.tenant.service.ISysRoleService;
@@ -15,8 +18,6 @@ import edu.travel.web.BaseController;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.HashSet;
@@ -34,27 +35,27 @@ import java.util.Set;
 
 @RestController
 @RequestMapping("/sysRole")
-public class SysRoleController extends BaseController<SysRole> {
+public class SysRoleController extends BaseController<SysRole> implements SysRoleRemoteController {
 
     @Autowired
     private ISysRoleService sysRoleService;
 
     /**
-     * 新增管理角色
+     * 新增管理角色并分配菜单
      */
-    @PostMapping("/addRole")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> addRole( @RequestBody SysRole sysRole) {
+    @PostMapping("/addRoleAndAssignMenus")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<SysRoleVo> addRoleAndAssignMenus(@RequestBody AddOrUpdateRoleDto addOrUpdateRoleDto) {
         EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        sysRoleService.add(sysRole,principal);
-        return new BaseResponse<>(200,"success",true) ;
+        SysRole role = sysRoleService.addRoleAndAssignMenus(addOrUpdateRoleDto, principal);
+        return new BaseResponse<>(200,"success",BeanUtil.copyProperties(role,SysRoleVo.class));
     }
 
     /**
      * 删除角色多个
      */
     @PostMapping("/deleteRoleByIds")
-//    @PreAuthorize("hasRole('超级管理员')")
+    @PreAuthorize("hasRole('超级管理员')")
     public BaseResponse<Boolean> deleteRoleByIds(@RequestBody List<Long> ids) {
         HashSet<Long> longs = new HashSet<>(ids);
         sysRoleService.deleteByIds(longs);
@@ -65,47 +66,62 @@ public class SysRoleController extends BaseController<SysRole> {
      * 删除角色单个
      */
     @PostMapping("/deleteRoleById")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> deleteRoleById(Long id) {
-        sysRoleService.deleteById(id);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteRoleById(@RequestParam Long id) {
+        Set<Long> list = new HashSet<>();
+        list.add(id);
+        sysRoleService.deleteByIds(list);
         return new BaseResponse<>(200,"success",true) ;
     }
 
     /**
-     * 更新角色
+     * 更新角色和角色下菜单
      */
-    @PostMapping("/updateRoleById")
-    public BaseResponse<Boolean> updateRoleById(@Validated(InsertGroups.class) @RequestBody SysRole sysRole) {
-        sysRoleService.updateRoleById(sysRole);
+    @PostMapping("/updateRoleAndMenusById")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateRoleAndMenusById( @RequestBody AddOrUpdateRoleDto addOrUpdateRoleDto) {
+        sysRoleService.updateRoleAndMenusById(addOrUpdateRoleDto);
         return new BaseResponse<>(200,"success",true) ;
     }
 
     /**
-     * 根据用户id查询用户角色
-     */
-    @GetMapping("/getRoleByUserId")
-    public BaseResponse<List<SysRole>> getRoleByUserId(Long userId) {
-        List<SysRole> sysRoles = sysRoleService.getRoleByUserId(userId);
-        return new BaseResponse<>(200,"success",sysRoles) ;
-    }
-
-    /**
      * 为角色分配菜单
      * @param dto
      * @return
      */
     @PostMapping("/assignMenusToRole")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> assignMenusToRole(@RequestBody AssignRolesOrMenus dto) {
-        sysRoleService.assignMenusToRole(dto);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> assignMenusToRole(@RequestBody AssignRolesOrMenusDto dto) {
+        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        sysRoleService.assignMenusToRole(dto,principal);
         return new BaseResponse<>(200,"sucess",true);
     }
 
+    /**
+     * 更新角色菜单
+     * @param assignRolesOrMenusDto
+     * @return
+     */
+    @PostMapping("/updateMenusToRole")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateMenusToRole(@RequestBody AssignRolesOrMenusDto assignRolesOrMenusDto) {
+        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        sysRoleService.updateMenusToRole(assignRolesOrMenusDto,principal);
+        return PageResponse.out(200,"success",true);
+    }
+
+    /**
+     * 分页查询角色列表
+     * @param sysRolePageDto
+     * @return
+     */
     @GetMapping("/getRolePageList")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<SysRole>> getRolePageList(SysRolePageDto sysRolePageDto) {
-            IPage<SysRole> page = new Page<>(sysRolePageDto.getPageNum(), sysRolePageDto.getPageSize());
-            IPage<SysRole> tenantIPage = sysRoleService.page(page, new LambdaQueryWrapper<SysRole>().eq(SysRole::getDeleteFlag, 0));
-            return PageResponse.out(200, "success", tenantIPage.getRecords(), (int) tenantIPage.getTotal(), (int) tenantIPage.getSize());
-        }
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<SysRoleVo>> getRolePageList(SysRolePageDto sysRolePageDto) {
+        IPage<SysRole> page = new Page<>(sysRolePageDto.getPageNum(), sysRolePageDto.getPageSize());
+        IPage<SysRole> tenantIPage = sysRoleService.page(page, new LambdaQueryWrapper<SysRole>().eq(SysRole::getDeleteFlag, 0)
+                .like(StringUtils.isNotBlank(sysRolePageDto.getName()),SysRole::getName, sysRolePageDto.getName()));
+        List<SysRoleVo> sysRoleVos = BeanUtil.copyToList(tenantIPage.getRecords(), SysRoleVo.class);
+        return PageResponse.out(200, "success", sysRoleVos, (int) tenantIPage.getTotal(), (int) tenantIPage.getSize());
+    }
 }

+ 1 - 1
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysRoleMenuController.java

@@ -1,9 +1,9 @@
 package edu.travel.tenant.web;
 
-import edu.travel.tenant.entity.SysRoleMenu;
 import edu.travel.web.BaseController;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import edu.travel.tenant.entity.SysRoleMenu;
 
 /**
  * SysMenuController 类。

+ 1 - 1
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/SysUserRoleController.java

@@ -1,9 +1,9 @@
 package edu.travel.tenant.web;
 
-import edu.travel.tenant.entity.SysUserRole;
 import edu.travel.web.BaseController;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import edu.travel.tenant.entity.SysUserRole;
 
 /**
  * SysMenuController 类。

+ 174 - 49
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/tenant/web/TenantController.java

@@ -1,135 +1,260 @@
 package edu.travel.tenant.web;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import edu.travel.remote.feign.mode.dto.tenant.AddOrUpdateTenantDto;
+import edu.travel.remote.feign.mode.dto.tenant.AssignRolesOrMenusDto;
+import edu.travel.remote.feign.mode.dto.tenant.EduTenantPageDto;
+import edu.travel.remote.feign.mode.vo.tenant.AdminInfoRoleMenuVo;
+import edu.travel.remote.feign.mode.vo.tenant.EduTenantVo;
+import edu.travel.remote.feign.mode.vo.tenant.MenuTreeVo;
+import edu.travel.remote.feign.mode.vo.tenant.SysRoleVo;
 import edu.travel.resp.BaseResponse;
 import edu.travel.resp.PageResponse;
-import edu.travel.tenant.dto.AssignRolesOrMenus;
-import edu.travel.tenant.dto.EduTenantPageDto;
 import edu.travel.tenant.TenantRemoteController;
 import edu.travel.tenant.entity.EduTenant;
-import edu.travel.tenant.entity.SysMenu;
 import edu.travel.tenant.entity.SysRole;
 import edu.travel.tenant.service.ITenantService;
 import edu.travel.web.BaseController;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
+import java.util.*;
 
 @RestController
-@RequestMapping("/tenant")
+@RequestMapping("/user")
 public class TenantController  extends BaseController<EduTenant> implements TenantRemoteController {
     @Autowired
     private ITenantService tenantService;
 
     @GetMapping("/getTenantByPhoneNumber")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<EduTenant> getTenantByPhoneNumber() {
-        EduTenant principal = (EduTenant)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        EduTenant list = tenantService.getTenantByPhoneNumber(principal.getTenantPhone());
-        return PageResponse.out(200,"success",list);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<EduTenantVo> getTenantByPhoneNumber() {
+        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        EduTenant tenant = tenantService.getTenantByPhoneNumber(principal.getTenantPhone());
+        EduTenantVo vo = BeanUtil.copyProperties(tenant, EduTenantVo.class);
+        return PageResponse.out(200, "success", vo);
     }
 
     /**
      * 新增用户
-     * @param tenant
+     *
+     * @param addOrUpdateTenantDto
      * @return
      */
     @PostMapping("/addTenant")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> addTenant(EduTenant tenant) {
-        tenantService.addTenant(tenant);
-        return PageResponse.out(200,"success",true);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<EduTenantVo> addTenant(@RequestBody AddOrUpdateTenantDto addOrUpdateTenantDto) {
+        EduTenant eduTenant = tenantService.addTenant(addOrUpdateTenantDto);
+        return PageResponse.out(200, "success", BeanUtil.copyProperties(eduTenant, EduTenantVo.class));
     }
 
     /**
      * 通过ids删除用户
+     *
      * @param ids
      * @return
      */
     @PostMapping("/deleteTenantByIds")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> deleteTenant(List<Long> ids) {
-        tenantService.deleteByIds(ids);
-        return PageResponse.out(200,"success",true);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteTenant(@RequestBody List<Long> ids) {
+//        List<Long> list = ids.get("ids");
+        HashSet<Long> set = new HashSet<>(ids);
+        tenantService.deleteByIds(set);
+        return PageResponse.out(200, "success", true);
+    }
+
+    /**
+     * 通过id删除用户
+     *
+     * @param id
+     * @return
+     */
+    @PostMapping("/deleteTenantById")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> deleteTenant(Long id) {
+        Set<Long> list = new HashSet<>();
+        list.add(id);
+        tenantService.deleteByIds(list);
+        return PageResponse.out(200, "success", true);
     }
 
     /**
      * 修改用户信息
-     * @param tenant
+     *
+     * @param addOrUpdateTenantDto
      * @return
      */
     @PostMapping("/updateTenantById")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> updateTenant(EduTenant tenant) {
-        tenantService.updateTenant(tenant);
-        return PageResponse.out(200,"success",true);
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateTenant(@RequestBody AddOrUpdateTenantDto addOrUpdateTenantDto) {
+        tenantService.updateTenant(addOrUpdateTenantDto);
+        return PageResponse.out(200, "success", true);
     }
 
     /**
-     * 通过id查询用户信息
+     * 通过id查询商城用户信息
+     *
      * @param id
      * @return
      */
     @GetMapping("/getTenantById")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<EduTenant> getTenantById(Long id) {
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<SysRoleVo> getTenantById(Long id) {
         EduTenant tenant = tenantService.getTenantById(id);
-        return PageResponse.out(200,"success",tenant);
+        SysRoleVo eduTenantVo = BeanUtil.copyProperties(tenant, SysRoleVo.class);
+        return PageResponse.out(200, "success", eduTenantVo);
     }
 
+
     /**
      * 获取用户分页列表
+     *
      * @param tenantDto
      * @return
      */
     @GetMapping("/getTenantPageList")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<EduTenant>> getTenantList(EduTenantPageDto tenantDto) {
-    IPage<EduTenant> page = new Page<>(tenantDto.getPageNum(), tenantDto.getPageSize());
-    IPage<EduTenant> tenantIPage = tenantService.page(page, new LambdaQueryWrapper<EduTenant>().eq(EduTenant::getDeleteFlag, 0));
-    return PageResponse.out(200,"success",tenantIPage.getRecords(),(int)tenantIPage.getTotal(),(int)tenantIPage.getSize()) ;
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<EduTenantVo>> getTenantList(EduTenantPageDto tenantDto) {
+
+        IPage<EduTenant> page = new Page<>(tenantDto.getPageNum(), tenantDto.getPageSize());
+
+        LambdaQueryWrapper<EduTenant> queryWrapper = new LambdaQueryWrapper<EduTenant>()
+                .eq(EduTenant::getDeleteFlag, 0)
+                .eq(tenantDto.getId() != null, EduTenant::getId, tenantDto.getId())
+                .like(tenantDto.getTenantName() != null && !tenantDto.getTenantName().isEmpty(), EduTenant::getTenantName, tenantDto.getTenantName());
+        IPage<EduTenant> tenantIPage = tenantService.dictMapPage(page, queryWrapper);
+
+        List<EduTenantVo> eduTenantVos = BeanUtil.copyToList(tenantIPage.getRecords(), EduTenantVo.class);
+
+        return PageResponse.out(200, "success", eduTenantVos, (int) tenantIPage.getTotal(), (int) tenantIPage.getSize());
     }
 
     /**
      * 根据用户id获取用户角色列表(未分页)
+     *
      * @return
      */
     @GetMapping("/getRoleListByUserId")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<SysRole>> getRoleListByUserId() {
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<List<SysRoleVo>> getRoleListByUserId() {
         EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
         List<SysRole> roleList = tenantService.getRoleListByUserId(principal);
-        return PageResponse.out(200,"success",roleList);
+        List<SysRoleVo> sysRoleVos = BeanUtil.copyToList(roleList, SysRoleVo.class);
+        return PageResponse.out(200, "success", sysRoleVos);
     }
 
     /**
-     * 根据用户id获取用户菜单列表(未分页)
+     * 根据用户id给用户分配角色(可以多个角色)
+     *
+     * @param assignRolesOrMenusDto
      * @return
      */
-    @GetMapping("/getMenuListByUserId")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<List<SysMenu>> getMenuList() {
+    @PostMapping("/assignRolesToUser")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> assignRolesToUser(@RequestBody AssignRolesOrMenusDto assignRolesOrMenusDto) {
         EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        List<SysMenu> menuList = tenantService.getMenuList(principal);
-        return PageResponse.out(200,"success",menuList);
+        tenantService.assignRolesToUser(assignRolesOrMenusDto, principal);
+        return PageResponse.out(200, "success", true);
     }
 
     /**
-     * 根据用户id给用户分配角色(可以多个角色)
-     * @param assignRolesOrMenus
+     * 根据用户id给用户修改角色(可以多个角色)
+     *
+     * @param assignRolesOrMenusDto
      * @return
      */
-    @PostMapping("/assignRolesToUser")
-//    @PreAuthorize("hasRole('超级管理员')")
-    public BaseResponse<Boolean> assignRolesToUser(@RequestBody AssignRolesOrMenus assignRolesOrMenus) {
+    @PostMapping("updateRolesToUser")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> updateRolesToUser(@RequestBody AssignRolesOrMenusDto assignRolesOrMenusDto) {
         EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
-        tenantService.assignRolesToUser(assignRolesOrMenus);
-        return PageResponse.out(200,"success",true);
+        tenantService.updateRolesToUser(assignRolesOrMenusDto, principal);
+        return PageResponse.out(200, "success", true);
+    }
+
+    /**
+     * 获取管理用户的信息、角色列表、菜单树形
+     *
+     * @return
+     */
+    @GetMapping("/getTenantInfoRoleListMenuTree")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<AdminInfoRoleMenuVo> getTenantInfoRoleListMenuTree() {
+        EduTenant principal = (EduTenant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
+        EduTenant tenant = tenantService.getTenantById(principal.getId());
+        EduTenantVo eduTenantVo = BeanUtil.copyProperties(tenant, EduTenantVo.class);
+        List<SysRole> roleList = tenantService.getRoleListByUserId(principal);
+        List<SysRoleVo> roleVoList = BeanUtil.copyToList(roleList, SysRoleVo.class);
+        List<MenuTreeVo> menuTreeVos = tenantService.getTenantPageTreeList(principal);
+        AdminInfoRoleMenuVo vo = new AdminInfoRoleMenuVo();
+        vo.setTenantVo(eduTenantVo);
+        vo.setRoleVoList(roleVoList == null ? new ArrayList<>() : roleVoList);
+        vo.setMenuTreeVo(menuTreeVos);
+        return PageResponse.out(200, "success", vo);
     }
 
+    /**
+     * 单个禁用用户
+     *
+     * @param id
+     * @return
+     */
+    @PostMapping("/disableTenantById")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> disableTenantById(Long id) {
+        Assert.isTrue(ObjectUtil.isNotEmpty(id), "请选择用户");
+        Set<Long> list = new HashSet<>();
+        list.add(id);
+        tenantService.disableTenantByIds(list);
+        return PageResponse.out(200, "success", true);
+    }
+
+    /**
+     * 单个启用用户
+     *
+     * @param id
+     * @return
+     */
+    @PostMapping("/enableTenantById")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> enableTenantById(Long id) {
+        Assert.isTrue(ObjectUtil.isNotEmpty(id), "请选择用户");
+        Set<Long> list = new HashSet<>();
+        list.add(id);
+        tenantService.enableTenantByIds(list);
+        return PageResponse.out(200, "success", true);
+    }
 
+    /**
+     * 批量启用用户
+     *
+     * @param ids
+     * @return
+     */
+    @PostMapping("/enableTenantByIds")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> enableTenantByIds(@RequestBody List<Long> ids) {
+        tenantService.enableTenantByIds(new HashSet<>(ids));
+        return PageResponse.out(200, "success", true);
+    }
+
+    /**
+     * 批量禁用用户
+     *
+     * @param ids
+     * @return
+     */
+    @PostMapping("/disableTenantByIds")
+    @PreAuthorize("hasRole('超级管理员')")
+    public BaseResponse<Boolean> disableTenantByIds(@RequestBody List<Long> ids) {
+        tenantService.disableTenantByIds(new HashSet<>(ids));
+        return PageResponse.out(200, "success", true);
+    }
 }
+