日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Jeecg-boot 2.4.6+ 多租户改造方案(涉及菜单部门角色等基础模块)

發布時間:2025/3/16 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Jeecg-boot 2.4.6+ 多租户改造方案(涉及菜单部门角色等基础模块) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

場景:

jeecg boot提供了多租戶的配置,但是并沒有完整實現該功能,此文就原系統表的菜單、部門、角色、用戶為例實現多租戶功能實現方案。

  • 修改菜單表:sys_permission 增加兩個字段tenant_id(租戶ID),并且設置tenant_id的初始值(注意實體需加對應字段)
  • ALTER TABLE `sys_permission` ADD COLUMN `tenant_id` int(1) NULL COMMENT '租戶ID' AFTER `internal_or_external`; update sys_permission set tenant_id = 1;
  • 修改部門表(注意實體需加字段)
  • ALTER TABLE `sys_depart` ADD COLUMN `tenant_id` int(1) NULL COMMENT '租戶ID' AFTER `update_time`; update sys_depart set tenant_id = 1;
  • 修改角色表(注意實體需加字段)
  • ALTER TABLE `sys_role` ADD COLUMN `tenant_id` int(1) NULL COMMENT '租戶ID' AFTER `update_time`; update sys_role set tenant_id = 1;
  • 配置基礎菜單json, 做多租戶的時候,需要將部分系統管理的菜單復制多分分配給不同租戶角色,所以需要配置一個json文件,詳細見補丁文件

  • 修改代碼:全項目搜索注解@RequiresRoles @RequiresPermissions,刪除,沒找到忽略

  • 修改SysDepartMapper.xml增加代碼

    <!-- 根據父ID查詢同級部門 --> <select id="querySameLevelDepart" parameterType="String" resultType="org.jeecg.modules.system.entity.SysDepart">select * from sys_depart<choose><when test="pid != null and pid != ''">where parent_id = #{pid,jdbcType=VARCHAR}</when><otherwise>where parent_id is null or parent_id=''</otherwise></choose>order by org_code desc </select>

    修改SysDepartMapper增加代碼:

    @InterceptorIgnore(tenantLine = "true")List<SysDepart> querySameLevelDepart(@Param("pid")String pid);

    接口ISysDepartService新增代碼如下:

    List<SysDepart> querySameLevelDepart(String pid);

    實現類SysDepartServiceImpl新增:

    @Overridepublic List<SysDepart> querySameLevelDepart(String pid) {return baseMapper.querySameLevelDepart(pid);}

    還是修改SysDepartServiceImpl: 將注解@Cacheable(value = CacheConstant.SYS_DEPARTS_CACHE) @Cacheable(value = CacheConstant.SYS_DEPART_IDS_CACHE)去掉

    修改SysPermissionTree代碼:

    /*** 租戶ID*/ private java.lang.Integer tenantId;/*** 是否是基礎菜單 1是0否 如果是1 新增租戶的時候需要復制*/ private java.lang.Boolean baseFlag;

    修改OrgCodeRule代碼:

  • 修改租戶表:sys_tenant 增加一個字段 pre_code(角色編碼前綴)

  • 修改新增租戶的邏輯 租戶接口:

  • public interface ISysTenantService extends IService<SysTenant> {/*** 保存* @param sysTenant*/void saveSysTenant(SysTenant sysTenant);}

    實現類SysTenantServiceImpl:

    package org.jeecg.modules.system.service.impl;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.mapper.SysPermissionMapper; import org.jeecg.modules.system.mapper.SysTenantMapper; import org.jeecg.modules.system.service.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.FileCopyUtils;import javax.annotation.Resource; import java.io.IOException; import java.util.*;@Service @Slf4j public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements ISysTenantService {@AutowiredISysPermissionService sysPermissionService;@AutowiredISysUserService sysUserService;@AutowiredISysRoleService sysRoleService;@AutowiredISysUserRoleService sysUserRoleService;@AutowiredISysRolePermissionService sysRolePermissionService;private List<SysPermission> getPermissionList(){// 如果設置了BaseFlag字段配置 可以讀取數據庫 /* LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();query.eq(SysPermission::getBaseFlag, true);query.eq(SysPermission::getTenantId, 1);List<SysPermission> ls = sysPermissionService.list(query);*/// 讀取json 需要自己提前在baseRoute.json文件里配置菜單信息String jsonPath = "static/system/baseRoute.json";ClassPathResource classPathResource = new ClassPathResource(jsonPath);byte[] bytes = new byte[0];try {bytes = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());} catch (IOException e) {e.printStackTrace();}String json = new String(bytes);JSONArray array = JSON.parseArray(json);List<SysPermission> ls = array.toJavaList(SysPermission.class);return ls;}@Override@Transactionalpublic void saveSysTenant(SysTenant sysTenant) {this.save(sysTenant);int tenantId = sysTenant.getId();List<SysPermission> ls = getPermissionList();Collection<String> menuIds = setPermissionTenant(ls, tenantId);sysPermissionService.saveBatch(ls);// 修改admin用戶的租戶SysUser user = sysUserService.getUserByName("admin");String refTenantIds = user.getRelTenantIds();if(oConvertUtils.isEmpty(refTenantIds)){user.setRelTenantIds(String.valueOf(tenantId));}else{user.setRelTenantIds(refTenantIds+","+tenantId);}sysUserService.updateById(user);// 添加admin角色SysRole role = new SysRole();role.setRoleCode(sysTenant.getPreCode()+"_admin");role.setRoleName("管理員");role.setTenantId(tenantId);sysRoleService.save(role);// 添加角色 用戶關系SysUserRole sysUserRole = new SysUserRole();// TODO is ok?sysUserRole.setRoleId(role.getId());sysUserRole.setUserId(user.getId());sysUserRoleService.save(sysUserRole);// 添加角色 菜單關系List<SysRolePermission> list = new ArrayList<>();for(String menuId: menuIds){SysRolePermission sp = new SysRolePermission();sp.setPermissionId(menuId);sp.setRoleId(role.getId());list.add(sp);}sysRolePermissionService.saveBatch(list);}private String randomId(){long id = IdWorker.getId();return String.valueOf(id);}private Collection<String> setPermissionTenant(List<SysPermission> ls, int tenantId){// 循環兩次 第一次設置ID和tenantId 第二次設置pidMap<String, String> map = new HashMap<>();for(SysPermission p: ls){String oldId = p.getId();String newId = randomId();map.put(oldId, newId);p.setId(newId);p.setTenantId(tenantId);p.setCreateBy(null);p.setCreateTime(null);p.setUpdateBy(null);p.setUpdateTime(null);}for(SysPermission p: ls){String oldPid = p.getParentId();if(oConvertUtils.isNotEmpty(oldPid)){String newPid = map.get(oldPid);if(oConvertUtils.isNotEmpty(newPid)){p.setParentId(newPid);}else{// TODO 一般情況下這個newPid是肯定有值的 如果沒有值 說明當前節點的父節點 沒有設置為基礎路由 那么 需要遞歸獲取 所有父級節點 挨個設置一下即可}}}return map.values();} }

    系統做成多租戶后,新增租戶的時候菜單會復制多份,如果這個時候想再切回來,那么多余的數據需要被清除,可以執行下面的sql:

    delete from sys_role_permission where permission_id in (select id from sys_permission where tenant_id <> 1); delete from sys_role_permission where role_id in (select id from sys_role where tenant_id <> 1); delete from sys_permission where tenant_id <> 1;delete from sys_user_role where role_id in (select id from sys_role where tenant_id <> 1); delete from sys_role where tenant_id <> 1;delete from sys_user_depart where dep_id in (select id from sys_depart where tenant_id <> 1); delete from sys_depart where tenant_id <> 1;

    代碼升級文件:鏈接:https://pan.baidu.com/s/1uwj2khoE6t_IYqfxa57ssQ 提取碼:6v7h

    ===================================
    上文多租戶要求配置一個基礎路由的json文件,里面的數據如果不想手動編寫可以在菜單表添加一個特殊標識 ,然后查詢需要的數據,將數據以json格式輸出,拿到json后配置到baseRoute.json文件即可:

    LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();

    // 這里的baseFlag就是一個特殊標識,說明該菜單需要被多租戶復制分配

    query.eq(SysPermission::getBaseFlag, true);query.eq(SysPermission::getTenantId, 1);List<SysPermission> ls = sysPermissionService.list(query); JSONArray array = new JSONArray();for(SysPermission p: ls){Map<String, Object> map = new LinkedHashMap<>();map.put("name", p.getName());map.put("id", p.getId());map.put("parentId", p.getParentId());map.put("component", p.getComponent());map.put("componentName", p.getComponentName());map.put("url", p.getUrl());map.put("route", p.isRoute());map.put("delFlag", p.getDelFlag());map.put("sortNo", p.getSortNo());map.put("icon", p.getIcon());map.put("alwaysShow", p.isAlwaysShow());map.put("hidden", p.isHidden());map.put("internalOrExternal", p.isInternalOrExternal());map.put("keepAlive", p.isKeepAlive());map.put("leaf", p.isLeaf());map.put("menuType", p.getMenuType());map.put("ruleFlag", p.getRuleFlag());JSONObject json = new JSONObject(map);array.add(json);}System.out.println("======================");System.out.println(array.toJSONString());System.out.println("======================");

    其他:用戶列表的saas實現

    不建議直接把用戶表加到配置中,建議單獨做一個列表,針對租戶ID配置通過配置數據權限的方式實現。
    因為用戶邏輯代碼太多了,改動成本太高,單獨做一個菜單給只自己看自己租戶的數據即可。

    總結

    以上是生活随笔為你收集整理的Jeecg-boot 2.4.6+ 多租户改造方案(涉及菜单部门角色等基础模块)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 天天爱天天干天天操 | 国产午夜福利一区二区 | 国产精品无码久久久久成人app | 巨大胸大乳奶电影 | 亚洲永久免费观看 | 肥臀浪妇太爽了快点再快点 | 迈开腿让我尝尝你的小草莓 | 天天射天天爽 | av资源库| 人人爱人人艹 | mm视频在线观看 | fc2ppv色の美マンに中出し | 国产乱淫av | 午夜国产片 | 亚洲天堂五月 | av有码在线 | 在线观看sm | 粉嫩av网| 麻豆精品影院 | 久久久久一区 | 国产精选自拍 | 看片国产 | 国产人澡人澡澡澡人碰视频 | 国产精品日韩专区 | 国产精品自拍视频 | 欧美第一视频 | 日本中文字幕第一页 | 香蕉视频一区二区 | 日日爱视频 | 一级h片| 亚洲热久久 | 久草国产在线观看 | 国产色一区二区 | 看片地址| 国精品无码一区二区三区 | 精品视频在线免费观看 | 久青草国产在线 | 天堂网免费视频 | 好吊色欧美一区二区三区视频 | 国产aaa大片 | 国产无遮挡呻吟娇喘视频 | 经典一区二区三区 | 亚洲精品女人 | 一女二男一黄一片 | 亚洲一区二三区 | 超碰精品在线观看 | 午夜视频福利在线 | 国产91影院| 麻豆视屏 | 日韩中文电影 | 人人超碰97| 日韩一道本 | 麻豆视频在线观看免费 | 国产一区二区黄色 | 国产美女自拍视频 | 成年人黄色片网站 | 40一50一60老女人毛片 | 五月婷婷六月丁香综合 | jizz欧美性11 | 欧美日韩综合在线 | 一级一片免费播放 | 男人和女人插插 | 日韩乱码人妻无码中文字幕 | 一炮成瘾1v1高h | 秋霞电影一区二区 | 亚洲精品国产精品国自产观看 | 91视频99| 麻豆传媒在线 | 免费在线色 | 国产喷水在线 | jizz日本大全 | 久久av一区| 91精品国产乱码久久久张津瑜 | 国产乱人伦 | 就爱啪啪网 | 香蕉视频18 | 一区二区成人在线观看 | 亚洲香蕉视频 | 在线高清观看免费观看 | 午夜精品久久久久久久四虎美女版 | 67194少妇在线观看 | 冲田杏梨一区二区三区 | 午夜影院免费体验区 | 91看片淫黄大片 | 成人午夜网站 | 亚洲视频综合 | 综合激情在线 | 国产精品久久久久久亚洲伦 | 久久精品人妻一区二区三区 | h网站免费在线观看 | 国产精品无码人妻一区二区在线 | 福利一区三区 | 九九热最新网址 | 国产乱码在线 | 一级片美女| 色噜噜影院 | 日本毛片在线观看 | 免费看黄色网址 | 国产激情综合五月久久 |