|
@@ -15,6 +15,7 @@ import com.fs.common.exception.CustomException;
|
|
|
import com.fs.common.utils.StringUtils;
|
|
import com.fs.common.utils.StringUtils;
|
|
|
import com.fs.common.utils.poi.ExcelUtil;
|
|
import com.fs.common.utils.poi.ExcelUtil;
|
|
|
import com.fs.framework.datasource.DynamicDataSourceContextHolder;
|
|
import com.fs.framework.datasource.DynamicDataSourceContextHolder;
|
|
|
|
|
+import com.fs.framework.datasource.TenantDataSourceContextHelper;
|
|
|
import com.fs.framework.datasource.TenantDataSourceManager;
|
|
import com.fs.framework.datasource.TenantDataSourceManager;
|
|
|
import com.fs.system.domain.SysConfig;
|
|
import com.fs.system.domain.SysConfig;
|
|
|
import com.fs.system.service.ISysConfigService;
|
|
import com.fs.system.service.ISysConfigService;
|
|
@@ -30,8 +31,10 @@ import org.springframework.validation.annotation.Validated;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
|
+import java.util.Collections;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -56,6 +59,9 @@ public class TenantInfoController extends BaseController
|
|
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private TenantDataSourceManager tenantDataSourceManager;
|
|
private TenantDataSourceManager tenantDataSourceManager;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private TenantDataSourceContextHelper tenantContextHelper;
|
|
|
/**
|
|
/**
|
|
|
* 查询租户基础信息列表
|
|
* 查询租户基础信息列表
|
|
|
*/
|
|
*/
|
|
@@ -378,7 +384,12 @@ public class TenantInfoController extends BaseController
|
|
|
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
|
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
|
|
}
|
|
}
|
|
|
menu.setUpdateBy(getUsername());
|
|
menu.setUpdateBy(getUsername());
|
|
|
- return toAjax(tenantInfoService.updateMenu(menu));
|
|
|
|
|
|
|
+ int result = tenantInfoService.updateMenu(menu);
|
|
|
|
|
+ if (result > 0) {
|
|
|
|
|
+ SysMenu fullMenu = tenantInfoService.selectMenuById(menu.getMenuId());
|
|
|
|
|
+ CompletableFuture.runAsync(() -> syncSysMenuUpdateToTenants(fullMenu));
|
|
|
|
|
+ }
|
|
|
|
|
+ return toAjax(result);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -402,7 +413,12 @@ public class TenantInfoController extends BaseController
|
|
|
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
|
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
|
|
}
|
|
}
|
|
|
menu.setUpdateBy(getUsername());
|
|
menu.setUpdateBy(getUsername());
|
|
|
- return toAjax(tenantInfoService.updateComMenu(menu));
|
|
|
|
|
|
|
+ int result = tenantInfoService.updateComMenu(menu);
|
|
|
|
|
+ if (result > 0) {
|
|
|
|
|
+ TenantCompanyMenu fullMenu = tenantInfoService.getTenantComMenu(menu.getMenuId());
|
|
|
|
|
+ CompletableFuture.runAsync(() -> syncComMenuUpdateToTenants(fullMenu));
|
|
|
|
|
+ }
|
|
|
|
|
+ return toAjax(result);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
|
|
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
|
|
@@ -414,7 +430,11 @@ public class TenantInfoController extends BaseController
|
|
|
{
|
|
{
|
|
|
return AjaxResult.error("存在子菜单,不允许删除");
|
|
return AjaxResult.error("存在子菜单,不允许删除");
|
|
|
}
|
|
}
|
|
|
- return toAjax(tenantInfoService.deleteMenuById(menuId));
|
|
|
|
|
|
|
+ int result = tenantInfoService.deleteMenuById(menuId);
|
|
|
|
|
+ if (result > 0) {
|
|
|
|
|
+ CompletableFuture.runAsync(() -> syncSysMenuDeleteToTenants(menuId));
|
|
|
|
|
+ }
|
|
|
|
|
+ return toAjax(result);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
|
|
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
|
|
@@ -426,6 +446,107 @@ public class TenantInfoController extends BaseController
|
|
|
{
|
|
{
|
|
|
return AjaxResult.error("存在子菜单,不允许删除");
|
|
return AjaxResult.error("存在子菜单,不允许删除");
|
|
|
}
|
|
}
|
|
|
- return toAjax(tenantInfoService.deleteComMenuById(menuId));
|
|
|
|
|
|
|
+ int result = tenantInfoService.deleteComMenuById(menuId);
|
|
|
|
|
+ if (result > 0) {
|
|
|
|
|
+ CompletableFuture.runAsync(() -> syncComMenuDeleteToTenants(menuId));
|
|
|
|
|
+ }
|
|
|
|
|
+ return toAjax(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ========== 菜单模板变更 → 异步同步到所有启用租户库 ==========
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 同步 sys 菜单修改到所有 status=1 的租户库(仅已存在该菜单的租户执行 upsert)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void syncSysMenuUpdateToTenants(SysMenu menu) {
|
|
|
|
|
+ List<TenantInfo> tenants = getActiveTenantsForSync();
|
|
|
|
|
+ for (TenantInfo tenant : tenants) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ tenantContextHelper.executeInTenant(tenant, () -> {
|
|
|
|
|
+ int count = tenantInfoMapper.countTenantSysMenuById(menu.getMenuId());
|
|
|
|
|
+ if (count > 0) {
|
|
|
|
|
+ tenantInfoMapper.upsertSysMenu(Collections.singletonList(menu));
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("同步sys菜单修改失败: tenant={}, menuId={}", tenant.getTenantCode(), menu.getMenuId(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 同步 sys 菜单删除到所有 status=1 的租户库(仅已存在该菜单的租户执行删除)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void syncSysMenuDeleteToTenants(Long menuId) {
|
|
|
|
|
+ List<TenantInfo> tenants = getActiveTenantsForSync();
|
|
|
|
|
+ for (TenantInfo tenant : tenants) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ tenantContextHelper.executeInTenant(tenant, () -> {
|
|
|
|
|
+ int count = tenantInfoMapper.countTenantSysMenuById(menuId);
|
|
|
|
|
+ if (count > 0) {
|
|
|
|
|
+ List<Long> menuIds = Collections.singletonList(menuId);
|
|
|
|
|
+ tenantInfoMapper.deleteSysRoleMenuByMenuIds(menuIds);
|
|
|
|
|
+ tenantInfoMapper.deleteTenantSysMenuByIds(menuIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("同步sys菜单删除失败: tenant={}, menuId={}", tenant.getTenantCode(), menuId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 同步 com 菜单修改到所有 status=1 的租户库(仅已存在该菜单的租户执行 upsert)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void syncComMenuUpdateToTenants(TenantCompanyMenu menu) {
|
|
|
|
|
+ List<TenantInfo> tenants = getActiveTenantsForSync();
|
|
|
|
|
+ for (TenantInfo tenant : tenants) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ tenantContextHelper.executeInTenant(tenant, () -> {
|
|
|
|
|
+ int count = tenantInfoMapper.countTenantComMenuById(menu.getMenuId());
|
|
|
|
|
+ if (count > 0) {
|
|
|
|
|
+ tenantInfoMapper.upsertComMenu(Collections.singletonList(menu));
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("同步com菜单修改失败: tenant={}, menuId={}", tenant.getTenantCode(), menu.getMenuId(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 同步 com 菜单删除到所有 status=1 的租户库(仅已存在该菜单的租户执行删除)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void syncComMenuDeleteToTenants(Long menuId) {
|
|
|
|
|
+ List<TenantInfo> tenants = getActiveTenantsForSync();
|
|
|
|
|
+ for (TenantInfo tenant : tenants) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ tenantContextHelper.executeInTenant(tenant, () -> {
|
|
|
|
|
+ int count = tenantInfoMapper.countTenantComMenuById(menuId);
|
|
|
|
|
+ if (count > 0) {
|
|
|
|
|
+ List<Long> menuIds = Collections.singletonList(menuId);
|
|
|
|
|
+ tenantInfoMapper.deleteComRoleMenuByMenuIds(menuIds);
|
|
|
|
|
+ tenantInfoMapper.deleteTenantComMenuByIds(menuIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("同步com菜单删除失败: tenant={}, menuId={}", tenant.getTenantCode(), menuId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询所有 status=1(启用)的租户,在主库执行
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<TenantInfo> getActiveTenantsForSync() {
|
|
|
|
|
+ return tenantContextHelper.executeInMaster(() -> {
|
|
|
|
|
+ TenantInfo query = new TenantInfo();
|
|
|
|
|
+ query.setStatus(1);
|
|
|
|
|
+ return tenantInfoService.selectTenantInfoList(query);
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|