diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java new file mode 100644 index 0000000..60146c7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/system/SysTenantController.java @@ -0,0 +1,192 @@ +package com.ruoyi.system.controller.system; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaCheckRole; +import com.baomidou.lock.annotation.Lock4j; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import com.ruoyi.common.core.constant.TenantConstants; +import com.ruoyi.common.core.core.domain.R; +import com.ruoyi.common.encrypt.annotation.ApiEncrypt; +import com.ruoyi.common.excel.utils.ExcelUtil; +import com.ruoyi.common.web.annotation.RepeatSubmit; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.orm.core.page.TableDataInfo; +import com.ruoyi.common.tenant.helper.TenantHelper; +import com.ruoyi.common.web.core.BaseController; +import com.ruoyi.system.domain.bo.SysTenantBo; +import com.ruoyi.system.domain.vo.SysTenantVo; +import com.ruoyi.system.service.ISysTenantService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 租户管理 + * + * @author Michelle.Chung + * author 数据小王子 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/system/tenant") +public class SysTenantController extends BaseController { + + @Resource + private ISysTenantService tenantService; + + /** + * 分页查询租户列表 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:list") + @GetMapping("/list") + public TableDataInfo list(SysTenantBo sysTenantBo) { + return tenantService.selectPage(sysTenantBo); + } + + /** + * 导出租户列表 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:export") + @Log(title = "租户", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(SysTenantBo sysTenantBo, HttpServletResponse response) { + List list = tenantService.selectList(sysTenantBo); + ExcelUtil.exportExcel(list, "租户", SysTenantVo.class, response); + } + + /** + * 获取租户详细信息 + * + * @param tenantId 主键 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:query") + @GetMapping("/{tenantId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long tenantId) { + return R.ok(tenantService.selectById(tenantId)); + } + + /** + * 新增租户 + */ + @ApiEncrypt + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:add") + @Log(title = "租户", businessType = BusinessType.INSERT) + @Lock4j + @RepeatSubmit() + @PostMapping() + public R add(@Validated @RequestBody SysTenantBo sysTenantBo) { + if (!tenantService.checkCompanyNameUnique(sysTenantBo)) { + return R.fail("新增租户'" + sysTenantBo.getCompanyName() + "'失败,企业名称已存在"); + } + boolean inserted = tenantService.insert(sysTenantBo); + if (!inserted) { + return R.fail("新增租户记录失败!"); + } + return R.ok(); + } + + /** + * 修改租户 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:edit") + @Log(title = "租户", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated @RequestBody SysTenantBo sysTenantBo) { + tenantService.checkTenantAllowed(sysTenantBo.getTenantId()); + boolean updated = tenantService.update(sysTenantBo); + if (!updated) { + R.fail("修改租户记录失败!"); + } + return R.ok(); + } + + /** + * 状态修改 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:edit") + @Log(title = "租户", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public R changeStatus(@RequestBody SysTenantBo sysTenantBo) { + tenantService.checkTenantAllowed(sysTenantBo.getTenantId()); + boolean updated = tenantService.updateTenantStatus(sysTenantBo); + if (!updated) { + R.fail("修改租户状态失败!"); + } + return R.ok(); + } + + /** + * 删除租户 + * + * @param tenantIds 主键串 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:remove") + @Log(title = "租户", businessType = BusinessType.DELETE) + @DeleteMapping("/{tenantIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] tenantIds) { + boolean deleted = tenantService.deleteByIds(List.of(tenantIds), true); + if (!deleted) { + R.fail("删除租户记录失败!"); + } + return R.ok(); + } + + /** + * 动态切换租户 + * + * @param tenantId 租户ID + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @GetMapping("/dynamic/{tenantId}") + public R dynamicTenant(@NotNull(message = "租户ID不能为空") @PathVariable Long tenantId) { + TenantHelper.setDynamic(tenantId); + return R.ok(); + } + + /** + * 清除动态租户 + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @GetMapping("/dynamic/clear") + public R dynamicClear() { + TenantHelper.clearDynamic(); + return R.ok(); + } + + + /** + * 同步租户套餐 + * + * @param tenantId 租户id + * @param packageId 套餐id + */ + @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY) + @SaCheckPermission("system:tenant:edit") + @Log(title = "租户", businessType = BusinessType.UPDATE) + @GetMapping("/syncTenantPackage") + public R syncTenantPackage(@NotNull(message = "租户ID不能为空") Long tenantId, + @NotNull(message = "套餐ID不能为空") Long packageId) { + boolean synced = tenantService.syncTenantPackage(tenantId, packageId); + if (!synced) { + R.fail("同步租户套餐失败!"); + } + return R.ok(); + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java new file mode 100644 index 0000000..9dfe07c --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTenant.java @@ -0,0 +1,117 @@ +package com.ruoyi.system.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import lombok.Data; +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 租户对象 sys_tenant + * + * @author Michelle.Chung + * author 数据小王子 + */ +@Data +@Table("sys_tenant") +public class SysTenant implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 租户编号 + */ + @Id + private Long tenantId; + + /** + * 联系人 + */ + private String contactUserName; + + /** + * 联系电话 + */ + private String contactPhone; + + /** + * 企业名称 + */ + private String companyName; + + /** + * 统一社会信用代码 + */ + private String licenseNumber; + + /** + * 地址 + */ + private String address; + + /** + * 域名 + */ + private String domain; + + /** + * 企业简介 + */ + private String intro; + + /** + * 备注 + */ + private String remark; + + /** + * 租户套餐编号 + */ + private Long packageId; + + /** + * 过期时间 + */ + private Date expireTime; + + /** + * 用户数量(-1不限制) + */ + private Long accountCount; + + /** + * 租户状态(0正常 1停用) + */ + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + private Integer delFlag; + + /** + * 创建者 + */ + private Long createBy; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新者 + */ + private Long updateBy; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java new file mode 100644 index 0000000..85df7f6 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysTenantBo.java @@ -0,0 +1,98 @@ +package com.ruoyi.system.domain.bo; + +import com.ruoyi.system.domain.SysTenant; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import jakarta.validation.constraints.*; +import java.io.Serializable; +import java.util.Date; + +/** + * 租户业务对象 sys_tenant + * + * @author Michelle.Chung + */ + +@Data +@AutoMapper(target = SysTenant.class, reverseConvertGenerate = false) +public class SysTenantBo implements Serializable { + + /** + * 租户编号 + */ + private Long tenantId; + + /** + * 联系人 + */ + @NotBlank(message = "联系人不能为空") + private String contactUserName; + + /** + * 联系电话 + */ + @NotBlank(message = "联系电话不能为空") + private String contactPhone; + + /** + * 企业名称 + */ + @NotBlank(message = "企业名称不能为空") + private String companyName; + + /** + * 用户名(创建系统用户) + */ + private String username; + + /** + * 密码(创建系统用户) + */ + private String password; + + /** + * 统一社会信用代码 + */ + private String licenseNumber; + + /** + * 地址 + */ + private String address; + + /** + * 域名 + */ + private String domain; + + /** + * 企业简介 + */ + private String intro; + + /** + * 备注 + */ + private String remark; + + /** + * 租户套餐编号 + */ + @NotNull(message = "租户套餐不能为空") + private Long packageId; + + /** + * 过期时间 + */ + private Date expireTime; + + /** + * 用户数量(-1不限制) + */ + private Long accountCount; + + /** + * 租户状态(0正常 1停用) + */ + private String status; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java new file mode 100644 index 0000000..49ab262 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysTenantVo.java @@ -0,0 +1,108 @@ +package com.ruoyi.system.domain.vo; + +import java.util.Date; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.ruoyi.common.excel.annotation.ExcelDictFormat; +import com.ruoyi.common.excel.convert.ExcelDictConvert; +import com.ruoyi.system.domain.SysTenant; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 租户视图对象 sys_tenant + * + * @author Michelle.Chung + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = SysTenant.class) +public class SysTenantVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 租户编号 + */ + @ExcelProperty(value = "租户编号") + private Long tenantId; + + /** + * 联系人 + */ + @ExcelProperty(value = "联系人") + private String contactUserName; + + /** + * 联系电话 + */ + @ExcelProperty(value = "联系电话") + private String contactPhone; + + /** + * 企业名称 + */ + @ExcelProperty(value = "企业名称") + private String companyName; + + /** + * 统一社会信用代码 + */ + @ExcelProperty(value = "统一社会信用代码") + private String licenseNumber; + + /** + * 地址 + */ + @ExcelProperty(value = "地址") + private String address; + + /** + * 域名 + */ + @ExcelProperty(value = "域名") + private String domain; + + /** + * 企业简介 + */ + @ExcelProperty(value = "企业简介") + private String intro; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 租户套餐编号 + */ + @ExcelProperty(value = "租户套餐编号") + private Long packageId; + + /** + * 过期时间 + */ + @ExcelProperty(value = "过期时间") + private Date expireTime; + + /** + * 用户数量(-1不限制) + */ + @ExcelProperty(value = "用户数量") + private Long accountCount; + + /** + * 租户状态(0正常 1停用) + */ + @ExcelProperty(value = "租户状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=正常,1=停用") + private String status; + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java new file mode 100644 index 0000000..690c166 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTenantMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.system.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.ruoyi.system.domain.SysTenant; +import org.apache.ibatis.annotations.Mapper; + +/** + * 租户Mapper接口 + * + * @author 数据小王子 + */ +@Mapper +public interface SysTenantMapper extends BaseMapper { + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java new file mode 100644 index 0000000..54f2458 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTenantService.java @@ -0,0 +1,87 @@ +package com.ruoyi.system.service; + +import com.ruoyi.common.orm.core.service.IBaseService; +import com.ruoyi.system.domain.SysTenant; +import com.ruoyi.system.domain.vo.SysTenantVo; +import com.ruoyi.system.domain.bo.SysTenantBo; +import com.ruoyi.common.orm.core.page.TableDataInfo; + +import java.util.Collection; +import java.util.List; + +/** + * 租户Service接口 + * + * @author Michelle.Chung + * author 数据小王子 + */ +public interface ISysTenantService extends IBaseService { + + /** + * 基于租户ID查询租户 + */ + SysTenantVo selectById(Long tenantId); + +// /** +// * 基于租户ID查询租户 +// */ +// SysTenantVo queryByTenantId(String tenantId); + + /** + * 分页查询租户列表 + * + * @param sysTenantBo 租户Bo + * @return 租户列表集合 + */ + TableDataInfo selectPage(SysTenantBo sysTenantBo); + + /** + * 查询租户列表 + */ + List selectList(SysTenantBo sysTenantBo); + + /** + * 新增租户 + */ + boolean insert(SysTenantBo sysTenantBo); + + /** + * 修改租户 + */ + boolean update(SysTenantBo sysTenantBo); + + /** + * 修改租户状态 + */ + boolean updateTenantStatus(SysTenantBo sysTenantBo); + + /** + * 校验租户是否允许操作 + */ + void checkTenantAllowed(Long tenantId); + + /** + * 校验并批量删除租户信息 + */ + boolean deleteByIds(Collection ids, Boolean isValid); + + /** + * 校验企业名称是否唯一 + */ + boolean checkCompanyNameUnique(SysTenantBo bo); + + /** + * 校验账号余额 + */ + boolean checkAccountBalance(Long tenantId); + + /** + * 校验有效期 + */ + boolean checkExpireTime(Long tenantId); + + /** + * 同步租户套餐 + */ + boolean syncTenantPackage(Long tenantId, Long packageId); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml new file mode 100644 index 0000000..f3fa4cb --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysTenantMapper.xml @@ -0,0 +1,7 @@ + + + + +