xgb 1 ヶ月 前
コミット
0eee8887d0

+ 427 - 0
fs-admin/src/main/java/com/fs/admin/controller/tenant/TenantInfoController.java

@@ -0,0 +1,427 @@
+package com.fs.admin.controller.tenant;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.annotation.Log;
+import com.fs.common.constant.UserConstants;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.entity.SysMenu;
+import com.fs.common.core.domain.entity.TenantCompanyMenu;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.enums.DataSourceType;
+import com.fs.common.exception.CustomException;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.framework.datasource.DynamicDataSourceContextHolder;
+import com.fs.framework.datasource.TenantDataSourceManager;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.service.ISysConfigService;
+import com.fs.tenant.domain.TenantInfo;
+import com.fs.tenant.dto.MenuDto;
+import com.fs.tenant.dto.SysConfigDto;
+import com.fs.tenant.mapper.TenantInfoMapper;
+import com.fs.tenant.service.TenantInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.CollectionUtils;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 租户基础信息Controller(SaaS 下租户表仅在主库,强制走主库)
+ *
+ * @author fs
+ * @date 2026-01-23
+ */
+@DataSource(DataSourceType.MASTER)
+@RestController("adminTenantInfoController")
+@RequestMapping("/tenant/tenant")
+public class TenantInfoController extends BaseController
+{
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private TenantInfoMapper tenantInfoMapper;
+
+    @Autowired
+    private TenantDataSourceManager tenantDataSourceManager;
+    /**
+     * 查询租户基础信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(TenantInfo tenantInfo)
+    {
+        startPage();
+        List<TenantInfo> list = tenantInfoService.selectTenantInfoList(tenantInfo);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询所有租户id以及租户名称 租户编码
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:list')")
+    @GetMapping("/tenantList")
+    public R tenantList(TenantInfo tenantInfo)
+    {
+        return R.ok().put("rows",tenantInfoService.tenantList(tenantInfo));
+    }
+
+    /**
+     * 导出租户基础信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:export')")
+    @Log(title = "租户基础信息", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(TenantInfo tenantInfo)
+    {
+        List<TenantInfo> list = tenantInfoService.selectTenantInfoList(tenantInfo);
+        ExcelUtil<TenantInfo> util = new ExcelUtil<TenantInfo>(TenantInfo.class);
+        return util.exportExcel(list, "租户基础信息数据");
+    }
+
+    /**
+     * 获取租户基础信息详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return AjaxResult.success(tenantInfoService.selectTenantInfoById(id));
+    }
+
+    /**
+     * 新增租户基础信息
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:add')")
+    @Log(title = "租户基础信息", businessType = BusinessType.INSERT)
+    @PostMapping
+    public R add(@RequestBody TenantInfo tenantInfo)
+    {
+        int i = tenantInfoService.insertTenantInfo(tenantInfo);
+        return i > 0 ? R.ok("租户数据库初始化中,请稍后") : R.error("租户创建失败");
+    }
+
+    /**
+     * 修改租户基础信息
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:edit')")
+    @Log(title = "修改租户基础信息", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody TenantInfo tenantInfo)
+    {
+        return toAjax(tenantInfoService.updateTenantInfo(tenantInfo));
+    }
+
+    /**
+     * 删除租户基础信息
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:remove')")
+    @Log(title = "删除租户基础信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        return toAjax(tenantInfoService.deleteTenantInfoByIds(ids));
+    }
+
+    /**
+     * 租户菜单修改(获取租户菜单)
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:edit')")
+    @PostMapping("/menu")
+    public R menuChange(@RequestBody Map<String,Object> map)
+    {
+        String id = map.get("id").toString();
+        TenantInfo tenantInfo = tenantInfoMapper.selectTenantInfoById(id);
+        if (tenantInfo.getStatus() == 2) {
+            throw new CustomException("租户初始化中");
+        }
+
+        // 先查一下标准菜单
+        String flag = map.get("flag").toString();
+        if ("sys".equals(flag)){
+            List<SysMenu> sysMenus = tenantInfoMapper.selectMenuList(new SysMenu());
+            tenantDataSourceManager.switchTenant(tenantInfo);
+            return tenantInfoService.menuChange(flag, sysMenus,null);
+        }
+
+        List<TenantCompanyMenu> companyMenus = tenantInfoMapper.selectCompanyMenuList(new TenantCompanyMenu());
+        tenantDataSourceManager.switchTenant(tenantInfo);
+        return tenantInfoService.menuChange(flag,null,companyMenus);
+
+    }
+
+    /**
+     * 租户菜单修改
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:tenant:edit')")
+    @PostMapping("/menu/edit")
+    public R menuEdit(@RequestBody MenuDto menuDto)
+    {
+        TenantInfo tenantInfo = tenantInfoMapper.selectTenantInfoById(menuDto.getId());
+        if (tenantInfo.getStatus() == 2) {
+            throw new CustomException("租户初始化中");
+        }
+
+        List<Long> selected = menuDto.getSelected();
+        List<Long> unSelected = menuDto.getUnSelected();
+        if ("sys".equals(menuDto.getFlag())) {
+            List<SysMenu> addSysMenu = getAddSysMenu(tenantInfo, menuDto.getSelected());
+            tenantDataSourceManager.switchTenant(tenantInfo);
+            return tenantInfoService.menuEdit(selected, unSelected, menuDto.getFlag(),addSysMenu,null);
+        }
+
+        List<TenantCompanyMenu> addCompanyMenu = getAddCompanyMenu(tenantInfo, menuDto.getSelected());
+        tenantDataSourceManager.switchTenant(tenantInfo);
+        return tenantInfoService.menuEdit(selected, unSelected, menuDto.getFlag(),null,addCompanyMenu);
+    }
+
+
+    /**
+     * 租户配置修改
+     */
+    @PreAuthorize("@ss.hasPermi('tenant:config:edit')")
+    @PostMapping("/config/edit")
+    public R configEdit(@Validated @RequestBody SysConfigDto config)
+    {
+        TenantInfo tenantInfo = tenantInfoMapper.selectTenantInfoById(config.getId());
+        if (tenantInfo.getStatus() == 2) {
+            throw new CustomException("租户初始化中");
+        }
+
+        tenantDataSourceManager.switchTenant(tenantInfo);
+        //修复只能更新的BUG
+        if (null != config.getConfigId()) {
+            return R.ok().put("data", configService.updateConfig(config));
+        } else {
+            return R.ok().put("data", configService.insertConfig(config));
+        }
+    }
+
+    /**
+     * 根据租户id获取指定配置文件
+     *
+     * @param configKey
+     * @param id
+     * @return
+     */
+    @GetMapping(value = "/getConfigByKey/{configKey}")
+    public AjaxResult getConfigByKey(@PathVariable String configKey,String id) {
+        TenantInfo tenantInfo = tenantInfoMapper.selectTenantInfoById(id);
+        if (tenantInfo.getStatus() == 2) {
+            throw new CustomException("租户初始化中");
+        }
+
+        tenantDataSourceManager.switchTenant(tenantInfo);
+        SysConfig config = configService.selectConfigByConfigKey(configKey);
+        return AjaxResult.success(config);
+    }
+
+    /**
+     * 获取需要更新的后台菜单
+     */
+    private List<SysMenu> getAddSysMenu(TenantInfo tenantInfo,List<Long> selected){
+        // 切换到租户库
+        tenantDataSourceManager.switchTenant(tenantInfo);
+        // 查询租户库里已经存在的menuId
+        List<Long> existIds = tenantInfoMapper.selectExistMenuIds();
+        // 不存在的menuId(就是要新增的)
+        List<Long> needAddIds = selected.stream()
+                .filter(id -> !existIds.contains(id))
+                .collect(Collectors.toList());
+        // 去总库查询详细的菜单详情
+        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+        if (!CollectionUtils.isEmpty(needAddIds)){
+            List<SysMenu> addMenuList = tenantInfoMapper.getTenSysMenuByIds(needAddIds);
+            return addMenuList;
+        }
+
+        return new ArrayList<>();
+    }
+
+    /**
+     * 获取需要更新的销售菜单
+     */
+    private List<TenantCompanyMenu> getAddCompanyMenu(TenantInfo tenantInfo, List<Long> selected){
+        // 切换到租户库
+        tenantDataSourceManager.switchTenant(tenantInfo);
+        // 查询租户库里已经存在的menuId
+        List<Long> existIds = tenantInfoMapper.selectExistComMenuIds();
+        // 不存在的menuId(就是要新增的)
+        List<Long> needAddIds = selected.stream()
+                .filter(id -> !existIds.contains(id))
+                .collect(Collectors.toList());
+        // 去总库查询详细的菜单详情
+        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+        if (!CollectionUtils.isEmpty(needAddIds)) {
+            List<TenantCompanyMenu> addMenuList = tenantInfoMapper.getTenComMenuByIds(needAddIds);
+            return addMenuList;
+        }
+
+        return new ArrayList<>();
+    }
+
+    /**
+     * 获取租户总后台菜单列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:list')")
+    @GetMapping("/tenantMenu/list")
+    public AjaxResult list(SysMenu menu)
+    {
+        List<SysMenu> menus = tenantInfoService.selectMenuList(menu, getUserId());
+        return AjaxResult.success(menus);
+    }
+
+    /**
+     * 获取租户销售菜单列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:list')")
+    @GetMapping("/tenantComMenu/list")
+    public AjaxResult list(TenantCompanyMenu menu)
+    {
+        List<TenantCompanyMenu> menus = tenantInfoService.selectCompanyMenuList(menu, getUserId());
+        return AjaxResult.success(menus);
+    }
+
+
+    /**
+     * 根据菜单编号获取详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:query')")
+    @GetMapping(value = "/tenantMenu/{menuId}")
+    public AjaxResult getInfo(@PathVariable Long menuId)
+    {
+        return AjaxResult.success(tenantInfoService.selectMenuById(menuId));
+    }
+
+    /**
+     * 根据菜单编号获取详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:query')")
+    @GetMapping(value = "/getTenantComMenu/{menuId}")
+    public AjaxResult getTenantComMenu(@PathVariable Long menuId)
+    {
+        return AjaxResult.success(tenantInfoService.getTenantComMenu(menuId));
+    }
+
+
+    /**
+     * 新增菜单
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:add')")
+    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
+    @PostMapping("/addTenantMenu")
+    public AjaxResult add(@Validated @RequestBody SysMenu menu)
+    {
+        if (UserConstants.NOT_UNIQUE.equals(tenantInfoService.checkMenuNameUnique(menu)))
+        {
+            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        }
+        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
+        {
+            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        }
+        menu.setCreateBy(getUsername());
+        return toAjax(tenantInfoService.insertMenu(menu));
+    }
+
+    @PreAuthorize("@ss.hasPermi('system:menu:add')")
+    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
+    @PostMapping("/addTenantComMenu")
+    public AjaxResult addTenantComMenu(@Validated @RequestBody TenantCompanyMenu menu)
+    {
+        if (UserConstants.NOT_UNIQUE.equals(tenantInfoService.checkComMenuNameUnique(menu)))
+        {
+            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        }
+        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
+        {
+            return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        }
+        menu.setCreateBy(getUsername());
+        return toAjax(tenantInfoService.insertComMenu(menu));
+    }
+
+    /**
+     * 修改菜单
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
+    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/updateTenantMenu")
+    public AjaxResult edit(@Validated @RequestBody SysMenu menu)
+    {
+        if (UserConstants.NOT_UNIQUE.equals(tenantInfoService.checkMenuNameUnique(menu)))
+        {
+            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        }
+        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
+        {
+            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        }
+        else if (menu.getMenuId().equals(menu.getParentId()))
+        {
+            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
+        }
+        menu.setUpdateBy(getUsername());
+        return toAjax(tenantInfoService.updateMenu(menu));
+    }
+
+    /**
+     * 修改菜单
+     */
+    @PreAuthorize("@ss.hasPermi('system:menu:edit')")
+    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/updateTenantComMenu")
+    public AjaxResult updateTenantComMenu(@Validated @RequestBody TenantCompanyMenu menu)
+    {
+        if (UserConstants.NOT_UNIQUE.equals(tenantInfoService.checkComMenuNameUnique(menu)))
+        {
+            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        }
+        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
+        {
+            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        }
+        else if (menu.getMenuId().equals(menu.getParentId()))
+        {
+            return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
+        }
+        menu.setUpdateBy(getUsername());
+        return toAjax(tenantInfoService.updateComMenu(menu));
+    }
+
+    @PreAuthorize("@ss.hasPermi('system:menu:remove')")
+    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/delTenantMenu/{menuId}")
+    public AjaxResult remove(@PathVariable("menuId") Long menuId)
+    {
+        if (tenantInfoService.hasChildByMenuId(menuId))
+        {
+            return AjaxResult.error("存在子菜单,不允许删除");
+        }
+        return toAjax(tenantInfoService.deleteMenuById(menuId));
+    }
+
+    @PreAuthorize("@ss.hasPermi('system:menu:remove')")
+    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/delTenantComMenu/{menuId}")
+    public AjaxResult delTenantComMenu(@PathVariable("menuId") Long menuId)
+    {
+        if (tenantInfoService.hasChildByComMenuId(menuId))
+        {
+            return AjaxResult.error("存在子菜单,不允许删除");
+        }
+        return toAjax(tenantInfoService.deleteComMenuById(menuId));
+    }
+}