权限管理系统,Lamda递归查询所有菜单

可以先去学习一下stream流

stream流学习

表结构建立,sql语句

这个是postgreSql 和mysql有一定的区别,注意一下!


CREATE TABLE "test"."sys_menu" (
	"id" INT8 NOT NULL,
	"parent_id" INT8 NOT NULL DEFAULT '-1' :: INTEGER,
	"name" VARCHAR ( 64 )  NOT NULL,
	"api_url" VARCHAR ( 255 ) ,
	"path" VARCHAR ( 255 ) ,
	"sort" INT2 NOT NULL,
	"create_time" TIMESTAMP ( 6 ),
	"update_time" TIMESTAMP ( 6 ),
	"type" INT2 NOT NULL DEFAULT 1,
	"hidden" INT2 NOT NULL DEFAULT 0,
	"tenant_id" VARCHAR ( 32 ) ,
	"belong_to" INT2 NOT NULL DEFAULT 1,
	CONSTRAINT "pk_sys_menu" PRIMARY KEY ( "id" ) 
);
ALTER TABLE "test"."sys_menu" OWNER TO "iscm";
CREATE INDEX "idx_parent_id" ON "test"."sys_menu" USING btree ( "parent_id" "pg_catalog"."int8_ops" ASC NULLS LAST );
COMMENT ON COLUMN "test"."sys_menu"."id" IS '主键';
COMMENT ON COLUMN "test"."sys_menu"."parent_id" IS '父菜单ID';
COMMENT ON COLUMN "test"."sys_menu"."name" IS '菜单名称';
COMMENT ON COLUMN "test"."sys_menu"."api_url" IS '请求url(type=2时有效)';
COMMENT ON COLUMN "test"."sys_menu"."path" IS '菜单路径';
COMMENT ON COLUMN "test"."sys_menu"."sort" IS '排序';
COMMENT ON COLUMN "test"."sys_menu"."create_time" IS '创建时间';
COMMENT ON COLUMN "test"."sys_menu"."update_time" IS '更新时间';
COMMENT ON COLUMN "test"."sys_menu"."type" IS '类型(1:菜单,2:按钮)';
COMMENT ON COLUMN "test"."sys_menu"."hidden" IS '是否隐藏(1:是,0:否)';
COMMENT ON COLUMN "test"."sys_menu"."tenant_id" IS '租户字段';
COMMENT ON COLUMN "test"."sys_menu"."belong_to" IS '菜单归属(1:后台菜单,2:商城菜单)';
COMMENT ON TABLE "test"."sys_menu" IS '系统菜单表';






CREATE TABLE "test"."sys_role" (
	"id" INT8 NOT NULL,
	"code" VARCHAR ( 32 )  NOT NULL,
	"name" VARCHAR ( 50 )  NOT NULL,
	"create_time" TIMESTAMP ( 6 ),
	"update_time" TIMESTAMP ( 6 ),
	"tenant_id" VARCHAR ( 32 ) ,
	"role_type" INT2,
	CONSTRAINT "pk_sys_role" PRIMARY KEY ( "id" ) 
);
ALTER TABLE "test"."sys_role" OWNER TO "iscm";
COMMENT ON COLUMN "test"."sys_role"."id" IS '主键';
COMMENT ON COLUMN "test"."sys_role"."code" IS '角色编码';
COMMENT ON COLUMN "test"."sys_role"."name" IS '角色名';
COMMENT ON COLUMN "test"."sys_role"."create_time" IS '创建时间';
COMMENT ON COLUMN "test"."sys_role"."update_time" IS '修改时间';
COMMENT ON COLUMN "test"."sys_role"."tenant_id" IS '租户字段';
COMMENT ON COLUMN "test"."sys_role"."role_type" IS '角色类型(0:系统管理员,1:零售商,2:供应商,3:零售商/供应商,4:省分管理员)';
COMMENT ON TABLE "test"."sys_role" IS '系统角色表';





CREATE TABLE "test"."sys_role_menu" ( "role_id" INT8 NOT NULL, "menu_id" INT8 NOT NULL, CONSTRAINT "pk_sys_role_menu" PRIMARY KEY ( "role_id", "menu_id" ) );
ALTER TABLE "test"."sys_role_menu" OWNER TO "iscm";
COMMENT ON TABLE "test"."sys_role_menu" IS '系统角色菜单表';


CREATE TABLE "test"."sys_role_user" ( "user_id" INT8 NOT NULL, "role_id" INT8 NOT NULL, CONSTRAINT "pk_sys_role_user" PRIMARY KEY ( "user_id", "role_id" ) );
ALTER TABLE "test"."sys_role_user" OWNER TO "iscm";
COMMENT ON TABLE "test"."sys_role_user" IS '系统用户角色表';













CREATE TABLE "test"."sys_user" (
	"id" INT8 NOT NULL,
	"username" VARCHAR ( 50 )  NOT NULL,
	"password" VARCHAR ( 60 )  NOT NULL,
	"nickname" VARCHAR ( 255 ) ,
	"head_img_url" VARCHAR ( 255 ) ,
	"mobile" VARCHAR ( 11 ) ,
	"sex" INT2,
	"enabled" INT2 NOT NULL DEFAULT 1,
	"type" VARCHAR ( 16 ) ,
	"create_time" TIMESTAMP ( 6 ),
	"update_time" TIMESTAMP ( 6 ),
	"company" VARCHAR ( 255 ) ,
	"open_id" VARCHAR ( 32 ) ,
	"is_del" INT2 NOT NULL DEFAULT 0,
	CONSTRAINT "pk_sys_user" PRIMARY KEY ( "id" ) 
);
ALTER TABLE "test"."sys_user" OWNER TO "iscm";
COMMENT ON COLUMN "test"."sys_user"."id" IS '主键';
COMMENT ON COLUMN "test"."sys_user"."username" IS '账号';
COMMENT ON COLUMN "test"."sys_user"."password" IS '密码';
COMMENT ON COLUMN "test"."sys_user"."nickname" IS '姓名';
COMMENT ON COLUMN "test"."sys_user"."head_img_url" IS '头像';
COMMENT ON COLUMN "test"."sys_user"."mobile" IS '手机号';
COMMENT ON COLUMN "test"."sys_user"."sex" IS '性别(0:未知,1:男,2:女)';
COMMENT ON COLUMN "test"."sys_user"."enabled" IS '有效状态(1:启用,0:停用)';
COMMENT ON COLUMN "test"."sys_user"."type" IS '类型';
COMMENT ON COLUMN "test"."sys_user"."create_time" IS '创建时间';
COMMENT ON COLUMN "test"."sys_user"."update_time" IS '修改时间';
COMMENT ON COLUMN "test"."sys_user"."company" IS '公司';
COMMENT ON COLUMN "test"."sys_user"."open_id" IS 'openid';
COMMENT ON COLUMN "test"."sys_user"."is_del" IS '删除标识(0-正常,1:删除)';
COMMENT ON TABLE "test"."sys_user" IS '系统用户表';



CREATE TABLE "test"."sys_user_company" (
	"id" INT8 NOT NULL,
	"user_id" INT8 NOT NULL,
	"role_type" INT2 NOT NULL,
	"company_code" VARCHAR ( 20 )  NOT NULL,
	"province_code" VARCHAR ( 20 )  NOT NULL,
	"create_time" TIMESTAMP ( 6 ),
	"update_time" TIMESTAMP ( 6 ),
	"merchant_id" INT8,
	CONSTRAINT "pk_sys_user_organization" PRIMARY KEY ( "id" ) 
);
ALTER TABLE "test"."sys_user_company" OWNER TO "iscm";
CREATE INDEX "idx_sys_user_organization_1" ON "test"."sys_user_company" USING btree ( "user_id" "pg_catalog"."int8_ops" ASC NULLS LAST );
COMMENT ON COLUMN "test"."sys_user_company"."id" IS '主键';
COMMENT ON COLUMN "test"."sys_user_company"."user_id" IS '用户id';
COMMENT ON COLUMN "test"."sys_user_company"."role_type" IS '角色类型(0:系统管理员,1:零售商,2:供应商,3:零售商/供应商,4:省分管理员)';
COMMENT ON COLUMN "test"."sys_user_company"."company_code" IS '公司编码';
COMMENT ON COLUMN "test"."sys_user_company"."province_code" IS '省份编码';
COMMENT ON COLUMN "test"."sys_user_company"."create_time" IS '创建时间';
COMMENT ON COLUMN "test"."sys_user_company"."update_time" IS '修改时间';
COMMENT ON COLUMN "test"."sys_user_company"."merchant_id" IS '商户id';
COMMENT ON TABLE "test"."sys_user_company" IS '用户所属公司组织';


1. 封装一个菜单的返回实体给前端


@Data
@ApiModel("菜单返回参数模型")
public class QueryMenuResp {
	@ApiModelProperty("ID")
	@JsonFormat(shape = JsonFormat.Shape.STRING)
	private Long id;
	/**
	 * 父菜单ID
	 */
	@ApiModelProperty("父菜单ID")
	@JsonFormat(shape = JsonFormat.Shape.STRING)
	private Long parentId;
	/**
	 * 菜单名
	 */
	@ApiModelProperty("菜单名")
	private String name;
	/**
	 * 菜单路径
	 */
	@ApiModelProperty("菜单路径")
	private String path;
	/**
	 * 排序
	 */
	@ApiModelProperty("排序")
	private Integer sort;
	/**
	 * 是否隐藏(1:是,0:否)
	 */
	@ApiModelProperty("是否隐藏(1:是,0:否)")
	private Integer hidden;
	/**
	 * 当前角色选中状态
	 */
	@ApiModelProperty("当前角色选中状态(1:是,0:否,仅findAvaiableMenuTree接口返回)")
	private Integer checked;
	/**
	 * 下级菜单
	 */
	@ApiModelProperty("下级菜单")
	private List<QueryMenuResp> subMenus;
}




2.先查询出来一级菜单,然后查询 非一级菜单进行递归调用,直到全部菜单查询出来

    @ParamCheck
    @ApiOperation(value = "查询所有菜单以树形结构返回")
    @PostMapping("/findMenuTree")
    public Result<List<QueryMenuResp>> findMenuTree(@RequestBody @ModelCheck QueryMenuParam param) {
    	log.info("findMenuTree param: {}", param);
    	
    	if (!MenuBelongTo.isLegalMenuBelong(param.getBelongTo())) {
    		return Result.error("非法的菜单归属类型");
    	}
    	
    	List<QueryMenuResp> allMenuList =  ModelChangeUtils.changeMenuRespList(menuService.findMenus(param.getBelongTo()));
    	// 一级菜单
    	List<QueryMenuResp> rootMenus = allMenuList.stream()
				.filter(r -> r.getParentId().equals(CommonConstant.ROOT_MENU_PARENT_ID))
				.collect(Collectors.toList());
    	// 非一级菜单
		List<QueryMenuResp> notRootMenus = allMenuList.stream()
				.filter(r -> !r.getParentId().equals(CommonConstant.ROOT_MENU_PARENT_ID))
				.collect(Collectors.toList());
		
		// 构造树形结构
		for (QueryMenuResp menu : rootMenus) {
            List<QueryMenuResp> subMenus = ModelChangeUtils.iterateMenus(notRootMenus, menu.getId());
            menu.setSubMenus(subMenus);
        }
		
        return Result.succeed(rootMenus);
    }


3.递归方法


public class ModelChangeUtils {
	/**
     * 多级菜单查询方法
     * @param menuList 不包含最高层次菜单的菜单集合
     * @param parentId 父菜单id
     * @return
     */
    public static List<QueryMenuResp> iterateMenus(List<QueryMenuResp> menuList, Long parentId){
        List<QueryMenuResp> result = new ArrayList<QueryMenuResp>();
        for (QueryMenuResp menu : menuList) {
            if (parentId.equals(menu.getParentId())){
                //递归查询当前子菜单的子菜单
                List<QueryMenuResp> iterateMenu = iterateMenus(menuList, menu.getId());
                menu.setSubMenus(iterateMenu);
                result.add(menu);
            }
        }
        return result;
    }

}

4.菜单表结构实体

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_menu")
public class SysMenu extends SuperEntity<SysRole> {
	private static final long serialVersionUID = 749360940290141180L;

	/**
	 * 父菜单ID
	 */
	private Long parentId;
	/**
	 * 菜单名
	 */
	private String name;
	/**
	 * 请求地址(type=2时有效)
	 */
	private String apiUrl;
	/**
	 * 菜单路径
	 */
	private String path;
	/**
	 * 排序
	 */
	private Integer sort;
	/**
	 * 类型(1:菜单,2:按钮)
	 */
	private Integer type;
	/**
	 * 是否隐藏(1:是,0:否)
	 */
	private Integer hidden;
	/**
	 * 菜单归属(1:后台管理菜单,2:商城菜单)
	 */
	private Integer belongTo;
	
	@TableField(exist = false)
	private List<SysMenu> subMenus;
}



5.角色表结构实体

/**
 * 
 * 角色
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_role")
public class SysRole  {
private Long id;
private Date create_time;
private Date update_time;
    private static final long serialVersionUID = 4497149010220586111L;
    private String code;
    private String name;
    /**
     * 角色类型(0:系统管理员,1:零售商,2:供应商,3:零售商/供应商,4:省分管理员)
     */
    private Integer roleType;
    @TableField(exist = false)
    private Long userId;
}


6 加上角色菜单表实体

public class SysRoleMenu{

private Long roleId;
private Long menuId;

}

7.菜单实体表



import java.util.List;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 *
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_menu")
public class SysMenu extends SuperEntity<SysRole> {
	private static final long serialVersionUID = 749360940290141180L;

	/**
	 * 父菜单ID
	 */
	private Long parentId;
	/**
	 * 菜单名
	 */
	private String name;
	/**
	 * 请求地址(type=2时有效)
	 */
	private String apiUrl;
	/**
	 * 菜单路径
	 */
	private String path;
	/**
	 * 排序
	 */
	private Integer sort;
	/**
	 * 类型(1:菜单,2:按钮)
	 */
	private Integer type;
	/**
	 * 是否隐藏(1:是,0:否)
	 */
	private Integer hidden;
	/**
	 * 菜单归属(1:后台管理菜单,2:商城菜单)
	 */
	private Integer belongTo;
	
	@TableField(exist = false)
	private List<SysMenu> subMenus;
}

8.用户表实体



import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.List;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 
 * 用户实体
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_user")
public class SysUser extends SuperEntity<SysUser> {
	private static final long serialVersionUID = -5886012896705137070L;

	private String username;
	private String password;
	private String nickname;
	private String headImgUrl;
	private String mobile;
	private Integer sex;
	@TableField(value = "enabled")
	private Integer userEnabled;
	private String type;
	private String openId;
	@TableLogic
	private Integer isDel;

	@TableField(exist = false)
	private List<SysRole> roles;
	@TableField(exist = false)
	private String roleId;
	@TableField(exist = false)
	private String oldPassword;
	@TableField(exist = false)
	private String newPassword;
	
	//---------------- iscm-sc扩展 ----------------//
	/**
	 * 角色类型
	 */
	@TableField(exist = false)
	private Integer roleType;
	/**
	 * 公司编码
	 */
	@TableField(exist = false)
	private String companyCode;
	/**
	 * 商户ID
	 */
	@TableField(exist = false)
	private Long merchantId;
	/**
	 * 省份编码
	 */
	@TableField(exist = false)
	private String provinceCode;
}


9.SuperEntity所有的基表字段,可以让所有的实体类extends这个

import java.util.Date;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.eshore.khala.common.constant.CommonConstant;
import com.fasterxml.jackson.annotation.JsonFormat;

import lombok.Getter;
import lombok.Setter;

/**
 * 实体父类
 *
 * @author khala
 */
@Setter
@Getter
public class SuperEntity<T extends Model<?>> extends Model<T> {
    /**
	 * 
	 */
	private static final long serialVersionUID = -1642699353161738353L;
	/**
     * 主键ID
     */
    @TableId(type = IdType.ASSIGN_ID)//基于雪花算法生成long主键
    private Long id;
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = CommonConstant.DATETIME_FORMAT)
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = CommonConstant.DATETIME_FORMAT)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有时间指导毕业设计

觉得写的好的话可以给我打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值