diff --git a/pom.xml b/pom.xml index 453e201..f451a54 100644 --- a/pom.xml +++ b/pom.xml @@ -18,13 +18,15 @@ 17 2.1.1 - 1.2.20 - 5.8.15 - 1.35.0.RC + 1.2.23 + 5.8.36 + 1.40.0 4.1.2 8.0.32 4.6.0 7.21.0 + 3.5.10.1 + 1.18.36 @@ -35,6 +37,10 @@ org.springframework.boot spring-boot-starter-jdbc + + org.springframework.boot + spring-boot-starter-data-redis + org.ssssssss magic-api-spring-boot-starter @@ -60,6 +66,11 @@ sa-token-spring-boot3-starter ${sa-token.version} + + cn.dev33 + sa-token-redis-jackson + ${sa-token.version} + org.ssssssss magic-api-plugin-task @@ -90,6 +101,17 @@ camunda-bpm-spring-boot-starter-rest ${camunda.spring-boot.version} + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatis-plus.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + diff --git a/src/main/java/org/ssssssss/magicboot/MagicBootApplication.java b/src/main/java/org/ssssssss/magicboot/MagicBootApplication.java index 9133e1f..d07cd2f 100644 --- a/src/main/java/org/ssssssss/magicboot/MagicBootApplication.java +++ b/src/main/java/org/ssssssss/magicboot/MagicBootApplication.java @@ -1,9 +1,11 @@ package org.ssssssss.magicboot; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication +@MapperScan("org.ssssssss.magicboot.data.mapper") public class MagicBootApplication { public static void main(String[] args) { diff --git a/src/main/java/org/ssssssss/magicboot/data/entity/SysTenant.java b/src/main/java/org/ssssssss/magicboot/data/entity/SysTenant.java new file mode 100644 index 0000000..5f16e10 --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/entity/SysTenant.java @@ -0,0 +1,178 @@ +package org.ssssssss.magicboot.data.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 租户表 + * @TableName sys_tenant + */ +@TableName(value ="sys_tenant") +@Data +public class SysTenant { + /** + * 租户ID + */ + @TableId(value = "id") + private String id; + + /** + * 租户编码 + */ + @TableField(value = "code") + private String code; + + /** + * 租户名称 + */ + @TableField(value = "name") + private String name; + + /** + * 租户Logo + */ + @TableField(value = "logo") + private String logo; + + /** + * 网站图标 + */ + @TableField(value = "favicon") + private String favicon; + + /** + * 登录页背景图 + */ + @TableField(value = "login_background") + private String loginBackground; + + /** + * 系统名称 + */ + @TableField(value = "system_name") + private String systemName; + + /** + * 版权信息 + */ + @TableField(value = "copyright") + private String copyright; + + /** + * 状态:0禁用,1启用 + */ + @TableField(value = "status") + private Integer status; + + /** + * 到期时间 + */ + @TableField(value = "expire_time") + private Date expireTime; + + /** + * 最大用户数 + */ + @TableField(value = "max_user") + private Integer maxUser; + + /** + * 联系人姓名 + */ + @TableField(value = "contact_name") + private String contactName; + + /** + * 联系人电话 + */ + @TableField(value = "contact_phone") + private String contactPhone; + + /** + * 联系人邮箱 + */ + @TableField(value = "contact_email") + private String contactEmail; + + /** + * 备注信息 + */ + @TableField(value = "remark") + private String remark; + + /** + * 创建时间 + */ + @TableField(value = "create_date") + private Date createDate; + + /** + * 更新时间 + */ + @TableField(value = "update_date") + private Date updateDate; + + /** + * 删除标识 + */ + @TableField(value = "is_del") + private Integer isDel; + + /** + * 创建人ID + */ + @TableField(value = "create_by") + private String createBy; + + /** + * 更新人ID + */ + @TableField(value = "update_by") + private String updateBy; + + /** + * 数据库类型(MYSQL/MARIADB/SQLSERVER/ORACLE) + */ + @TableField(value = "db_type") + private String dbType; + + /** + * 租户JDBC连接字符串 + */ + @TableField(value = "db_jdbc_url") + private String dbJdbcUrl; + + /** + * 数据库IP + */ + @TableField(value = "db_host") + private String dbHost; + + /** + * 数据库端口号 + */ + @TableField(value = "db_port") + private Integer dbPort; + + /** + * 数据库用户名 + */ + @TableField(value = "db_user") + private String dbUser; + + /** + * 数据库密码 + */ + @TableField(value = "db_password") + private String dbPassword; + + /** + * 数据库名称 + */ + @TableField(value = "db_name") + private String dbName; +} \ No newline at end of file diff --git a/src/main/java/org/ssssssss/magicboot/data/entity/SysTenantPlatform.java b/src/main/java/org/ssssssss/magicboot/data/entity/SysTenantPlatform.java new file mode 100644 index 0000000..2801af7 --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/entity/SysTenantPlatform.java @@ -0,0 +1,82 @@ +package org.ssssssss.magicboot.data.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.util.Date; +import lombok.Data; + +/** + * 租户接入配置表 + * @TableName sys_tenant_platform + */ +@TableName(value ="sys_tenant_platform") +@Data +public class SysTenantPlatform { + /** + * 主键 + */ + @TableId(value = "id") + private String id; + + /** + * 租户ID + */ + @TableField(value = "tenant_id") + private String tenantId; + + /** + * 平台类型:DOMAIN域名,PATH路径,WX_MINI微信小程序,WX_MP微信公众号,WX_WORK企业微信,DINGTALK钉钉,FEISHU飞书 + */ + @TableField(value = "platform_type") + private String platformType; + + /** + * 标识符(域名/路径/AppID) + */ + @TableField(value = "identifier") + private String identifier; + + /** + * 应用密钥 + */ + @TableField(value = "app_secret") + private String appSecret; + + /** + * 是否默认(用于域名) + */ + @TableField(value = "is_default") + private Integer isDefault; + + /** + * 其他配置JSON + */ + @TableField(value = "other_config") + private String otherConfig; + + /** + * 状态:0禁用,1启用 + */ + @TableField(value = "status") + private Integer status; + + /** + * 备注 + */ + @TableField(value = "remark") + private String remark; + + /** + * 创建时间 + */ + @TableField(value = "create_date") + private Date createDate; + + /** + * 更新时间 + */ + @TableField(value = "update_date") + private Date updateDate; +} \ No newline at end of file diff --git a/src/main/java/org/ssssssss/magicboot/data/mapper/SysTenantMapper.java b/src/main/java/org/ssssssss/magicboot/data/mapper/SysTenantMapper.java new file mode 100644 index 0000000..08daf62 --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/mapper/SysTenantMapper.java @@ -0,0 +1,24 @@ +package org.ssssssss.magicboot.data.mapper; + +import org.apache.ibatis.annotations.Param; +import org.ssssssss.magicboot.data.entity.SysTenant; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author yean +* @description 针对表【sys_tenant(租户表)】的数据库操作Mapper +* @Entity org.ssssssss.magicboot.data.entity.SysTenant +*/ +public interface SysTenantMapper extends BaseMapper { + + /** + * 根据域名查询租户信息 + * @param domain + * @return + */ + SysTenant getTenantByDomain(@Param("domain") String domain); +} + + + + diff --git a/src/main/java/org/ssssssss/magicboot/data/mapper/SysTenantPlatformMapper.java b/src/main/java/org/ssssssss/magicboot/data/mapper/SysTenantPlatformMapper.java new file mode 100644 index 0000000..aaa2b76 --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/mapper/SysTenantPlatformMapper.java @@ -0,0 +1,18 @@ +package org.ssssssss.magicboot.data.mapper; + +import org.ssssssss.magicboot.data.entity.SysTenantPlatform; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author yean +* @description 针对表【sys_tenant_platform(租户接入配置表)】的数据库操作Mapper +* @createDate 2025-02-22 17:40:22 +* @Entity org.ssssssss.magicboot.data.entity.SysTenantPlatform +*/ +public interface SysTenantPlatformMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/org/ssssssss/magicboot/data/service/SysTenantPlatformService.java b/src/main/java/org/ssssssss/magicboot/data/service/SysTenantPlatformService.java new file mode 100644 index 0000000..b2fa2d4 --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/service/SysTenantPlatformService.java @@ -0,0 +1,13 @@ +package org.ssssssss.magicboot.data.service; + +import org.ssssssss.magicboot.data.entity.SysTenantPlatform; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author yean +* @description 针对表【sys_tenant_platform(租户接入配置表)】的数据库操作Service +* @createDate 2025-02-22 17:40:22 +*/ +public interface SysTenantPlatformService extends IService { + +} diff --git a/src/main/java/org/ssssssss/magicboot/data/service/SysTenantService.java b/src/main/java/org/ssssssss/magicboot/data/service/SysTenantService.java new file mode 100644 index 0000000..8138baf --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/service/SysTenantService.java @@ -0,0 +1,19 @@ +package org.ssssssss.magicboot.data.service; + +import org.ssssssss.magicboot.data.entity.SysTenant; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author yean +* @description 针对表【sys_tenant(租户表)】的数据库操作Service +* @createDate 2025-02-22 17:37:23 +*/ +public interface SysTenantService extends IService { + + /** + * 根据域名获取租户信息 + * @param domain + * @return + */ + SysTenant getTenantByDomain(String domain); +} diff --git a/src/main/java/org/ssssssss/magicboot/data/service/impl/SysTenantPlatformServiceImpl.java b/src/main/java/org/ssssssss/magicboot/data/service/impl/SysTenantPlatformServiceImpl.java new file mode 100644 index 0000000..aadca54 --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/service/impl/SysTenantPlatformServiceImpl.java @@ -0,0 +1,22 @@ +package org.ssssssss.magicboot.data.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.ssssssss.magicboot.data.entity.SysTenantPlatform; +import org.ssssssss.magicboot.data.service.SysTenantPlatformService; +import org.ssssssss.magicboot.data.mapper.SysTenantPlatformMapper; +import org.springframework.stereotype.Service; + +/** +* @author yean +* @description 针对表【sys_tenant_platform(租户接入配置表)】的数据库操作Service实现 +* @createDate 2025-02-22 17:40:22 +*/ +@Service +public class SysTenantPlatformServiceImpl extends ServiceImpl + implements SysTenantPlatformService{ + +} + + + + diff --git a/src/main/java/org/ssssssss/magicboot/data/service/impl/SysTenantServiceImpl.java b/src/main/java/org/ssssssss/magicboot/data/service/impl/SysTenantServiceImpl.java new file mode 100644 index 0000000..3cac23c --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/data/service/impl/SysTenantServiceImpl.java @@ -0,0 +1,26 @@ +package org.ssssssss.magicboot.data.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.ssssssss.magicboot.data.entity.SysTenant; +import org.ssssssss.magicboot.data.service.SysTenantService; +import org.ssssssss.magicboot.data.mapper.SysTenantMapper; +import org.springframework.stereotype.Service; + +/** +* @author yean +* @description 针对表【sys_tenant(租户表)】的数据库操作Service实现 +* @createDate 2025-02-22 17:37:23 +*/ +@Service +public class SysTenantServiceImpl extends ServiceImpl + implements SysTenantService{ + + @Override + public SysTenant getTenantByDomain(String domain) { + return getBaseMapper().getTenantByDomain(domain); + } +} + + + + diff --git a/src/main/java/org/ssssssss/magicboot/enums/TenantStatus.java b/src/main/java/org/ssssssss/magicboot/enums/TenantStatus.java new file mode 100644 index 0000000..c924b3f --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/enums/TenantStatus.java @@ -0,0 +1,28 @@ +package org.ssssssss.magicboot.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +public enum TenantStatus { + + NORMAL(1,"启用"), + + EXPIRED(0,"禁用"), + ; + + /** + * 状态码 + */ + @Getter + private final Integer code; + + /** + * 状态名称 + */ + @Getter + private final String name; + + +} diff --git a/src/main/java/org/ssssssss/magicboot/interceptor/MagicApiAuthorizationInterceptor.java b/src/main/java/org/ssssssss/magicboot/interceptor/MagicApiAuthorizationInterceptor.java index 74cba3c..dfde54f 100644 --- a/src/main/java/org/ssssssss/magicboot/interceptor/MagicApiAuthorizationInterceptor.java +++ b/src/main/java/org/ssssssss/magicboot/interceptor/MagicApiAuthorizationInterceptor.java @@ -3,8 +3,8 @@ package org.ssssssss.magicboot.interceptor; import cn.dev33.satoken.secure.SaSecureUtil; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; import com.alibaba.druid.pool.DruidDataSource; -import com.mysql.cj.jdbc.JdbcConnection; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import org.springframework.jdbc.core.JdbcTemplate; @@ -12,7 +12,11 @@ import org.springframework.stereotype.Component; import org.ssssssss.magicapi.core.context.MagicUser; import org.ssssssss.magicapi.core.exception.MagicLoginException; import org.ssssssss.magicapi.core.interceptor.AuthorizationInterceptor; +import org.ssssssss.magicboot.data.entity.SysTenant; +import org.ssssssss.magicboot.data.service.SysTenantService; import org.ssssssss.magicboot.enums.TenantDbType; +import org.ssssssss.magicboot.enums.TenantStatus; +import org.ssssssss.magicboot.utils.DruidTenantDataSourceUtil; import java.util.Map; @@ -31,6 +35,12 @@ public class MagicApiAuthorizationInterceptor implements AuthorizationIntercepto @Resource private JdbcTemplate jdbcTemplate; + @Resource + private SysTenantService sysTenantService; + + @Resource + private DruidTenantDataSourceUtil druidTenantDataSourceUtil; + @Override public boolean requireLogin() { return true; @@ -39,25 +49,21 @@ public class MagicApiAuthorizationInterceptor implements AuthorizationIntercepto @Override public MagicUser login(String username, String password) throws MagicLoginException { // 根据当前域名查询租户 - Map tenantInfo = jdbcTemplate.queryForMap(""" - select st.* - from sys_tenant_platform stp - left join sys_tenant st on (st.id = stp.tenant_id) - where stp.identifier = ? limit 1 - """, httpServletRequest.getServerName()); + SysTenant tenantInfo = sysTenantService.getTenantByDomain(httpServletRequest.getServerName()); - if (MapUtil.isEmpty(tenantInfo)) { + if (ObjectUtil.isEmpty(tenantInfo)) { throw new MagicLoginException("很抱歉,租户不存在,请检查当前域名是否正确"); } else { + if (TenantStatus.EXPIRED.getCode().equals(tenantInfo.getStatus())) { + throw new MagicLoginException("很抱歉,租户已禁用"); + } return handleTenantLogin(tenantInfo, username, password); } } @Override public MagicUser getUserByToken(String token) throws MagicLoginException { - String loginId = (String) StpUtil.getLoginIdByToken(token); - if (StpUtil.isLogin(loginId)) { return new MagicUser(loginId, loginId, token); } else { @@ -77,33 +83,43 @@ public class MagicApiAuthorizationInterceptor implements AuthorizationIntercepto * @param tenantInfo * @return */ - public MagicUser handleTenantLogin(Map tenantInfo, String username, String password) { - TenantDbType dbType = TenantDbType.valueOf(tenantInfo.get("db_type").toString()); - DruidDataSource dataSource = new DruidDataSource(); - dataSource.setUrl((String) tenantInfo.get("db_jdbc_url")); - dataSource.setUsername((String) tenantInfo.get("db_user")); - dataSource.setPassword((String) tenantInfo.get("db_password")); - dataSource.setDriverClassName(dbType.getDriverClassName()); - - JdbcTemplate template = new JdbcTemplate(dataSource); + public MagicUser handleTenantLogin(SysTenant tenantInfo, String username, String password) throws MagicLoginException { + TenantDbType dbType = TenantDbType.valueOf(tenantInfo.getDbType()); + + DruidDataSource tenantDataSource = null; try { - Map userInfo = template.queryForMap(""" - select * from sys_user where username = ? and password = ? limit 1; - """, username, SaSecureUtil.sha256(password)); + // 使用工具类创建数据源 + tenantDataSource = druidTenantDataSourceUtil.createTenantDataSource( + dbType.getDriverClassName(), + tenantInfo.getDbJdbcUrl(), + tenantInfo.getDbUser(), + tenantInfo.getDbPassword() + ); + + // 使用临时JdbcTemplate查询用户 + JdbcTemplate tenantJdbcTemplate = new JdbcTemplate(tenantDataSource); + Map userInfo = tenantJdbcTemplate.queryForMap( + "select * from sys_user where username = ? and password = ? and is_del = 0 limit 1", + username, + SaSecureUtil.sha256(password) + ); + if (MapUtil.isNotEmpty(userInfo)) { - StpUtil.login(tenantInfo.get("id") + ":" + userInfo.get("id")); + StpUtil.login(tenantInfo.getId() + ":" + userInfo.get("id")); MagicUser user = new MagicUser(); user.setToken(StpUtil.getTokenValue()); - user.setUsername(tenantInfo.get("id") + ":" + username); - user.setId(tenantInfo.get("id") + "_" + userInfo.get("id").toString()); - + user.setUsername(tenantInfo.getId() + ":" + username); + user.setId(tenantInfo.getId() + "_" + userInfo.get("id").toString()); return user; } else { throw new MagicLoginException("很抱歉,用户名或密码错误"); } } catch (Exception e) { e.printStackTrace(); + throw new MagicLoginException("登录失败: " + e.getMessage()); + } finally { + // 使用工具类关闭数据源 + druidTenantDataSourceUtil.closeDataSource(tenantDataSource); } - return null; } } diff --git a/src/main/java/org/ssssssss/magicboot/utils/DruidTenantDataSourceUtil.java b/src/main/java/org/ssssssss/magicboot/utils/DruidTenantDataSourceUtil.java new file mode 100644 index 0000000..19b42eb --- /dev/null +++ b/src/main/java/org/ssssssss/magicboot/utils/DruidTenantDataSourceUtil.java @@ -0,0 +1,74 @@ +package org.ssssssss.magicboot.utils; + +import com.alibaba.druid.pool.DruidDataSource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class DruidTenantDataSourceUtil { + + /** + * 创建租户数据源 + * + * @param driverClassName 数据库驱动类名 + * @param url 数据库连接URL + * @param username 用户名 + * @param password 密码 + * @return DruidDataSource实例 + */ + public DruidDataSource createTenantDataSource(String driverClassName, String url, String username, String password) throws Exception { + DruidDataSource tenantDataSource = new DruidDataSource(); + + // 设置基本连接信息 + tenantDataSource.setDriverClassName(driverClassName); + tenantDataSource.setUrl(url); + tenantDataSource.setUsername(username); + tenantDataSource.setPassword(password); + + // 设置连接池配置 + tenantDataSource.setInitialSize(1); + tenantDataSource.setMinIdle(1); + tenantDataSource.setMaxActive(20); + tenantDataSource.setMaxWait(60000); + tenantDataSource.setTimeBetweenEvictionRunsMillis(60000); + tenantDataSource.setMinEvictableIdleTimeMillis(300000); + tenantDataSource.setValidationQuery("SELECT 1"); + tenantDataSource.setTestWhileIdle(true); + tenantDataSource.setTestOnBorrow(false); + tenantDataSource.setTestOnReturn(false); + tenantDataSource.setPoolPreparedStatements(true); + tenantDataSource.setMaxPoolPreparedStatementPerConnectionSize(20); + + // 初始化数据源 + tenantDataSource.init(); + + return tenantDataSource; + } + + /** + * 创建租户JdbcTemplate + * + * @param driverClassName 数据库驱动类名 + * @param url 数据库连接URL + * @param username 用户名 + * @param password 密码 + * @return JdbcTemplate实例 + */ + public JdbcTemplate createTenantJdbcTemplate(String driverClassName, String url, String username, String password) throws Exception { + DruidDataSource dataSource = createTenantDataSource(driverClassName, url, username, password); + return new JdbcTemplate(dataSource); + } + + /** + * 安全关闭数据源 + * + * @param dataSource 要关闭的数据源 + */ + public void closeDataSource(DruidDataSource dataSource) { + if (dataSource != null && !dataSource.isClosed()) { + dataSource.close(); + } + } +} \ No newline at end of file diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 0000000..5aba2cd --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,6 @@ + ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗ ██████╗ ██████╗ ██████╗ ████████╗ + ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝ ██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝ + ██╔████╔██║███████║██║ ███╗██║██║ ██████╔╝██║ ██║██║ ██║ ██║ + ██║╚██╔╝██║██╔══██║██║ ██║██║██║ ██╔══██╗██║ ██║██║ ██║ ██║ + ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗ ██████╔╝╚██████╔╝╚██████╔╝ ██║ + ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ \ No newline at end of file diff --git a/src/main/resources/mapper/SysTenantMapper.xml b/src/main/resources/mapper/SysTenantMapper.xml new file mode 100644 index 0000000..83edef0 --- /dev/null +++ b/src/main/resources/mapper/SysTenantMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id,code,name, + logo,favicon,login_background, + system_name,copyright,status, + expire_time,max_user,contact_name, + contact_phone,contact_email,remark, + create_date,update_date,is_del, + create_by,update_by,db_type, + db_jdbc_url,db_host,db_port, + db_user,db_password,db_name + + + diff --git a/src/main/resources/mapper/SysTenantPlatformMapper.xml b/src/main/resources/mapper/SysTenantPlatformMapper.xml new file mode 100644 index 0000000..e4dba6e --- /dev/null +++ b/src/main/resources/mapper/SysTenantPlatformMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + id,tenant_id,platform_type, + identifier,app_secret,is_default, + other_config,status,remark, + create_date,update_date + +