feat(tenant): 初始化新租户的默认MinIO上传配置
- 在TenantServiceImpl中新增initDefaultUploadSetting方法 - 判断租户是否已有upload配置,避免重复写入 - 创建默认MinIO配置内容并插入数据库 - 预热redis上传配置缓存,提升首次读取性能 - 自动建桶并应用匿名只读策略,失败不阻断流程 - 在租户菜单授权成功后调用初始化方法 - SettingMapper新增countByKeyAndTenant和insertSetting方法,绕过多租户插件执行数据库操作
This commit is contained in:
@@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.gxwebsoft.common.system.entity.Setting;
|
||||
import com.gxwebsoft.common.system.param.SettingParam;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -37,4 +39,20 @@ public interface SettingMapper extends BaseMapper<Setting> {
|
||||
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
Setting getBySettingKeyIgnore(@Param("param") SettingParam param);
|
||||
|
||||
/**
|
||||
* 统计指定租户下某 setting_key 的记录数(绕过多租户插件,自行按 tenant_id 过滤)。
|
||||
* 用于初始化时幂等判断,避免被上下文租户覆盖。
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
@Select("SELECT COUNT(1) FROM sys_setting WHERE setting_key = #{settingKey} AND tenant_id = #{tenantId} AND deleted = 0")
|
||||
int countByKeyAndTenant(@Param("settingKey") String settingKey, @Param("tenantId") Integer tenantId);
|
||||
|
||||
/**
|
||||
* 显式插入系统设置(绕过多租户插件,tenant_id 由实体携带,确保写入目标租户)。
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
@Insert("INSERT INTO sys_setting (setting_key, content, sort_number, comments, tenant_id, create_time, update_time, deleted) "
|
||||
+ "VALUES (#{settingKey}, #{content}, #{sortNumber}, #{comments}, #{tenantId}, #{createTime}, #{updateTime}, 0)")
|
||||
int insertSetting(Setting setting);
|
||||
}
|
||||
|
||||
@@ -7,11 +7,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.common.core.Constants;
|
||||
import com.gxwebsoft.common.core.utils.CommonUtil;
|
||||
import com.gxwebsoft.common.core.utils.DomainUtil;
|
||||
import com.gxwebsoft.common.core.utils.MinioUtil;
|
||||
import com.gxwebsoft.common.core.utils.RedisUtil;
|
||||
import com.gxwebsoft.common.system.entity.*;
|
||||
import com.gxwebsoft.common.system.mapper.MenuMapper;
|
||||
import com.gxwebsoft.common.system.mapper.RoleMapper;
|
||||
import com.gxwebsoft.common.system.mapper.RoleMenuMapper;
|
||||
import com.gxwebsoft.common.system.mapper.SettingMapper;
|
||||
import com.gxwebsoft.common.system.mapper.UserRoleMapper;
|
||||
import com.gxwebsoft.common.system.mapper.TenantMapper;
|
||||
import com.gxwebsoft.common.system.param.MenuParam;
|
||||
@@ -21,6 +23,7 @@ import com.gxwebsoft.common.system.param.TenantParam;
|
||||
import com.gxwebsoft.common.core.web.ApiResult;
|
||||
import com.gxwebsoft.common.core.web.PageParam;
|
||||
import com.gxwebsoft.common.core.web.PageResult;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -28,6 +31,7 @@ import org.springframework.util.CollectionUtils;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -73,6 +77,8 @@ import java.util.stream.Collectors;
|
||||
private UserService userService;
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
@Resource
|
||||
private SettingMapper settingMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<Tenant> pageRel(TenantParam param) {
|
||||
@@ -616,6 +622,12 @@ import java.util.stream.Collectors;
|
||||
// 添加菜单ID到超级管理员所属角色ID
|
||||
if (resultMenu) {
|
||||
saveRedis(company);
|
||||
// 初始化默认 MinIO 云存储配置(oss-{tenantId} 桶 + 自动建桶/策略),失败不阻断开通
|
||||
try {
|
||||
initDefaultUploadSetting(company.getTid());
|
||||
} catch (Exception e) {
|
||||
System.out.println("[Tenant] 初始化默认上传配置失败(不影响开通): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -667,6 +679,52 @@ import java.util.stream.Collectors;
|
||||
redisUtil.set(key, tenant);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为新开通的租户写入默认 MinIO 上传配置,并自动建桶 + 匿名只读策略。
|
||||
* 幂等:若已存在 upload 配置则跳过。
|
||||
*/
|
||||
private void initDefaultUploadSetting(Integer tenantId) {
|
||||
// 绕过多租户插件,按目标租户精确计数,避免被上下文租户覆盖
|
||||
int exists = settingMapper.countByKeyAndTenant("upload", tenantId);
|
||||
if (exists > 0) {
|
||||
return;
|
||||
}
|
||||
final String bucketName = "oss-" + tenantId;
|
||||
final String endpoint = "https://minio.sitelnk.cn";
|
||||
final String accessKeyId = "ZB1RK0ARI4XPF0CWA2FF";
|
||||
final String accessKeySecret = "QPnFBGLmXxto1lBEiaTyXgf4E4H46e8TOR4sYyiY";
|
||||
|
||||
JSONObject content = new JSONObject();
|
||||
content.put("settingKey", "upload");
|
||||
content.put("uploadMethod", "minio");
|
||||
content.put("bucketName", bucketName);
|
||||
content.put("bucketEndpoint", endpoint);
|
||||
content.put("accessKeyId", accessKeyId);
|
||||
content.put("accessKeySecret", accessKeySecret);
|
||||
content.put("bucketDomain", endpoint + "/" + bucketName);
|
||||
|
||||
Setting setting = new Setting();
|
||||
setting.setSettingKey("upload");
|
||||
setting.setContent(content.toJSONString());
|
||||
setting.setSortNumber(0);
|
||||
setting.setComments("默认MinIO存储");
|
||||
setting.setTenantId(tenantId);
|
||||
setting.setDeleted(0);
|
||||
setting.setCreateTime(new Date());
|
||||
setting.setUpdateTime(new Date());
|
||||
settingMapper.insertSetting(setting);
|
||||
|
||||
// 预热上传配置缓存,避免新租户首次读取命中空缓存
|
||||
redisUtil.set("Upload:" + tenantId, content);
|
||||
|
||||
// 自动建桶 + 匿名只读策略(失败不阻断开通)
|
||||
try {
|
||||
MinioUtil.ensureBucketReady(MinioUtil.buildClient(endpoint, accessKeyId, accessKeySecret), endpoint, bucketName);
|
||||
} catch (Exception e) {
|
||||
System.out.println("[Tenant] 初始化时自动建桶失败(忽略): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean destructionAll(Integer tenantId){
|
||||
if (baseMapper.destructionAll(tenantId)) {
|
||||
|
||||
Reference in New Issue
Block a user