This commit is contained in:
2023-06-08 17:56:44 +08:00
parent bc6d760c4f
commit ccf453b198
38 changed files with 524 additions and 101 deletions

View File

@ -0,0 +1,19 @@
package com.qiaoba.common.base;
/**
* 数据源接口
*
* @author ailanyin
* @version 1.0
* @since 2023/6/8 17:23
*/
public interface DatasourceService {
/**
* 检查租户是否允许访问
*
* @param tenantId tenantId
* @return true = 允许
*/
boolean checkTenantInfo(String tenantId);
}

View File

@ -18,4 +18,9 @@ public class TenantConstant {
* header 租户 key * header 租户 key
*/ */
public static final String HEADER_KEY_TENANT = "tenant"; public static final String HEADER_KEY_TENANT = "tenant";
/**
* 系统默认租户ID
*/
public static final String DEFAULT_TENANT_ID = "1";
} }

View File

@ -58,6 +58,16 @@ public class DynamicDataSourceConfig {
dataSource.freshDataSource(DATA_SOURCE_MAP); dataSource.freshDataSource(DATA_SOURCE_MAP);
} }
public void addTenantDataSource(String tenantId, String driver, String url, String username, String password, PoolInfo poolInfo) {
addDataSourceToMap(DynamicDatasourceConstant.MASTER_PREFIX + tenantId, buildDataSource(driver, url, username, password, poolInfo));
dataSource.freshDataSource(DATA_SOURCE_MAP);
}
public void deleteTenantDataSource(String tenantId) {
DATA_SOURCE_MAP.remove(DynamicDatasourceConstant.MASTER_PREFIX + tenantId);
dataSource.freshDataSource(DATA_SOURCE_MAP);
}
private static Object buildDataSource(String driver, String url, String username, String password, PoolInfo poolInfo) { private static Object buildDataSource(String driver, String url, String username, String password, PoolInfo poolInfo) {
boolean flag = JdbcUtil.checkConnect(driver, url, username, password); boolean flag = JdbcUtil.checkConnect(driver, url, username, password);
if (!flag) { if (!flag) {

View File

@ -1,9 +1,9 @@
package com.qiaoba.common.database.filters; package com.qiaoba.common.database.filters;
import com.qiaoba.common.base.constants.BaseConstant; import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.DatasourceService;
import com.qiaoba.common.base.constants.TenantConstant; import com.qiaoba.common.base.constants.TenantConstant;
import com.qiaoba.common.base.context.BaseContext; import com.qiaoba.common.base.context.BaseContext;
import com.qiaoba.common.database.config.DynamicDataSourceContext;
import com.qiaoba.common.database.constants.DynamicDatasourceConstant; import com.qiaoba.common.database.constants.DynamicDatasourceConstant;
import com.qiaoba.common.web.utils.ResponseUtil; import com.qiaoba.common.web.utils.ResponseUtil;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
@ -13,7 +13,6 @@ import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@ -30,26 +29,33 @@ import java.io.IOException;
public class DynamicDataSourceFilter extends OncePerRequestFilter { public class DynamicDataSourceFilter extends OncePerRequestFilter {
@Resource @Resource
private DynamicDataSourceContext dynamicDataSourceContext; private DatasourceService datasourceService;
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
before(request); String tenantId = request.getHeader(TenantConstant.HEADER_KEY_TENANT);
// 主库或没有tenantId
if (StrUtil.isBlank(tenantId)
|| TenantConstant.DEFAULT_TENANT_ID.equals(tenantId)
|| request.getRequestURI().startsWith("/tenant")) {
setDefaultSetting();
filterChain.doFilter(request, response);
return;
}
if (!checkTenantInfo(tenantId)) {
// 检查租户的信息,是否存在,是否过期,是否禁用
ResponseUtil.response(response, "租户可能到期或被禁用");
return;
}
before(tenantId);
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
after(); after();
} }
private boolean checkTenantInfo(String tenantCode, ServletResponse servletResponse) throws IOException { private void before(String tenantId) {
// 检查租户的信息,是否存在,是否过期,是否禁用
ResponseUtil.response((HttpServletResponse) servletResponse, "租户: " + tenantCode + "已到期");
return false;
}
private void before(HttpServletRequest request) {
String tenantId = request.getHeader(TenantConstant.HEADER_KEY_TENANT);
// todo
//设置当前租户对应的数据源 //设置当前租户对应的数据源
BaseContext.setDataSource(DynamicDatasourceConstant.DEFAULT_MASTER_DATASOURCE_KEY); BaseContext.setDataSource(DynamicDatasourceConstant.MASTER_PREFIX + tenantId);
//设置当前租户对应的租户ID //设置当前租户对应的租户ID
BaseContext.setTenantId(tenantId); BaseContext.setTenantId(tenantId);
//设置当前租户对应的数据库类型 //设置当前租户对应的数据库类型
@ -59,4 +65,16 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
private void after() { private void after() {
BaseContext.clearAllHolder(); BaseContext.clearAllHolder();
} }
private boolean checkTenantInfo(String tenantId) {
return datasourceService.checkTenantInfo(tenantId);
}
private void setDefaultSetting() {
BaseContext.setDataSource(DynamicDatasourceConstant.DEFAULT_MASTER_DATASOURCE_KEY);
//设置当前租户对应的租户ID
BaseContext.setTenantId(TenantConstant.DEFAULT_TENANT_ID);
//设置当前租户对应的数据库类型
BaseContext.setDatabaseType("MySQL");
}
} }

View File

@ -1,6 +1,8 @@
package com.qiaoba.common.database.properties; package com.qiaoba.common.database.properties;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* 数据源连接池信息 * 数据源连接池信息
@ -10,6 +12,8 @@ import lombok.Data;
* @since 2023-04-23 15:37:43 * @since 2023-04-23 15:37:43
*/ */
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
public class PoolInfo { public class PoolInfo {
/** /**

View File

@ -2,7 +2,6 @@ package com.qiaoba.common.database.utils;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.exceptions.ServiceException; import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.common.web.advice.ExceptionAdvice;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;

View File

@ -9,7 +9,6 @@ import com.qiaoba.common.database.entity.TableDataInfo;
import com.qiaoba.module.tenant.entity.SysTenant; import com.qiaoba.module.tenant.entity.SysTenant;
import com.qiaoba.module.tenant.entity.dto.TenantSettingDto; import com.qiaoba.module.tenant.entity.dto.TenantSettingDto;
import com.qiaoba.module.tenant.entity.param.SysTenantParam; import com.qiaoba.module.tenant.entity.param.SysTenantParam;
import com.qiaoba.module.tenant.handle.MysqlHandler;
import com.qiaoba.module.tenant.service.SysTenantService; import com.qiaoba.module.tenant.service.SysTenantService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@ -19,8 +18,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.nio.charset.Charset;
/** /**
* 租户管理 Web层 * 租户管理 Web层
@ -36,7 +33,6 @@ import java.nio.charset.Charset;
public class SysTenantController { public class SysTenantController {
private final SysTenantService sysTenantService; private final SysTenantService sysTenantService;
private final MysqlHandler mysqlHandler;
@PreAuthorize("hasAuthority('tenant:add')") @PreAuthorize("hasAuthority('tenant:add')")
@PostMapping @PostMapping
@ -86,24 +82,15 @@ public class SysTenantController {
return AjaxResult.success(sysTenantService.update(BeanUtil.copyProperties(dto, SysTenant.class))); return AjaxResult.success(sysTenantService.update(BeanUtil.copyProperties(dto, SysTenant.class)));
} }
@PreAuthorize("hasAuthority('tenant:init')")
@PostMapping("/init")
@Operation(summary = "初始化")
public void initData(String tenantId) throws Exception {
sysTenantService.initData(tenantId);
}
@GetMapping("/test") @GetMapping("/test")
public void test(HttpServletResponse response) throws Exception { public void test(HttpServletResponse response) throws Exception {
response.setCharacterEncoding("UTF-8"); sysTenantService.initData("2");
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
int i = 0;
while (i < 101) {
String text = null;
if (i == 100) {
text = "<div style=\"color:#00FF00\"><h3>恭喜!升级完成</h3></div>";
} else {
text = "<div style=\"color:#FF0000\"><h3>升级进度:[" + i + "]</h3></div>";
}
writer.write(text);
writer.flush();
i = i + 10;
Thread.sleep(1000);
}
writer.close();
} }
} }

View File

@ -0,0 +1,23 @@
package com.qiaoba.module.tenant.handler;
import java.sql.Connection;
/**
* 数据处理器
*
* @author ailanyin
* @version 1.0
* @since 2023/6/8 15:27
*/
public interface DataHandler {
/**
* 处理
*
* @param conn conn
* @param needCreateTables 是否需要建表
* @param tenantId tenantId
* @return 结果
*/
boolean handle(Connection conn, String tenantId, Boolean needCreateTables);
}

View File

@ -0,0 +1,46 @@
package com.qiaoba.module.tenant.handler;
import com.qiaoba.common.base.enums.DataBaseEnum;
import com.qiaoba.common.base.exceptions.ServiceException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 处理器工厂-根据不同类型的数据库-选择不同的处理器
*
* @author ailanyin
* @version 1.0
* @since 2023/6/8 15:34
*/
@Component
@RequiredArgsConstructor
public class DataHandlerFactory {
private static Map<String, DataHandler> handlerMap = new ConcurrentHashMap<>();
private final MysqlDataHandler mysqlDataHandler;
private final OracleDataHandler oracleDataHandler;
private final PostgreSqlHandler postgreSqlHandler;
private final SqlServerHandler sqlServerHandler;
@PostConstruct
public void register() {
handlerMap.put(DataBaseEnum.MY_SQL.getType(), mysqlDataHandler);
handlerMap.put(DataBaseEnum.ORACLE.getType(), oracleDataHandler);
handlerMap.put(DataBaseEnum.POSTGRE_SQL.getType(), postgreSqlHandler);
handlerMap.put(DataBaseEnum.SQL_SERVER.getType(), sqlServerHandler);
}
public static DataHandler getHandler(String name) {
DataHandler dataHandler = handlerMap.get(name);
if (Objects.isNull(dataHandler)) {
throw new ServiceException("数据库处理器工厂异常, 类型:[" + name + "]找不到相对应的解析器");
}
return dataHandler;
}
}

View File

@ -1,19 +1,22 @@
package com.qiaoba.module.tenant.handle; package com.qiaoba.module.tenant.handler;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Snowflake; import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.db.DbUtil; import cn.hutool.db.DbUtil;
import cn.hutool.db.sql.SqlExecutor; import cn.hutool.db.sql.SqlExecutor;
import com.qiaoba.module.tenant.service.SysTenantService;
import com.qiaoba.module.tenant.utils.MenuUtil; import com.qiaoba.module.tenant.utils.MenuUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileReader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException;
import java.util.List; import java.util.List;
/** /**
@ -26,9 +29,7 @@ import java.util.List;
@Component @Component
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class MysqlHandler { public class MysqlDataHandler implements DataHandler {
private final SysTenantService sysTenantService;
/** /**
* 角色-超管ID * 角色-超管ID
@ -40,13 +41,14 @@ public class MysqlHandler {
*/ */
private static final ThreadLocal<Long> USER_SUPER_ADMIN_ID = new ThreadLocal<>(); private static final ThreadLocal<Long> USER_SUPER_ADMIN_ID = new ThreadLocal<>();
@Override
public boolean handle(Connection conn, String tenantId, Boolean needCreateTables) {
public void handle(String tenantId) {
log.info("Mysql-Column-Start");
Connection conn = sysTenantService.getConnection(tenantId);
try { try {
// 手动提交
conn.setAutoCommit(false);
// 创建表
initTables(conn);
// 处理 sys_config // 处理 sys_config
handleSysConfig(conn, tenantId); handleSysConfig(conn, tenantId);
// 处理 sys_post // 处理 sys_post
@ -61,20 +63,35 @@ public class MysqlHandler {
MenuUtil.handleMenu(conn, tenantId); MenuUtil.handleMenu(conn, tenantId);
// 处理 sys_role_menu // 处理 sys_role_menu
bindRoleAndMenu(conn, tenantId); bindRoleAndMenu(conn, tenantId);
conn.commit();
return true;
} catch (Exception e) { } catch (Exception e) {
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
DbUtil.close(conn); DbUtil.close(conn);
ROLE_SUPER_ADMIN_ID.remove(); ROLE_SUPER_ADMIN_ID.remove();
USER_SUPER_ADMIN_ID.remove(); USER_SUPER_ADMIN_ID.remove();
} }
log.info("Mysql-Column-End"); return false;
} }
private void initTables(Connection conn) throws Exception {
ClassPathResource resource = new ClassPathResource("MySQL/table/base_tables");
File file = resource.getFile();
FileReader reader = new FileReader(file);
ScriptRunner scriptRunner = new ScriptRunner(conn);
scriptRunner.setSendFullScript(true);
scriptRunner.runScript(reader);
reader.close();
}
private void handleSysConfig(Connection conn, String tenantId) throws Exception { private void handleSysConfig(Connection conn, String tenantId) throws Exception {
handleSql(conn, tenantId, "data/sys_config_data"); handleSql(conn, tenantId, "MySQL/data/sys_config_data");
} }
private void handleSql(Connection conn, String tenantId, String fileName) throws Exception { private void handleSql(Connection conn, String tenantId, String fileName) throws Exception {
@ -94,11 +111,11 @@ public class MysqlHandler {
} }
private void handleSysPost(Connection conn, String tenantId) throws Exception { private void handleSysPost(Connection conn, String tenantId) throws Exception {
handleSql(conn, tenantId, "data/sys_post_data"); handleSql(conn, tenantId, "MySQL/data/sys_post_data");
} }
private void handleSysRole(Connection conn, String tenantId) throws Exception { private void handleSysRole(Connection conn, String tenantId) throws Exception {
handleUserOrRole(conn, tenantId, "data/sys_role_data", true); handleUserOrRole(conn, tenantId, "MySQL/data/sys_role_data", true);
} }
private void handleUserOrRole(Connection conn, String tenantId, String fileName, Boolean isRole) throws Exception { private void handleUserOrRole(Connection conn, String tenantId, String fileName, Boolean isRole) throws Exception {
@ -131,7 +148,7 @@ public class MysqlHandler {
} }
private void handleSysUser(Connection conn, String tenantId) throws Exception { private void handleSysUser(Connection conn, String tenantId) throws Exception {
handleUserOrRole(conn, tenantId, "data/sys_user_data", false); handleUserOrRole(conn, tenantId, "MySQL/data/sys_user_data", false);
} }
private void bindUserAndRole(Connection conn, String tenantId) throws Exception { private void bindUserAndRole(Connection conn, String tenantId) throws Exception {

View File

@ -0,0 +1,25 @@
package com.qiaoba.module.tenant.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.sql.Connection;
/**
* OracleDataHandler
*
* @author ailanyin
* @version 1.0
* @since 2023/6/5 16:28
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class OracleDataHandler implements DataHandler {
@Override
public boolean handle(Connection conn, String tenantId, Boolean needCreateTables) {
return false;
}
}

View File

@ -0,0 +1,25 @@
package com.qiaoba.module.tenant.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.sql.Connection;
/**
* PostgreSqlHandler
*
* @author ailanyin
* @version 1.0
* @since 2023/6/5 16:28
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class PostgreSqlHandler implements DataHandler {
@Override
public boolean handle(Connection conn, String tenantId, Boolean needCreateTables) {
return false;
}
}

View File

@ -0,0 +1,25 @@
package com.qiaoba.module.tenant.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.sql.Connection;
/**
* SqlServerHandler
*
* @author ailanyin
* @version 1.0
* @since 2023/6/5 16:28
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class SqlServerHandler implements DataHandler {
@Override
public boolean handle(Connection conn, String tenantId, Boolean needCreateTables) {
return false;
}
}

View File

@ -3,8 +3,8 @@ package com.qiaoba.module.tenant.service;
import com.qiaoba.common.database.entity.PageQuery; import com.qiaoba.common.database.entity.PageQuery;
import com.qiaoba.common.database.entity.TableDataInfo; import com.qiaoba.common.database.entity.TableDataInfo;
import com.qiaoba.module.tenant.entity.SysTenant; import com.qiaoba.module.tenant.entity.SysTenant;
import com.qiaoba.module.tenant.entity.vo.TenantSettingVo;
import com.qiaoba.module.tenant.entity.param.SysTenantParam; import com.qiaoba.module.tenant.entity.param.SysTenantParam;
import com.qiaoba.module.tenant.entity.vo.TenantSettingVo;
import java.sql.Connection; import java.sql.Connection;
@ -50,14 +50,6 @@ public interface SysTenantService {
*/ */
SysTenant selectById(String tenantId); SysTenant selectById(String tenantId);
/**
* 获取租户数据库连接
*
* @param tenantId tenantId
* @return Connection
*/
Connection getConnection(String tenantId);
/** /**
* 获取设置信息 * 获取设置信息
* *
@ -65,4 +57,12 @@ public interface SysTenantService {
* @return setting * @return setting
*/ */
TenantSettingVo getSetting(String tenantId); TenantSettingVo getSetting(String tenantId);
/**
* 初始化数据
*
* @param tenantId tenantId
* @throws Exception Exception
*/
void initData(String tenantId) throws Exception;
} }

View File

@ -3,16 +3,20 @@ package com.qiaoba.module.tenant.service.impl;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qiaoba.auth.utils.SecurityUtil; import com.qiaoba.auth.utils.SecurityUtil;
import com.qiaoba.common.base.DatasourceService;
import com.qiaoba.common.base.enums.BaseEnum; import com.qiaoba.common.base.enums.BaseEnum;
import com.qiaoba.common.base.enums.DataBaseEnum; import com.qiaoba.common.base.enums.DataBaseEnum;
import com.qiaoba.common.base.exceptions.ServiceException; import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
import com.qiaoba.common.database.entity.PageQuery; import com.qiaoba.common.database.entity.PageQuery;
import com.qiaoba.common.database.entity.TableDataInfo; import com.qiaoba.common.database.entity.TableDataInfo;
import com.qiaoba.common.database.properties.PoolInfo;
import com.qiaoba.common.database.utils.JdbcUtil; import com.qiaoba.common.database.utils.JdbcUtil;
import com.qiaoba.module.tenant.entity.SysTenant; import com.qiaoba.module.tenant.entity.SysTenant;
import com.qiaoba.module.tenant.entity.SysTenantDatasource; import com.qiaoba.module.tenant.entity.SysTenantDatasource;
import com.qiaoba.module.tenant.entity.vo.TenantSettingVo;
import com.qiaoba.module.tenant.entity.param.SysTenantParam; import com.qiaoba.module.tenant.entity.param.SysTenantParam;
import com.qiaoba.module.tenant.entity.vo.TenantSettingVo;
import com.qiaoba.module.tenant.handler.DataHandlerFactory;
import com.qiaoba.module.tenant.mapper.SysTenantMapper; import com.qiaoba.module.tenant.mapper.SysTenantMapper;
import com.qiaoba.module.tenant.service.SysTenantDatasourceService; import com.qiaoba.module.tenant.service.SysTenantDatasourceService;
import com.qiaoba.module.tenant.service.SysTenantService; import com.qiaoba.module.tenant.service.SysTenantService;
@ -34,7 +38,7 @@ import java.util.Objects;
*/ */
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class SysTenantServiceImpl implements SysTenantService { public class SysTenantServiceImpl implements SysTenantService, DatasourceService {
@Value("${qiaoba.datasource.master.driver}") @Value("${qiaoba.datasource.master.driver}")
private String driver; private String driver;
@ -49,6 +53,7 @@ public class SysTenantServiceImpl implements SysTenantService {
private final SysTenantMapper sysTenantMapper; private final SysTenantMapper sysTenantMapper;
private final SysTenantDatasourceService sysTenantDatasourceService; private final SysTenantDatasourceService sysTenantDatasourceService;
private final DynamicDataSourceConfig dynamicDataSourceConfig;
@Override @Override
public int insert(SysTenant sysTenant) { public int insert(SysTenant sysTenant) {
@ -75,26 +80,6 @@ public class SysTenantServiceImpl implements SysTenantService {
return sysTenantMapper.selectById(tenantId); return sysTenantMapper.selectById(tenantId);
} }
@Override
public Connection getConnection(String tenantId) {
SysTenant sysTenant = selectById(tenantId);
if (Objects.isNull(sysTenant)) {
throw new ServiceException("租户不存在");
}
if (SysTenant.COLUMN_MODE.equals(sysTenant.getMode())) {
return column();
}
if (SysTenant.DATABASE_MODE.equals(sysTenant.getMode())) {
return database(tenantId);
}
if (SysTenant.DATASOURCE_MODE.equals(sysTenant.getMode())) {
return datasource(tenantId);
}
throw new ServiceException("未找到租户设置的数据源模式");
}
@Override @Override
public TenantSettingVo getSetting(String tenantId) { public TenantSettingVo getSetting(String tenantId) {
SysTenant sysTenant = selectById(tenantId); SysTenant sysTenant = selectById(tenantId);
@ -105,6 +90,31 @@ public class SysTenantServiceImpl implements SysTenantService {
return new TenantSettingVo(tenantId, sysTenant.getMode(), datasourceList); return new TenantSettingVo(tenantId, sysTenant.getMode(), datasourceList);
} }
@Override
public void initData(String tenantId) throws Exception {
SysTenant sysTenant = selectById(tenantId);
if (Objects.isNull(sysTenant)) {
throw new ServiceException("租户不存在");
}
// 初始化数据
Connection connection = getConnection(sysTenant);
boolean result = DataHandlerFactory.getHandler(connection.getMetaData().getDatabaseProductName().trim()).handle(connection, tenantId, !SysTenant.COLUMN_MODE.equals(sysTenant.getMode()));
if (!result) {
throw new ServiceException("同步数据出错, 数据已回滚");
}
// 将数据源添加到数据源池中
if (sysTenant.getMode().equals(SysTenant.DATASOURCE_MODE)) {
SysTenantDatasource master = sysTenantDatasourceService.selectMaster(tenantId);
dynamicDataSourceConfig.addTenantDataSource(tenantId,
DataBaseEnum.getDriver(master.getType()),
DataBaseEnum.getUrl(master.getType(), master.getIp(), master.getPort(), master.getName()),
master.getUsername(),
master.getPassword(),
new PoolInfo(master.getInitCount(), master.getMinCount(), master.getMaxCount()));
}
}
private QueryWrapper<SysTenant> param2Wrapper(SysTenantParam param) { private QueryWrapper<SysTenant> param2Wrapper(SysTenantParam param) {
QueryWrapper<SysTenant> wrapper = new QueryWrapper<>(); QueryWrapper<SysTenant> wrapper = new QueryWrapper<>();
wrapper.lambda() wrapper.lambda()
@ -129,6 +139,20 @@ public class SysTenantServiceImpl implements SysTenantService {
return wrapper; return wrapper;
} }
private Connection getConnection(SysTenant sysTenant) {
if (SysTenant.COLUMN_MODE.equals(sysTenant.getMode())) {
return column();
}
if (SysTenant.DATABASE_MODE.equals(sysTenant.getMode())) {
return database(sysTenant.getTenantId());
}
if (SysTenant.DATASOURCE_MODE.equals(sysTenant.getMode())) {
return datasource(sysTenant.getTenantId());
}
throw new ServiceException("未找到租户设置的数据源模式");
}
/** /**
* 处理字段模式 * 处理字段模式
*/ */
@ -150,8 +174,18 @@ public class SysTenantServiceImpl implements SysTenantService {
private Connection datasource(String tenantId) { private Connection datasource(String tenantId) {
SysTenantDatasource master = sysTenantDatasourceService.selectMaster(tenantId); SysTenantDatasource master = sysTenantDatasourceService.selectMaster(tenantId);
if (Objects.isNull(master)) { if (Objects.isNull(master)) {
throw new ServiceException("未找到租户数据源信息"); throw new ServiceException("未找到租户数据源信息");
} }
return JdbcUtil.getConnection(DataBaseEnum.getDriver(master.getType()), DataBaseEnum.getUrl(master.getType(), master.getIp(), master.getPort(), master.getName()), master.getUsername(), master.getPassword()); return JdbcUtil.getConnection(DataBaseEnum.getDriver(master.getType()), DataBaseEnum.getUrl(master.getType(), master.getIp(), master.getPort(), master.getName()), master.getUsername(), master.getPassword());
} }
@Override
public boolean checkTenantInfo(String tenantId) {
SysTenant sysTenant = selectById(tenantId);
if (Objects.isNull(sysTenant)) {
return false;
}
// todo 检查租户有没有过期/禁用
return sysTenant.getStatus().equals(BaseEnum.NORMAL.getCode());
}
} }

View File

@ -36,8 +36,8 @@ public class MenuUtil {
SqlExecutor.execute(conn, sql); SqlExecutor.execute(conn, sql);
// 登录用户 // 登录用户
Long onlineUserId = handleMenu(conn, monitorId, tenantId, "data/sys_menu/monitor/online_user/menu"); Long onlineUserId = handleMenu(conn, monitorId, tenantId, "MySQL/data/sys_menu/monitor/online_user/menu");
handleButton(conn, tenantId, onlineUserId, "data/sys_menu/monitor/online_user/button"); handleButton(conn, tenantId, onlineUserId, "MySQL/data/sys_menu/monitor/online_user/button");
} }
private static void handleSystemMenu(Connection conn, String tenantId) throws Exception { private static void handleSystemMenu(Connection conn, String tenantId) throws Exception {
@ -47,26 +47,26 @@ public class MenuUtil {
SqlExecutor.execute(conn, sql); SqlExecutor.execute(conn, sql);
// 用户管理 // 用户管理
Long userId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/user/menu"); Long userId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/user/menu");
handleButton(conn, tenantId, userId, "data/sys_menu/system/user/button"); handleButton(conn, tenantId, userId, "MySQL/data/sys_menu/system/user/button");
// 角色管理 // 角色管理
Long roleId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/role/menu"); Long roleId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/role/menu");
handleButton(conn, tenantId, roleId, "data/sys_menu/system/role/button"); handleButton(conn, tenantId, roleId, "MySQL/data/sys_menu/system/role/button");
// 菜单管理 // 菜单管理
Long menuId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/menu/menu"); Long menuId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/menu/menu");
handleButton(conn, tenantId, menuId, "data/sys_menu/system/menu/button"); handleButton(conn, tenantId, menuId, "MySQL/data/sys_menu/system/menu/button");
// 部门管理 // 部门管理
Long deptId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/dept/menu"); Long deptId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/dept/menu");
handleButton(conn, tenantId, deptId, "data/sys_menu/system/dept/button"); handleButton(conn, tenantId, deptId, "MySQL/data/sys_menu/system/dept/button");
// 岗位管理 // 岗位管理
Long postId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/post/menu"); Long postId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/post/menu");
handleButton(conn, tenantId, postId, "data/sys_menu/system/post/button"); handleButton(conn, tenantId, postId, "MySQL/data/sys_menu/system/post/button");
// 字典管理 // 字典管理
Long dictId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/dict/menu"); Long dictId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/dict/menu");
handleButton(conn, tenantId, dictId, "data/sys_menu/system/dict/button"); handleButton(conn, tenantId, dictId, "MySQL/data/sys_menu/system/dict/button");
// 参数管理 // 参数管理
Long configId = handleMenu(conn, systemId, tenantId, "data/sys_menu/system/config/menu"); Long configId = handleMenu(conn, systemId, tenantId, "MySQL/data/sys_menu/system/config/menu");
handleButton(conn, tenantId, configId, "data/sys_menu/system/config/button"); handleButton(conn, tenantId, configId, "MySQL/data/sys_menu/system/config/button");
} }
private static Long handleMenu(Connection conn, Long systemId, String tenantId, String fileName) throws Exception { private static Long handleMenu(Connection conn, Long systemId, String tenantId, String fileName) throws Exception {

View File

@ -0,0 +1,186 @@
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `sys_config`;
CREATE TABLE `sys_config` (
`config_id` bigint NOT NULL COMMENT '参数主键',
`config_name` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '参数名称',
`config_key` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '参数键名',
`config_value` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '参数键值',
`config_type` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT 'N' COMMENT '系统内置Y是 N否',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL,
PRIMARY KEY (`config_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1666019098658177025 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '参数配置表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_dept`;
CREATE TABLE `sys_dept` (
`dept_id` bigint NOT NULL COMMENT '部门id',
`parent_id` bigint NULL DEFAULT 0 COMMENT '父部门id',
`ancestors` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '祖级列表',
`dept_name` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '部门名称',
`order_num` int NULL DEFAULT 0 COMMENT '显示顺序',
`leader` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '负责人ID',
`phone` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '手机号',
`email` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '邮箱',
`status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '部门状态1正常 0停用',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`dept_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '部门表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_dict_data`;
CREATE TABLE `sys_dict_data` (
`dict_code` bigint NOT NULL COMMENT '字典编码',
`dict_sort` int NULL DEFAULT 0 COMMENT '字典排序',
`dict_label` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '字典标签',
`dict_value` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '字典键值',
`dict_type` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '字典类型',
`css_class` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)',
`list_class` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '表格回显样式',
`is_default` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT 'N' COMMENT '是否默认Y是 N否',
`status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '状态0正常 1停用',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`dict_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1665587655929507842 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '字典数据表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_dict_type`;
CREATE TABLE `sys_dict_type` (
`dict_id` bigint NOT NULL COMMENT '字典主键',
`dict_name` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '字典名称',
`dict_type` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '字典类型',
`status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '状态0正常 1停用',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`dict_id`) USING BTREE,
UNIQUE INDEX `dict_type`(`dict_type`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1665587609699889155 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '字典类型表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu` (
`menu_id` bigint NOT NULL COMMENT '菜单ID',
`menu_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '菜单名称',
`parent_id` bigint NULL DEFAULT 0 COMMENT '父菜单ID',
`order_num` int NULL DEFAULT 0 COMMENT '显示顺序',
`path` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '路由地址',
`component` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '组件路径',
`query` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '路由参数',
`is_frame` int NULL DEFAULT 1 COMMENT '是否为外链1是 0否',
`is_cache` int NULL DEFAULT 0 COMMENT '是否缓存1缓存 0不缓存',
`menu_type` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '菜单类型M目录 C菜单 F按钮',
`is_visible` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '菜单状态1显示 0隐藏',
`perms` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '权限标识',
`icon` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '#' COMMENT '菜单图标',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL,
PRIMARY KEY (`menu_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '菜单权限表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_post`;
CREATE TABLE `sys_post` (
`post_id` bigint NOT NULL COMMENT '岗位ID',
`post_code` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '岗位编码',
`post_name` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '岗位名称',
`post_sort` int NOT NULL COMMENT '显示顺序',
`status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '状态1正常 0停用',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`post_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '岗位信息表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
`role_id` bigint NOT NULL COMMENT '角色ID',
`role_name` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '角色名称',
`role_key` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '角色权限字符串',
`role_sort` int NOT NULL COMMENT '显示顺序',
`data_scope` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '1' COMMENT '数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限',
`status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '角色状态1正常 0停用',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`role_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '角色信息表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_role_dept`;
CREATE TABLE `sys_role_dept` (
`role_id` bigint NOT NULL COMMENT '角色ID',
`dept_id` bigint NOT NULL COMMENT '部门ID',
`tenant_id` bigint NOT NULL COMMENT '租户ID',
PRIMARY KEY (`role_id`, `dept_id`, `tenant_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '角色和部门关联表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_role_menu`;
CREATE TABLE `sys_role_menu` (
`role_id` bigint NOT NULL COMMENT '角色ID',
`menu_id` bigint NOT NULL COMMENT '菜单ID',
`tenant_id` bigint NOT NULL COMMENT '租户ID',
PRIMARY KEY (`role_id`, `menu_id`, `tenant_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL COMMENT '用户ID',
`dept_id` bigint NULL DEFAULT NULL COMMENT '部门ID',
`username` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户账号',
`nickname` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户昵称',
`email` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '用户邮箱',
`phone` varchar(11) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '手机号码',
`gender` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '用户性别0男 1女 2未知',
`avatar` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '头像地址',
`password` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '密码',
`status` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '0' COMMENT '帐号状态1正常 0停用',
`create_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '备注',
`tenant_id` bigint NULL DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1660830718629277698 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '用户信息表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_user_post`;
CREATE TABLE `sys_user_post` (
`user_id` bigint NOT NULL COMMENT '用户ID',
`post_id` bigint NOT NULL COMMENT '岗位ID',
`tenant_id` bigint NOT NULL COMMENT '租户ID',
PRIMARY KEY (`user_id`, `post_id`, `tenant_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = DYNAMIC;
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
`user_id` bigint NOT NULL COMMENT '用户ID',
`role_id` bigint NOT NULL COMMENT '角色ID',
`tenant_id` bigint NOT NULL COMMENT '租户ID',
PRIMARY KEY (`user_id`, `role_id`, `tenant_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '用户和角色关联表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;